Usage
Nuxt Custom-Elements is used to export components from a Nuxt.js project as custom elements, this is used when providing widgets.
Write Custom-Element
These are the first steps you need to export a component built in Nuxt.js as a custom element. Alternatively, you can take a look at the Nuxt Custom-Elements Example project that follows the steps.
Create Component
Create a component that you want to use as custom element.
WARNING
There is no integration of Nuxt.js modules in the custom elements. For using Vue plugins, look at Integrations.
<template>
<div class="custom-element-example">
<div class="title">
{{ exampleTitle }}
</div>
<div class="content">
<slot>Default Content</slot>
</div>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
default: null
}
},
computed: {
exampleTitle () {
return this.title || 'Default Title';
}
}
};
</script>
<style lang="postcss" scoped>
/* lato-regular - latin */
@font-face {
font-family: Lato;
font-style: normal;
font-weight: 400;
src:
url("~assets/fonts/lato-v22-latin/lato-v22-latin-regular.woff2") format("woff2"),
url("~assets/fonts/lato-v22-latin/lato-v22-latin-regular.woff") format("woff");
}
/* lato-700 - latin */
@font-face {
font-family: Lato;
font-style: normal;
font-weight: 700;
src:
url("~assets/fonts/lato-v22-latin/lato-v22-latin-700.woff2") format("woff2"),
url("~assets/fonts/lato-v22-latin/lato-v22-latin-700.woff") format("woff");
}
.custom-element-example {
min-width: 300px;
padding: 10px;
font-family:
Lato,
"Source Sans Pro",
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
"Helvetica Neue",
Arial,
sans-serif;
font-size: 16px;
color: #35495e;
text-align: center;
background: #35495e;
border-radius: 4px;
}
.title {
margin-bottom: 10px;
font-size: 24px;
font-weight: bold;
text-transform: uppercase;
}
.title,
.content {
padding: 5px;
color: white;
background: #3b8070;
}
.content {
line-height: 1.6;
}
.content a {
margin-top: 10px;
color: currentColor;
}
</style>Add Module with Configuration
Add nuxt-custom-elements dependency to your project:
yarn add nuxt-custom-elements@betanpm install nuxt-custom-elements@betaAfter the installation, add the module in the nuxt.config.
Remember that the created component must be added to the module.
For providing a custom element an entry must be created, this needs a name and should be specified in PascalCase.
The previously created component is put under tags. The name must also be specified as PascalCase.
If necessary you can also define multiple custom elements in tags and deliver them together 😉 .
Learn more about async loading of tags
{
customElements: {
entries: [
{
name: 'Example',
tags: [
{
name: 'CustomElementExample',
path: '@/components/Example.ce.vue',
options: {
props: {
title: 'Prop. Example Title'
}
},
slotContent: 'Slot Example Content'
}
]
}
]
},
modules: [
'nuxt-custom-elements'
]
}Generate Custom-Elements
After the module is installed & configured, the generation of the custom element can be started.
For this purpose a nuxt build or nuxt generate can be used.
The generation of the custom element takes place only in
nuxt build, innuxt generatethe result is copied to thedistdirectory.
Finished
After the build or generate has run, you will find the export under following paths:
| Task | Destination Path |
|---|---|
nuxt build | .nuxt/nuxt-custom-elements/dist |
nuxt generate | dist/nuxt-custom-elements (nuxt.generate.dir Learn more) |
Example Sandbox
:sandbox
Development
To develop a custom component in Dev mode, you must call the entry in thecreate or mounted method. This contains all the tags that can be called in the template.
Learn more about composable useCustomElements
<script setup>
import { useCustomElements } from '#imports';
const { registerEntry } = useCustomElements();
registerEntry('example');
</script>Place the relevant tags in a client-only tag, this is important so that the tag is not resolved in SSR.
Alternatively, SSR can be disabled if possible.
<template>
<div>
<client-only>
<custom-element-example title="Prop. Title">
Slot Content
</custom-element-example>
</client-only>
</div>
</template>Webpack Public Path
The Webpack Public Path is important for the integration of a custom element entry on an external page.
It defines from which origin the resources (fonts, images, scripts) should be loaded.
Normally this Public Path is located at ./, if I include an entry externally, all resources on the external page will be loaded.
To solve this, the build must be told what the correct Public Path is.
Example:
An entry from https://<your-domain>/custom-elements/my-entry/my-entry.js is included, so the public path must also be defined with this url as root.
{
publicPath: 'https://<your-domain>/custom-elements/my-entry/'
}The modification can be done in two ways:
Define fixed public path in the build
For a fixed definition of the publich path, the output option must be extended in the entry in webpackExtend.
{
webpackExtend (config) {
config.output.publicPath = 'https://<your-domain>/custom-elements/my-entry/'
return config
}
}Define Public Path dynamically
Alternatively, the public path can be set dynamically in the webpackExtend of Entry. The Webpack plugin webpack-dynamic-public-path can be used for this.
Konfiguration Beispiel:
{
webpackExtend (config){
config.output.publicPath= "publicPathPlaceholder";
config.plugins.push(new WebpackDynamicPublicPathPlugin({
externalPublicPath: "window.externalPublicPath"
}));
return config
}
}Usage Example:
<custom-element-example />
<script type="text/javascript">
window.externalPublicPath = 'https://<your-domain>/custom-elements/my-entry';
</script>
<script src="https://<your-domain>/custom-elements/my-entry/my-entry.js"></script>