Skip to main content
vannsl.io | Blog

Statically generated website with Svelte and Sapper

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.


Versions:


Introduction

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

...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:

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>.

<script>
  import Header from '../components/Header.svelte';
  import Footer from '../components/Footer.svelte';
</script>

<style>
  main {
    margin: 0 auto;
    max-width: 1200px;
  }
</style>

<Header></Header>
<main>
  <slot></slot>
</main>
<Footer></Footer>

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.

<svelte:head>
  <title>My first Sapper app</title>
</svelte:head>

<h1>Hello!</h1>
<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.