3

I have a SvelteKit 2/Svelte 5 app with out-of-the-box configuration - what you get by running npx sv create my-app. I want to build my app normally with adapter-node, but I also want to build a single .svelte file as a web component that I can reuse in other projects.

Currently my setup is this:

// $lib/widget/MyComponent.svelte

<svelte:options
    customElement={{
        tag: 'my-component',
    }}
/>

<script lang="ts">
    let counter = $state(0)
</script>

<button onclick={() => (counter += 1)}>
    Clicked {counter} times
</button>
// svelte.config.js

import { mdsvex } from 'mdsvex'
import adapter from '@sveltejs/adapter-node'
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'

const config = {
    preprocess: [vitePreprocess(), mdsvex()],
    kit: {
        adapter: adapter(),
    },
    extensions: ['.svelte', '.svx'],
}

export default config
// vite.widget.config.ts

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

export default {
    build: {
        lib: {
            entry: 'src/lib/widget/MyComponent.svelte',
            name: 'MyComponent',
            fileName: (format) => `my-component.${format}.js`,
            formats: ['es'],
        },
        rollupOptions: {
            external: ['svelte'],
            output: {
                globals: {
                    svelte: 'svelte',
                },
            },
        },
        sourcemap: 'inline',
    },
    plugins: [
        svelte({
            compilerOptions: {
                customElement: true,
            },
        }),
    ],
}
vite build --config vite.widget.config.ts
<!-- root/my-component.html -->
<my-component></my-component>
<script src="./dist/my-component.es.js" type="module"></script>

It works, but I'm not sure if this is the correct way to do it.

I'm getting a warning in my .svelte file that I haven't specified customElement: true, but that's because I have my compiler options in vite.widget.config.ts.

I tried looking at the svelte/compiler docs, but I couldn't understand how I'm supposed to use that module.

Any tips are welcome!

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.