Description
Describe the bug
Hello,
I am having difficulties getting the slot feature working for Svelte Components that are compiled as Custom Elements. When I compile the component into a custom element and use it as follows
<head>
<script src="./counter-component-wc.js"></script>
</head>
<body>
<counter-component>
<p slot="middle">blue world</p>
</counter-component/>
</body>
I expected "blue world" to replace the default slot content of <counter-component>
. However, the default slot content (i.e. <span>This is the default slot </span>
still gets rendered:
In addition, I can't seem to get the extend
keyword to work with the Custom Element API:
<svelte:options
customElement={{
tag: 'counter-component',
extend: (customElementConstructor) => {
return class extends customElementConstructor {
constructor() {
super();
console.log('hello world')
}
};
}
}},
/>
Specifically, I extended the customElementConstructor with a class that simply prints "hello world" in its constructor body. However, "hello world" doesn't show up in the console whenever the custom element <counter-component>
is mounted on the web page.
Check out the reproduction instructions below for details. The bottom of the instructions includes a .zip of the repository that you can use as well if it's more convenient.
Am I doing something wrong, or is this a bug?
Thanks for your time!
Reproduction
# Create a new project. Specify "SvelteKit demo app", "Typescript", and "Prettier" when prompted.
npm create svelte@latest my-app
cd my-app
npm install
npm install \
@rollup/plugin-commonjs \
@rollup/plugin-node-resolve \
@rollup/plugin-replace \
@rollup/plugin-typescript \
rollup-plugin-css-only \
rollup-plugin-scss \
rollup-plugin-svelte
In the included src/routes/Counter.svelte
, insert a <svelte:options>
element to mark the component as a custom element with a custom element constructor that simply prints "hello world". In addition, add an arbitrary <slot>
element in the component's template:
<!-- src/routes/Counter.svelte -->
<svelte:options
customElement={{
tag: 'counter-component',
extend: (customElementConstructor) => {
return class extends customElementConstructor {
constructor() {
super();
console.log('hello world')
}
};
}
}},
/>
...
...
<div class="counter">
<slot name="header">
<span>This is the default slot</span>
</slot>
...
...
</div>
Create a file called counter-component-wc.ts
in the src/
directory that imports the .svelte file that we want to compile into a custom element:
// src/counter-component-wc.ts
import Counter from './routes/Counter.svelte';
Create a rollup.config.js file in the root of the repository, which is used to compile counter-component-wc.ts
into a standalone counter-component-wc.js
file:
// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';
import svelte from 'rollup-plugin-svelte';
import scss from 'rollup-plugin-scss'
import typescript from '@rollup/plugin-typescript';
import commonjs from '@rollup/plugin-commonjs';
import sveltePreprocess from 'svelte-preprocess';
export default {
input: 'src/counter-component-wc.ts',
output: {
file: 'public/counter-component-wc.js',
format: 'iife',
name: 'app',
},
plugins: [
resolve({
// Allow browser-specific functionality like onMount() to be
// included in bundle.
browser: true
}),
commonjs(),
scss(),
typescript(),
svelte({
preprocess: sveltePreprocess({scss: true}),
compilerOptions: {customElement: true}
}),
]
};
Run npx rollup -c rollup.config.js
. counter-component-wc.js
should be generated in the public/
directory.
Afterwards, create a simple index.html file that uses the custom element that we just compiled. The <counter-component>
has an arbitrary <p>
nested with a slot="header"
attribute.
<!-- public/index.html -->
<!doctype html>
<html>
<head>
<title>Web Component Sandbox</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="./counter-component-wc.js"></script>
</head>
<body>
<h1>Hello World. This is a Web Component Demo.</h1>
<br/>
<counter-component>
<p slot="header">blue world</p>
</counter-component/>
</body>
</html>
Then open public/index.html in your browser.
I also have a .zip of the repository with the above edits. Extract the zip, run npm install
, npx rollup -c rollup.config.js
, and then open public/index.html
in your browser.
Logs
No response
System Info
System:
OS: Windows 10 10.0.19045
CPU: (8) x64 Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz
Memory: 5.91 GB / 15.96 GB
Binaries:
Node: 16.17.1 - C:\Program Files\nodejs\node.EXE
npm: 8.15.0 - C:\Program Files\nodejs\npm.CMD
pnpm: 8.6.6 - ~\AppData\Local\pnpm\pnpm.EXE
Browsers:
Edge: Spartan (44.19041.1266.0), Chromium (114.0.1823.82)
Internet Explorer: 11.0.19041.1566
npmPackages:
svelte: ^4.0.5 => 4.0.5
Severity
annoyance