SvelteKit
Now that I have moved to Svelte 5, these docs should be focused on that version.
Configuration
You can add alias' to certain folders for importing. It is handy especially since there are no auto imports. VS Code can help with the import process, but having this sort of alias is handy to help it find what you are looking for.
//svelte.config.js
const config = {
kit: {
alias: {
$components: './src/lib/components',
},
},
};
You can use a cool experimental feature that allows you to click your page and it will take you to the code in VS Code. This makes it so when you are in Development mode you can hold Command+Shift and hover over an element to click. Documentation on the feature is found at https://github.com/sveltejs/vite-plugin-svelte/blob/main/docs/config.md#inspector
//svelte.config.js
const config = {
// ... Other configuration
vitePlugin: {
experimental: {
inspector: {
toggleKeyCombo: 'meta-shift',
holdMode: true,
showToggleButton: 'never',
}
},
},
};
Sass
SvelteKit comes with the preprocessor already available. All you need to do is run npm install Sass -D
.
To make variables accessible from any and add the following to svelte.config.js
. The file paths are relative to the config file.
import {sveltePreprocess} from 'svelte-preprocess';
const config = {
preprocess: [
sveltePreprocess({
scss: {
prependData: `
@import './src/sass/_variables.scss';
@import './node_modules/bootstrap/scss/mixins/_breakpoints.scss';
`,
},
}),
],
};
To add global styles to all pages, add the following to the main +layout.svelte
file.
<script>
import '../sass/style.scss';
</script>
Generating a Static Site
To generate a static website you must set the adapter to @sveltejs/adapter-static
in the svelte.config.js
file. That way when you run npm run build
it makes a static site instead of a SSR website.
import adapterStatic from '@sveltejs/adapter-static';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
adapter: adapterStatic(),
},
}
Another important thing to add is create a +layout.js
at the root of the src
directory. Add the following to that file:
export const prerender = true;
export const trailingSlash = 'always';
Error Page
Make a page called +error.svelte
at the root of the route directory and add this to get started:
<script>
import { page } from '$app/stores';
</script>
<h1>{$page.status} - {$page.error?.message}</h1>
<a href="/">Home Page</a>
Assuming that the adapter is adapter-static
make sure you have this in your svelte.config.js
file before deploying to Firebase or GitHub Pages:
import adapterStatic from '@sveltejs/adapter-static';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
adapter: adapterStatic({
fallback: '404.html',
}),
},
}
Deploying to GitHub Pages
Alternative Option
Instead of this process here, you can use GitHub Actions. See SvelteKit's Documentation for details
One thing that tripped me up was that there were a lot of files that were ignored from GitHub Pages. After doing research and waiting for the domain to correctly register, I found that directories and files preceding with an _
are ignored by default. To fix this, simply add a .nojekyll
file in the static directory. This is an empty file and you don't need to do anything but create it.
The next thing to do is to change the output directory from build
to docs
. In the svelte.config.js
file, make sure the following is there:
import adapterStatic from '@sveltejs/adapter-static';
/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
adapter: adapterStatic({
pages: 'docs',
assets: 'docs',
}),
},
}
Then in GitHub make sure the pages is hosted from the master branch at /docs.
I don't know how to do this at a sub path, this will only work at a subdomain setup.
Typings
With Svelte 5 I guess it is recommended to just use JS instead of TS and use jsDoc syntax for typings. I'm okay with this, but I am learning a few things as I go along. Here are some things that were hard to find.
Children Props
/**
* @type {{
* href: string,
* theme: string,
* children: import('svelte').Snippet
* class?: string
* }}
*/
let { href = '', theme = 'primary', children, class: classList = '' } = $props();
Class Props
<script>
/**
* @type {{
* class?: string
* }}
*/
let { class: classList = '' } = $props();
</script>
<div class="{classList}">Hello World</div>
Create Elemental Components
I really like how Nuxt will auto-import components for you. There are libraries out there for this, but they all seem to have some shortcomings. This is my solution that isn't automatic, but just a one-liner.
You can add these files:
// src/components/Elemental/Btn.svelte
<button class="btn btn-primary"><slot /></button>
// src/components/Elemental/index.ts
export { default as Btn } from './Btn.svelte';
And use it like this:
<script lang="ts">
import * as E from '$components/Elemental';
</script>
<E.Btn>Hello</E.Btn>
I would recommend that you add a snippet for each one. You would probably want to do that anyway.
Nuggets
Google Analytics
This stems from this issue thread. Make sure that "Enhanced Measurement" is turned on in Google Analytics or this will not work!
Make a component like Analytics.svelte
and add the following code (replacing the G-XXXXXXXXXX).
<script>
// @ts-nocheck
import { dev } from '$app/environment';
import { afterNavigate } from '$app/navigation';
afterNavigate(() => {
if (!dev) {
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
}
});
</script>
<svelte:head>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
</svelte:head>
Comments in VS Code on hover
Add this to the beginning of a component. When you hover over that component reference this will show up.
<!--
@component
## Title
You can use `markdown` in this.
-->
Only run js on client
This is helpful for things like "window.*" or things that need a DOM to run. You can also use the OnMount()
hook.
import { browser } from '$app/environment';
if(browser){
return getComputedStyle(document.documentElement).getPropertyValue('--bs-primary');
}
Constant variable in each block
https://svelte.dev/repl/00e2468ea1b147acb25a679a1fbcb12a?version=3.46.0
In short:
{#each boxes as box}
{@const area = box.width * box.height}
...
{/each}