Statically generated website with Svelte and Sapper
Tags: javascript, tutorial, webdev, svelte
Published: 2020-01-05 10:51:52

This article is Part I of my first three posts about Svelte. Part II discusses [Svelte Single File Components](https://dev.to/vannsl/all-you-need-to-know-to-start-writing-svelte-single-file-components-cbd) in more detail. Part III shows [how to use TailwindCSS with Svelte and Sapper](https://dev.to/vannsl/configuring-tailwindcss-for-sapper-58jm). 

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:**
Svelte: 3.16.7
Sapper: 0.27.9 (!  early state)

## Introduction

In this article, we will go through the process of setting up a statically generated website with [Svelte](https://svelte.dev/) or more specifically its companion framework [Sapper](https://sapper.svelte.dev/). 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](https://github.com/Vannsl/portfolio-sapper).

### What is Svelte?

[Svelte](https://svelte.dev/) is a free and open-source software for creating performant web sites. In comparison to [React](https://reactjs.org/) and [Vue](https://vuejs.org/), 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](https://svelte.dev/blog) to understand how the framework works. They provide a detailed [tutorial](https://svelte.dev/tutorial/basics). The talk of Rich Harris, the mind behind [rollup](https://rollupjs.org/guide/en/) and Svelte, about [Rethinking Reactivity](https://svelte.dev/blog/svelte-3-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](https://sapper.svelte.dev/) is the companion of Svelte, like [Nuxt](https://nuxtjs.org/) is it for Vue or [Next](https://nextjs.org/) 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:

```json
"files.associations": {
  "*.svelte": "html"
}
```

There are also some Svelte Extensions available. I've recommend to install the extensions [Svelte language support](https://marketplace.visualstudio.com/items?itemName=JamesBirtles.svelte-vscode) and [Svelte 3 Snippets](https://marketplace.visualstudio.com/items?itemName=fivethree.vscode-svelte-snippets).

## Create a new project

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

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

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

```html
<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

```shell
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](https://github.com/sveltejs/sapper-template/issues/22#issuecomment-500228964) and solved with [this commit](https://github.com/sveltejs/sapper/pull/975/commits/71ce2c0fd4fd7aa750ca6e484a34350938103153) adding the information to the _README.md_. You can either add it as a dev dependency yourself with

```shell
npm install cypress --save-dev
```

or install is globally to use it everywhere

```shell
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:

```shell
npm run export
```

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

## Netlify Deployment

To deploy the static page on [Netlify](https://www.netlify.com/), 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.