Generally, svelte-konva is a client-side only library. When using SvelteKit, special care needs to be taken if svelte-konva/Konva functionality is used on prerendered and server side rendered (SSR) components. Prerendering and SSR happens in a Node.js environment which causes Konva to require the canvas library as Konva can also be used in Node.js environments. When you use svelte-konva in such conditions you’ll likely run into the following error:
Error: Cannot find module ‘canvas’
There are multiple solutions to this problem:
Installing canvas:
Simplest solution is to install canvas:
npm i canvas |
This will satisfy the canvas dependency of Konva and you can use svelte-konva components in prerendered and SSR SvelteKit pages. The solution is a bit messy though, as you now have installed a package you don’t really need which adds unnecessary overhead. Alternatively use one of the following solutions:
Dynamically import your svelte-konva stage:
A better approach is to dynamically import your svelte-konva canvas on the client-side only. Suppose you have a Svelte component containing your stage with various svelte-konva components:
MyCanvas.svelte
<script> |
To use this component inside a SvelteKit prerendered/SSR page you can dynamically import it inside onMount()
and render it using <svelte:component>
:
+page.svelte
<script> |
Dynamically import svelte-konva using vite:
The vite-plugin-iso-import allows you to make client-side only imports without needing the manual approach in onMount()
described above. Please follow the installation instructions in the README then you can dynamically import your component like so:
+page.svelte
<script> |
Currently vite-plugin-iso-import cannot automatically fix intellisense inside .svelte files with TypeScript. Consult the README for a workaround to this problem. Or have a look at the demo below.
Instructions: Each page available in this SvelteKit App is rendered differently containing a svelte-konva
canvas. Both dynamic import approaches are shown. Dynamic loading using onMount()
on the prerendered page and dynamic loading with vite-plugin-iso-import on the SSR page. Try to inspect the network requests made on each navigation to understand the different approaches of rendering in SvelteKit.