Creating Custom Elements with Svelte, SvelteKit, and Vite

This tutorial will guide you through the process of creating custom elements using Svelte, building them with Vite, and using them in a standard HTML page.

Prerequisites

  • Node.js and npm installed on your system

  • Basic knowledge of Svelte and JavaScript

Step 1: Set Up the Project

  1. Create a new SvelteKit project:

    npm create svelte@latest my-web-components

    Choose the options that best suit your needs when prompted.

  2. Navigate to the project directory and install dependencies:

    cd my-web-components
    npm install

Step 2: Create a Svelte Component

Create a new file src/lib/MyComponent.svelte:

<svelte:options customElement="my-component" />

<script>
  export let name = 'World';
</script>

<h1>Hello {name}!</h1>

Explanation:

  • The <svelte:options customElement="my-component" /> tells Svelte to compile this component as a custom element with the tag name my-component.

  • We define a name prop with a default value of 'World'.

  • The component renders an <h1> element with the greeting.

Step 3: Create a Custom Elements Export File

Create a new file src/lib/custom-elements.js:

import MyComponent from './MyComponent.svelte';

export const MyCustomElement = MyComponent.element;

Explanation:

  • We import the Svelte component.

  • We export the custom element constructor as MyCustomElement. The .element property is available on Svelte components when compiled with the customElement option.

Step 4: Create a Separate Vite Config for Library Build

Create a new file vite.config.lib.js in the project root:

import { defineConfig } from 'vite';
import { svelte } from '@sveltejs/vite-plugin-svelte';

export default defineConfig({
  plugins: [svelte({ compilerOptions: { customElement: true } })],
  build: {
    lib: {
      entry: 'src/lib/custom-elements.js',
      name: 'MyWebComponents',
      fileName: (format) => `my-web-components.${format}.js`
    },
    rollupOptions: {
      output: {
        globals: {
          svelte: 'Svelte'
        }
      }
    }
  }
});

Explanation:

  • We use Vite's library mode to build our custom elements.

  • The entry point is our custom-elements.js file.

  • We set the global name to MyWebComponents, which will be used to access our custom elements.

  • The fileName function determines the output file names.

Step 5: Update Package.json

Add a new script to your package.json:

{
  "scripts": {
    "build:components": "vite build --config vite.config.lib.js"
  }
}

This script will use our custom Vite config to build the web components.

Step 6: Build the Custom Elements

Run the build command:

npm run build:components

This will generate the compiled JavaScript files in the dist directory.

Step 7: Use the Custom Elements

Create an HTML file (e.g., index.html) to use your custom element:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>My Custom Element Demo</title>
</head>
<body>
  <script src="dist/my-web-components.umd.js"></script>
  <script>
    customElements.define('my-component', MyWebComponents.MyCustomElement);
  </script>
  <my-component name="Svelte"></my-component>
</body>
</html>

Explanation:

  • We include the UMD build of our custom elements.

  • We define the custom element using customElements.define(), associating the tag name with our exported constructor.

  • We use the custom element in our HTML, passing the name prop.

If you want to use the .es.js file, you have to add the type="module"to enable es6 features.

<script src="dist/my-web-components.umd.js"></script>

Step 8: Serve the HTML File

You can use any local server to serve this HTML file. For example, with the http-server package:

  1. Install http-server globally if you haven't:

    npm install -g http-server
  2. Navigate to the directory containing your HTML file and run:

    http-server
  3. Open the provided URL in your browser (usually http://localhost:8080).

You should now see your custom element rendered on the page!

Additional Notes

  1. Browser Support: Custom elements are supported in all modern browsers, but you might need a polyfill for older browsers.

  2. Styling: Styles in Svelte components are automatically scoped to the custom element's shadow DOM.

  3. Props: All exported variables in your Svelte component become properties of the custom element.

  4. Events: Svelte's event dispatching works with custom elements, allowing you to listen to custom events.

  5. Slots: You can use Svelte's slot system, which translates to the native slot system of custom elements.

By following this tutorial, you've created a Svelte component, compiled it as a custom element, and used it in a standard HTML page. This approach allows you to leverage Svelte's powerful features while creating reusable web components that can be used in any web project, regardless of the framework.

Last updated