Mastering SvelteKit Deployment Part 1: Getting Started

  • SvelteKit
  • Deployment
  • SSR
  • Static Websites

Published on

One of the great parts of SvelteKit is how it supports different platforms in terms of deployment. It’s built with Zero restrictions, and you can deploy it almost everywhere.

Throughout this series, we will dive into various cloud-hosting services and explore our options. One exciting part about this journey is the vast knowledge you will gain about deployment platforms and what makes them different.

Outline

We will break down the series into the following parts:

When you decide to read a blog post on this series, I highly recommend applying what you learn. Doing so is the only way to learn and gain experience. You are free to skip parts as you see fit, but it would be best if you read Part 1 and Part 2

The Example app

We will use a sample app throughout this series, showcasing different features of SvelteKit. We will go through SSR, streaming, server actions, prerendering, ISR, Pure SSG, API handlers, and more. This app allows users to view and post comments and change their avatar image.

Go ahead and clone the GitHub repo, which contains the example app we’re going to deploy:

git clone

code deployed-sveltekit-app # Or use your favorite editor

We will be using Supabase for data storage. Setting up a supabase instance is pretty straightforward, but no worries! I made one for you. The public key is included within the repo πŸ‘€ - Remember it’s restricted. Feel free to set up your own for more freedom.

You will find that the file structure for the example app looks similar to the following:

.
β”œβ”€β”€ src
β”‚   β”œβ”€β”€ app.d.ts
β”‚   β”œβ”€β”€ app.html
β”‚   β”œβ”€β”€ index.test.ts
β”‚   β”œβ”€β”€ lib
β”‚   β”‚   ...
β”‚   └── routes
β”‚       β”œβ”€β”€ +layout.server.ts
β”‚       β”œβ”€β”€ +layout.svelte
β”‚       β”œβ”€β”€ +page.svelte
β”‚       β”œβ”€β”€ api
β”‚       β”‚   └── avatar
β”‚       β”‚       └── +server.ts
β”‚       β”œβ”€β”€ cache-headers
β”‚       β”‚   β”œβ”€β”€ +page.server.ts
β”‚       β”‚   └── +page.svelte
β”‚       β”œβ”€β”€ ssg
β”‚       β”‚   β”œβ”€β”€ +page.server.ts
β”‚       β”‚   └── +page.svelte
β”‚       β”œβ”€β”€ isr
β”‚       β”‚   β”œβ”€β”€ +page.server.ts
β”‚       β”‚   └── +page.svelte
β”‚       β”œβ”€β”€ ssr
β”‚       β”‚   β”œβ”€β”€ +page.server.ts
β”‚       β”‚   └── +page.svelte
β”‚       └── ssr-streaming
β”‚           β”œβ”€β”€ +page.server.ts
β”‚           └── +page.svelte
β”œβ”€β”€ static
β”‚   └── favicon.png
β”œβ”€β”€ svelte.config.js
β”œβ”€β”€ tests
β”‚   └── test.ts
β”œβ”€β”€ tsconfig.json
β”œβ”€β”€ vite.config.ts

Let’s break down our example app into the following parts:

  • +layout.svelte: The root layout has a navigation bar and the current page’s content. The navbar has a button to change the user avatar to a random one by firing an AJAX request to the /api/avatar endpoint.
  • +layout.server.ts: Contains a server load function that serves the root layout. It also fetches an initial user avatar, which is saved to a cookie β€” Note that the cookie on the load function won’t work for pre-rendered pages since the page is determined at build time.
  • ssr:
    • +page.svelte: This page displays a list of comments that are server-side rendered. It also has a feature for the users to post new comments, which is done by a form server action.
    • +page.server.ts: Contains the server action for posting new user comments. For our example app, those are saved to Supabase.
  • ssr-streaming:
    • +page.svelte: Same as the SSR page, The only difference is that it’s charged up with Streaming supprt. It will delay fetching unnecessary data to enhance the experience. Here we delay fetching comments by 2 seconds to simulate this behavior.
    • +page.server.ts: Similar to the SSR server load, the difference is that we make comments nested inside the object and omit the await, which allows us to stream the promise from the server.
  • ssg:
    • +page.svelte: This page displays the same comments, but this time they are statically generated once at build time, it’s not dynamic data anymore, and this page doesn’t allow adding new comments.
    • +page.ts: Exports a prerender = true option to enable static generation for this page.
  • ssg-sr:
    • +page.svelte: Same as SSG page, but here it’s charged up with Incremental Static Regeneration. It will keep running the load function to update comments at a specific fixed interval.
    • +page.ts: Exports a config object with the isr option, the expiration is set to 15 seconds. In real websites you would probably make it larger than this interval.
  • cache-headers:
    • +page.svelte: A simple page that shows the current time in β€œHH:mm:ss” format. What’s interesting here is that this page is served with a cache header.
    • +page.server.ts: Exports the current time with a Cache-Control header of max-age=10, which means that the time will be cached for 10 seconds.
  • /api/avatar: A GET request handler that generates a random avatar. It first generates a set of colors using the Node crypto API, then use those to return an imageSrc that points to the boringAvatars API.

As you see, we have integrated many features to experiment with. Note that not every feature will work on every platform, especially the server functions, which are not supported by static-only deployment platforms. We will dig deeper into this in the next parts.

Example App show

As we explore different deployment options, the example app may be modified. Each modified version will be in a separate branch based on the original example app, which is in the main branch.

That’s all for the first part. In Part 2, we will explain the concepts of adapters like never before! exciting things ahead! See you in the next one.

Β© 2023 Fayez Nazzal. All rights reserved.
Social Links:
contact@fayez.io