Cover image for Statically generated website with Svelte and Sapper

Statically generated website with Svelte and Sapper

vannsl profile image Vannsl ・Updated on ・5 min read

This article is Part I of my first three posts about Svelte. Part II discusses Svelte Single File Components in more detail. Part III shows how to use TailwindCSS with Svelte and Sapper.

In this article we will configure VS Code for Svelte, install the demo application of Sapper, discuss the project structure, run the E2E tests, build the demo application statically and deploy it on Netlify.

Svelte: 3.16.7
Sapper: 0.27.9 (! early state)


In this article, we will go through the process of setting up a statically generated website with Svelte or more specifically its companion framework Sapper. I'm currently using this framework to build my portfolio web page from scratch. The code of currently unfinished version can be found on my Sapper repository on github.

What is Svelte?

Svelte is a free and open-source software for creating performant web sites. In comparison to React and Vue, Svelte does a lot of work already in the compile step while building the application. React and Vue do a lot of these tasks in the browser. I've tried it out and in my opinion. It's worth to give it a shot or at least keep it in mind.

I won't go further into the technical details of Svelte. The contributors know them better as me. There is a lot of great material on their blog to understand how the framework works. They provide a detailed tutorial. The talk of Rich Harris, the mind behind rollup and Svelte, about Rethinking Reactivity explains everything you need to know about the backgrounds of Svelte. Check them out! Reading the documentary is the key to become a better developer πŸ™‚.

What is Sapper?

Sapper is the companion of Svelte, like Nuxt is it for Vue or Next is it for React. It includes

  • server-side rendering
  • automatic routing (using the "routes" directory, similar to "pages" directories of Nuxt and Next)
  • code splitting
  • offline support (using service workers)

...and therefore the ability to create statically generated pages.

VS Code Support

Before creating the demo application, the IDE should be configured for Svelte. As we see below more detailed, a .svelte file is organized similar to pure .html files. To enable syntax highlighting, open the settings (JSON) in VS Code. Do that by clicking Cmd + Shift + P to open the Command Palette and open Preferences: Open Settings (JSON) and add the following setting:

