SvelteKit can be used to build both static and server-rendered websites. I had a great experience building static websites with it multiple times, so I decided to write down the steps here.
Create a Svelte project
First, create a new Svelte project:
1
|
npx sv create my-static-website
|
Select the following options:
- SvelteKit minimal
- TypeScript (optional)
- “What would you like to add to your project?” - Nothing
- Package manager: npm
The project should be populated with a sample page. Feel free to modify it, but we will continue with the default one for this tutorial.
Build the project
To build a static site, we first need to install the required dependency:
1
|
npm i -D @sveltejs/adapter-static
|
Then, add the adapter to the svelte.config.js
file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
// svelte.config.js
import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: vitePreprocess(),
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter({
// default options are shown. On some platforms
// these options are set automatically — see below
pages: 'build',
assets: 'build',
fallback: undefined,
precompress: false,
strict: true
}),
// If your repo name is not equivalent to your-username.github.io, make sure to update config.kit.paths.base to match your repo name.
// This is because the site will be served from https://your-username.github.io/your-repo-name rather than from the root.
paths: {
base: process.argv.includes('dev') ? '' : process.env.BASE_PATH
}
}
};
export default config;
|
We also need to specify some options in src/routes/+layout.ts
to make sure the site can be statically generated at build time:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
// server-side rendering
// false = single-page application
export const ssr = false;
// client-side rendering
// false = no js on client
export const csr = true;
// Prerendering means generating HTML for a page once, at build time, rather than dynamically for each request
// no effect when running in dev mode
export const prerender = true;
// Optional: always add trailing slash to URLs
export const trailingSlash = "always";
|
We should be able to build the project now:
Deploy the site
For deployment, there are a few options as described in the official documentation. I like to deploy my stuff with Docker.
First, create a Dockerfile in the root of the project:
1
2
3
4
5
6
7
8
9
10
11
12
|
# Dockerfile
FROM node:22 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
|
Then, test building the Docker image:
1
|
docker build -t static:test .
|
This will produce a light-weight docker image that contains nginx and the static site.
It is totally fine to manually build and push the image for deployment, but I like to automate it with GitHub Actions. Details in this post.