I have doubts about how to create a Custom element API. I have followed the documentation, but I get the following warning:
The 'tag' option is used when generating a custom element. Did you forget the 'customElement: true' compile option? (Link.svelte: 1:16)
I have marked customElement: true
in compiler options.
I'm lost, can anyone help me?
So it appears that the REPL doesn't really support custom elements. It kind of make sense...
The general idea with custom elements in Svelte is as follow:
customElement: true
For example, in the default Rollup template, you'd set this option here in the Svelte plugin for Rollup:
plugins: [
svelte({
compilerOptions: {
customElement: true,
...
}
...
}),
...
]
<svelte:options tag="what-ever" />
to your Svelte components<svelte:options tag="what-ever" />
<script>
// make sure component Foo is available, but we don't import
// it... we'll use it with it's tag <my-foo /> (see bellow)
import './Foo.svelte'
export let name = 'World'
</script>
<p>Hello, {name}!</p>
<my-foo {name} />
<style>
p { color: skyblue; }
</style>
Foo.svelte
<svelte:options tag="my-foo" />
<script>
export let name
</script>
<p>I am {name}</p>
Note that you can't mix and match custom element components with normal components.
This means you'll have to add the tag
option to all you children components and, instead of importing components as usual, you'll use their tag name directly in your markup.
You'll still need to import the files for the components to be available (but with empty imports, eg import './Foo.svelte'
).
If we keep with the example of Svelte official template for Rollup, then you'll end up with a generated bundle.js
file.
bundle.js
file in a HTML page:<script defer src='/build/bundle.js'></script>
<div>
or <strong>
.They will be implemented as Svelte components but, as this stage, this is now an implementation detail.
So, for example, in this page, you can now do things like:
document.body.querySelector('#container').innerHTML = '<what-ever>Foo</what-ever>'
Or, you could have this in your HTML (for example, in the index.html
file of the default template):
<body>
<what-ever>foo</what-ever>
</body>
And that's it. In some situation, this can be fancy, or very handy. You can have custom elements implemented in a smooth declarative framework, that you can use in any context (as long as you can import a .js
file), with minimal overhead due to the framework itself.
That's nice if you want to include this as a widget on a Wordpress blog instead of using jQuery, or even if you want to publish a framework-agnostic component.
Now, if your whole app is going to be Svelte based, it loses a lot of its salt, because Svelte custom elements do suffer some limitations (end of the linked section) as compared to regular Svelte components.
Whether you should use them or not depends on your use case.
And, in any event, it seems that you can't play with them in the REPL...
Since I've used the default Svelte template all along this answer, it should be noted that if you want to use it with custom elements, you should not initialize the App
component yourself in main.js:
import App from './App.svelte';
// NOT needed with custom elements
//const app = new App({
// target: document.body,
// props: {
// name: 'world'
// }
//});
export default app;
The entry points will now be individual custom elements that you create with the aforementioned techniques.
BUT you should still ensure that all of your custom elements .svelte
files are imported by the entry point (main.js
in this case) that is fed to Rollup, or they won't be available in the final bundle.js
file that is produced. (Importing in files that are imported by main.js
is fine.)