"files.associations": {
  "*.svelte": "html"

There are also some Svelte Extensions available. I've recommend to install the extensions Svelte language support and Svelte 3 Snippets.

Create a new project

Let's dive into it. To create a new project execute the following commands in the terminal:

npx degit "sveltejs/sapper-template#rollup" sapper-app
# or npx degit "sveltejs/sapper-template#webpack" sapper-app
cd sapper-app
npm install
npm run dev

Project structure

If you already have worked with Nuxt or Next, the folder structure will be familiar to you. The folder structure of the demo application is:

  • ./__sapper__ which includes the built files for production, dev and static modes
  • ./cypress for e2e testing
  • ./node_modules
  • ./src which includes the source files
    • ./components which includes the single file components
    • ./node_modules
    • ./routes which includes page components with names representing the URL path (e.g. index.svelte or about.svelte) and layout files containig the skeletons (e.g. _layout.svelte or _error.svelte)
    • client.js, the client entry
    • server.js, the server entry
    • service-worker.js
    • template.html, which contains the content of the wrapping HTML for each page
  • ./static for assets
  • package.json
  • package-lock.json
  • README.md
  • [rollup|webpack].config.js

Most of the things to develop will be in the directories src/components and src/routes. In both folders, you will find .svelte files. A more detailed explanation about the Single File components will be provided in Part II, I will skip that part for this article.

However, the interesting components for Sapper are the layout and page components. Let's have a closer look at them.

Layout Skeletons

Layout Components structure the wrapping HTML of different pages. It enables the possibility to add Header, Navigation, Footer and other components which should be on several pages more easily. In the example below, we see a skeleton with a Header, Footer and the main content. The content of the page will be provided through the page components. Their content will be rendered in the unnamed <slot></slot>.

  import Header from '../components/Header.svelte';
  import Footer from '../components/Footer.svelte';

  main {
    margin: 0 auto;
    max-width: 1200px;


Have a look at Part II for more details of the naming conventions of child components. Note here, that we can use Header and Footer as names although these names are already given to pure HTML tags. This is possible since Svelte component names are case sensitive. By using PascalCase, it is not needed to add a prefix like "the" for TheHeader or TheFooter.

Routes Component

To create a new page, a new .svelte file has to be added into the src/routes directory. Besides the blocks <script> and <style> page components can use a <svelte:head> block. This block contains HEAD information, like a title or meta description. It is usually put after the blocks <script> and <style> before the template part.

  <title>My first Sapper app</title>

<p>This is my first Sapper app</p>

Accessibility Feature

A great feature of Svelte is that it checks the a11y of the template. πŸ‘πŸ‘πŸ‘
If an <img> tag misses the attribute alt, it prints a warning. It is still possible to compile the application.

E2E Testing

The demo application of Sapper includes a Cypress E2E test. To run tests execute

npm run test

You might get an error that your machine does not know "cypress". That means that you still have to install it. On purpose, cypress is not a dev dependency to minimize the install time. This topic was discussed in this github issue and solved with this commit adding the information to the README.md. You can either add it as a dev dependency yourself with

npm install cypress --save-dev

or install is globally to use it everywhere

npm install -g cypress

Static Build

πŸŽ‰ That's all you need to know to create your first Sapper application. πŸŽ‰

Let's build it. To execute the static build of the demo application, run:

npm run export

and find the built files in the directory ./__sapper__/export.

Netlify Deployment

To deploy the static page on Netlify, initialize the project as a git repository and upload it on GitHub. Import that project on Netlify. Go to the project's settings. Edit the settings for Build & Deploy. The build command is npm run export. The publish directory is __sapper__/export. Trigger the deploy and the application will be built and deployed.


Editor guide
khrome83 profile image
Zane Milakovic

Nice write up. I did this for Khrome.dev.

We started to adopt this professionally at my job as well. The biggest issues we have found is with Sapper not Svelte.

It’s worth mentioning that Sapper is not ready for production in general. We use it, because we are static generation of the site in the build pipeline, so the risk is not see by users.

We found out that the current Sapper version has memory issues when you go about a few hundred pages. It depends on the complexity, but it’s pretty easy to hit. So it’s good now for small sites, but marketing and enterprise sites should think twice.

We opened a few PR that solve these issues, and improves the deploy time greatly. But they have been sitting idle since September. Which makes me worried the project is vaporware.

Otherwise I have really grown to love it.

vannsl profile image
Vannsl Author

That's very good to know. I've added the version of Sapper in the beginning of the article because I also had the same feeling that Sapper is not ready for complex applications yet. I read that the authors of the open-source software are telling us the same on their web page.

I think for the early state of the project a lot more things are working than I would have imaged. E.g. I can change the tailwind.config.js and it gets recompiled on the fly. But from time to time (more often than I'd like to) I have to restart the process.

I totally enjoy writing it, it feels even more "vanilla-javascriptishy" than Vue. Amazing that you've tried it out for more complex applications and giving us your insights.

khrome83 profile image
Zane Milakovic


You can check out my source code for my blog. I am hosting on Zeit Now instead of Netlify, otherwise pretty similar.

The one thing I did was try and replace Gridsome, which uses GraphQL to access Markdown files.

I am not 100 hundred percent happy with the final output. I want to get the graphql into the page itself, instead of the JSON file, but it worked out well. It keeps the request only having the data I need.

rubenmedios profile image
Ruben Rojas @rubenmedios

Hello, this is a big proyect for start with svelte + sapper, i love it!
I use this tutorial for begin a project, but have some complications with routes, i need publish this project in a subdirectory of my server, but the navigation links always use for default the root url or root directory, i can't configure the basepath and have not very knowledge where i put the info for basepath to make the app run in a subdirectory of my server. Thanks in advance for help.