Svelte and SvelteKit setup
Set svgworm up in a Svelte or SvelteKit app in three steps. The Icon component is a plain .svelte file that init writes into your project. It needs no extra package, and it renders the same markup as the React Icon. With server rendering, icons show before any JavaScript runs.
Requires Node ^22.20 || >=24.11 and Svelte 5 (runes).
Steps#
-
Install and set up:
pnpm add -D svgworm && pnpm svgworm init # npm: npm install -D svgworm && npx svgworm init # yarn: yarn add -D svgworm && yarn svgworm initinitsees thesvelteor@sveltejs/kitdependency and does the setup for you:- Files: writes
svgworm.config.json, thepredev/prebuildscripts and the component. Then it builds once. - SvelteKit: the component goes to
src/lib/components/Icon.svelte. The sprites go tostatic/icons/, because SvelteKit servesstatic/, notpublic/. - Svelte with Vite: the component goes to
src/components/Icon.svelte, and the sprites go topublic/icons/. - Sample icon: if
icons/is missing or empty, it addsicons/svgworm.svgso the first build works. - Flags: with
--yesit asks nothing. Use--framework sveltewhen the project has nosveltedependency yet.
See the CLI reference for every flag.
- Files: writes
-
Put your SVG files in
icons/(delete the sample) and build:pnpm svgwormThis writes the sprite to the static folder and the manifest and types to
svgworm/. While you work, runsvgworm watchnext to the dev server to rebuild on each change. -
Use it in any component:
<script lang="ts"> import Icon from '$lib/components/Icon.svelte'; </script> <nav> <Icon name="home" /> <Icon name="brand/sunset" width={32} height={32} /> <Icon name="home" title="Go home" class="nav-icon" /> </nav>- Names come from the file paths:
homeisicons/home.svgandbrand/sunsetisicons/brand/sunset.svg, lower-cased with-between words. - Type-checked:
nameis typed from the generatedIconName, so a typo failssvelte-check. - Decorative by default: the icon is
aria-hiddenunless you passtitleorlabel. - Attributes pass through:
class,style(a string),id,data-*andaria-*land on the rendered element.
- Names come from the file paths:
Icon.svelte is your file, and init never overwrites it. To refresh it after upgrading svgworm, delete it and run svgworm init again.
Set up by hand#
Without init, run the CLI before dev and build yourself:
{ "scripts": { "predev": "svgworm", "prebuild": "svgworm" } }
Yarn 2+ never runs pre scripts. With it, put the command in front of the scripts instead, for example "dev": "svgworm && vite dev". For SvelteKit, set "outDir": "static/icons" and "publicPath": "/icons" in svgworm.config.json.
With Vite, the optional svgworm/vite plugin can rebuild icons inside vite dev. It does not depend on React. See the plugin section of the Vite setup.
base#
Content-Security-Policy#
Svelte’s server renderer adds onload and onerror attributes to an <img> with spread attributes, to replay those events on hydration. That touches icons with the img delivery (multicolor icons with gradients, masks, clip paths or filters). They are inline event handlers, so a strict script-src without 'unsafe-inline' blocks them and reports a violation. The image still loads. The other deliveries have no such attributes.
Sprites on a CDN#
init --cdn-url is not supported for Svelte yet: crossOrigin "inject" needs a loader <script> in the page, and init does not write one for Svelte (ADR-0034). Icon.svelte already renders the in-page references that mode needs. Until it is, serve the sprites from your own origin.
Cache for a year#
The file names are content-hashed, so a long cache is safe. Send Cache-Control: public, max-age=31536000, immutable for /icons/* from your host, as in the Astro setup.
What to commit and CI#
Commit the sprite folder (static/icons/ or public/icons/) and svgworm/, and run svgworm check in CI, before the build. It fails when someone changed an icon and forgot to rebuild. Or ignore both folders and rely on the predev and prebuild scripts: then anything that type-checks before the build must run svgworm first.
pnpm svgworm check
pnpm build
How it is checked#
A conformance test compiles the generated Icon.svelte for the server and checks that it renders the same markup as the React Icon from the same manifest, for every delivery. svelte-check checks that an unknown name is a type error.
Next steps#
- Icon component: every prop, the markup per delivery, sizing and coloring with CSS.
- How it works: the sprite, the stack, delivery forms, the manifest and determinism.
- CLI reference: every command, flag and exit code.
- Troubleshooting: blank icons, 404s, wrong colors, collisions,
checkin CI. - Using Vue? Read the Vue setup.