The easy way
GitHub is a great deploy option for static websites and works especially well for Svelte libraries where you can use SvelteKit to author the package (in the /lib
folder) with the docs and examples published from the /routes
pages.
There are already several guides on how to deploy a SvelteKit app to GitHub pages but I found many contain unnecessary complexity or required configuration changes that are not needed.
So I thought I’d share and describe the deploy action I use - the exact same file can be copied into any SvelteKit project as-is and “just works”.
Of course GitHub pages are static only, so you have to be using the Static Adapter for SvelteKit.
First install it as a dev dependency using your package manager of choice which really should be pnpm
(trust me!):
pnpm i -D @sveltejs/adapter-static
Then change the adapter used in svelte.config.js
which should be a case of replacing the default @sveltejs/adapter-auto
with @sveltejs/adapter-static
instead:
import adapter from '@sveltejs/adapter-static'
Go to the Settings tab on your GitHub repo and the Pages
section on the left. The “Build and deployment” option should be set to use Github Actions.
Now just add the following .github/workflows/deploy.yml
file to your project and commit it. There is nothing project-specific that needs to be changed so the exact same file can be used for any project:
name: Deploy to GitHub Pages
on:
# Trigger the workflow every time you push to the `main` branch
# Using a different branch name? Replace `main` with your branch’s name
push:
branches: [master]
# Allows you to run this workflow manually from the Actions tab on GitHub.
workflow_dispatch:
# Allow this job to clone the repo and create a page deployment
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 8
- name: Install Node.js
uses: actions/setup-node@v3
with:
node-version: 18
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Setup Pages
uses: actions/configure-pages@v3
with:
static_site_generator: sveltekit
- name: Build
run: pnpm run build
- name: Upload Artifacts
uses: actions/upload-pages-artifact@v1
with:
# this should match the `pages` option in your adapter-static options
path: 'build/'
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy
id: deployment
uses: actions/deploy-pages@v1
Your SvelteKit project should now auto-deploy after a commit and appear on github pages.
So how does it work and why is it different?
Well first, if you use GitHub actions you don’t need to bother with any .nojekyll
file. That is simply a leftover from the-time-before-actions when pages could only be published by setting up a separate branch, and github pages were initially designd to use “Jekyll” for templating. For SvelteKit especially, it just makes sense to use GitHub actions rather than a separate branch - what you want to deploy is the app itself containing the routes.
Secondly, the action knows that it’s deploying a SvelteKit project, and it knows the name of the repository, so it can configure the base path for you without needing any environment setup or test for whether it’s running in production or development mode. Not having to configure the project to know it’s own name is one less change to make which seems easier to me.
As long as you are using pnpm
(you really should be), the default branch name and out-the-box SvelteKit setup this should work as-is. You can of course customize it if you need to but I’ve found it’s re-usable and I can just re-use it across projects
Please let me know what you think and if you see any way to improve it!