A preprocessor for svelte that allows you to annotate a component as a client component with the extension .client.svelte
Contributions are always welcome!
If you want to start contributing take a look at the contributions guidelines, otherwise if you found a problem or have an idea feel free to open an issue
If you want the fastest way to open a PR try out Codeflow
Install svelte-client-components with pnpm (or npm, or yarn)
pnpm install svelte-client-components@latest -D
The only thing you have to do to use this preprocessor is add it to your svelte.config.js
import adapter from '@sveltejs/adapter-static';
import { svelte_client_components } from 'svelte-client-components';
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: svelte_client_components(),
kit: {
adapter: adapter(),
},
};
export default config;
to annotate a component as a client component you can just use the extension .client.svelte
(eg. Button.client.svelte
).
The preprocessor will be invoked before the svelte compiler and will change your code to prevent the component to be rendered during SSR. How? It make use of the fact that server svelte will not await Promises inside the {#await}
block.
Whenever you will use a Component that has .client.svelte
in the import path will be changed to a dynamic import and the usage will be wrapped in an await
block to await that import. Let's see a simple example.
This code
<script>
import Test from './Test.client.svelte';
</script>
<Test />
will be preprocessed to become this
<script>
const Test = import('./Test.client.svelte');
</script>
{#await Test then { default: Test }}<Test />{/await}
As you have just read this preprocessor uses static analysis to do his job. This means that it has unfortunately some gotcha's. For example you cannot import anything else from the component file. This is not usual in svelte but it might happen if you export something from <script context="module">
. This is the cases that are currently tracked by the preprocessor
<script>
import Test from './Test.client.svelte';
</script>
<Test />
svelte:component
<script>
import Test from './Test.client.svelte';
</script>
<svelte:component this={Test} />
N.b. this will only work if you use the actual imported component in the this
attribute
const
variable<script>
import Test from './Test.client.svelte';
const Test2 = Test;
</script>
<Test2 />