Options

buildDir

  • Type: String

Sets destination for custom-element build.

analyzer

  • Type: Boolean, Object
    • Default: false

Sets true for default module config or object with custom webpack-bundle-analyzer configuration.

entries

  • Type: Array
    • Default: []
    • required

Defines the component bundles.

Components can be distributed in separate endpoints.
Allows the targeted distribution of resources.

Entry

{
  name: 'EndpointName',
  viteExtend(config) { … }, // or webpackExtend(config) { … },
  tags: [
    // Simplified props, definition only
    {
      async: false,
      name: 'TagName',
      path: 'component path',
      options: {
        props: ['prop1', 'prop2']
      } 
    },
    // Extended props, with default values
    {
      async: true,
      name: 'AnotherTagName',
      path: 'component path',
      options: {
        props: {
          prop1: false,
          prop2: true
        }
      }
    }
  ]
}
KeyTypeRequriedDescriptionDefault
nameStringyesName of the endpoint. Value will be converted to ParamCase later.
viteExtendFunctionLearn more
webpackExtendFunctionLearn more
tagsArrayTag Definitions.[]

More about viteExtend

Called before the build and allows to customize the configuration before build.
Return value is the config. async is supported.

Example Configuration:

{
  viteExtend(config) {

    plugins.plugins.push(VitePlugin())

    return config;
  }
}

More about webpackExtend

Called before the build and allows to customize the configuration before build.
Return value is the config. async is supported.

Example Configuration:

{
  webpackExtend(config) {

    /**
     * Defines the webpack output options (`publicPath`, `filename`, `chunkFilename`).
     **/
    config.output = {
      ...config.output, 
      publicPath: 'https://domain/nuxt-custom-elements/example/',
      filename: (webpackConfig, moduleOptions) => {
        return '[name].js'
      },
      chunkFilename: (webpackConfig, moduleOptions) => {
        return '[name].js'
      }
    };

    /**
     * Defines the webpack optimization options, see [webpack optimization](https://webpack.js.org/configuration/optimization/).
     * Example to create several chunks with minimum size of 100kb. 
     * One of the chunks contains all vue and vuetify related vendor libraries:
     **/
    config.optimization.splitChunks = {
      ...config.optimization.splitChunks,
      automaticNameDelimiter: '.',
      minChunks: 1,
      minSize: 100_000,
      chunks: 'all',
      cacheGroups: {
        uiFrameworks: {
          test: /[/\\]node_modules[/\\](vuetify.*|vue.*)[/\\]/,
          name: 'ui',
          chunks: 'all',
          priority: 10,
          enforce: true
        }
      }
    };

    /**
     * Defines webpack plugins, see [webpack plugins](https://webpack.js.org/configuration/plugins/).
     * The following example includes the `compression-webpack-plugin`:
     **/
    config.plugins = [
      ...config.plugins, 
      new (require('compression-webpack-plugin'))({
        filename: '[path][base].gz[query]',
        algorithm: 'gzip',
        test: /\.(js|css)$/,
      })
    ];

    return config;

  }
}

Tag

KeyTypeRequriedDescriptionDefault
nameStringyesName of the Tag. Value will be converted to ParamCase later.

Example: TagName -> tag-name
asyncBooleanComponents are loaded asynchronously. If there is more than one entry the async will lead to unwanted webpack chunk splitting.false
pathStringPath to the component to be called by the tag.false
optionsFunction, ObjectOptions from custom-element.
Learn more about vue-custom-element options.
undefined
appContextString, FunctionFile Reference or Function call to extend the Vue app. Example: Plugin registration of vuetify, pinia, vue-router, ...undefined
cssStringCan be used to inject CSS into the element.undefined
slotContentStringDefault slot content for generated html entry output.undefined

Example appContext config file

export default function (Vue) {
  // Customize Vue App here
  // e.g. Vue.component('my-component', MyComponent) or Vue.use(MyPlugin)

  console.log('Vue App', Vue);
}

Important

  1. You can set as object or when using functions in options, use function.
{
  name: 'ComponentAppExample',
  tags: [
    // with function call
    {
      async: true,
      name: 'CustomElementAppExample',
      path: '@/components/apps/AppExample',
      options () {
        return {
          props: ['prop1', 'prop2']
        };
      },
      slotContent: '<div>Slot Content!</div>'
    },
    // without function call
    {
      async: true,
      name: 'CustomElementAppExample',
      path: '@/components/apps/AppExample',
      options: {
        props: {
          'prop1': 'Value 1',
          'prop2': 'Value 2'
        }
      },
      slotContent: '<div>Slot Content!</div>'
    }
  ]
}
  1. You can customize the Vue app to install plugins, for example. (e.g. vuetify, pinia, vue-18n, vue-router)
{
  name: 'ComponentAppExample',
  tags: [
    // Recommended to control appContext via config file.
    {
      async: true,
      name: 'CustomElementAppExample',
      path: '@/components/apps/AppExample',
      options: {
        props: {
          'prop1': 'Value 1',
          'prop2': 'Value 2'
        }
      },
      appContext: '@/components/apps/AppExample.appContext.js',
      slotContent: '<div>Slot Content!</div>'
    },
    // appContext can also be defined by function, this is copied to the entry by stringify. 
    // Beware: function loses the scope to `nuxt.config`.
    {
      async: true,
      name: 'CustomElementAppExample',
      path: '@/components/apps/AppExample',
      options: {
        props: {
          'prop1': 'Value 1',
          'prop2': 'Value 2'
        }
      },
      appContext(Vue) {
        console.log('Vue App', Vue);
        // usage for Vue.use…
      },
      slotContent: '<div>Slot Content!</div>'
    }
  ]
}

Example Configuration

{
  customElements: {
    analyzer: true,
    modern: true,

    entries: [

      // Entry with single tag.
      {
        name: 'CustomElementsOne',
        tags: [
          {
            name: 'ComponentOne',
            path: 'Path to ComponentOne',
            options: {
              props: ['prop1', 'prop2'],
            },
            appContext: 'Path to ComponentOne Config',
          }
        ]
      },
      {
        name: 'CustomElementsTwo',
        tags: [
          {
            name: 'ComponentTwo',
            path: 'Path to ComponentTwo',
            options: {
              props: {
                'prop1': 'Value 1',
                'prop2': 'Value 2'
              }
            },
            appContext: 'Path to ComponentTwo Config',
          }
        ]
      },

      // Entry-Bundle with two tags.
      {
        name: 'CustomElementsBundle',
        tags: [
          {
            async: true,
            name: 'ComponentOne',
            path: 'Path to ComponentOne',
            options: {
              props: ['prop1', 'prop2']
            },
            appContext: 'Path to ComponentOne Config',
          },
          {
            async: true,
            name: 'ComponentTwo',
            path: 'Path to ComponentTwo',
            options: {
              props: {
                'prop1': 'Value 1',
                'prop2': 'Value 2'
              }
            },
            appContext(Vue) {
              console.log('Vue App', Vue);
              // usage for Vue.use…
            }
          }
        ]
      }
    ]
  }
}