DEV Community

Cover image for Building your static website with Svelte, SvelteKit and TailwindCSS
Roberto B.
Roberto B.

Posted on • Edited on

Building your static website with Svelte, SvelteKit and TailwindCSS

In this post, I would like to share my process for building a new website to launch my next open-source project.

This post is updated for Svelte 5 and using the Svelte CLI

I aim to build a website with a few pages, a home page, and some pages explaining the process.

To achieve that, I need to:

  • use a kit to help me structure pages/modules/layout (a couple of pages that share some modules like header, footer, nav bar, etc.);
  • on-demand file serving over native ESM;
  • fast Hot Module Replacement;
  • optimized build;
  • serve static pre-render files (no server-side logic/language);
  • use Tailwind CSS for styling;
  • using an approach that helps me in following some SEO guidelines.

I decided to use Svelte 5 to develop the frontend part and started using Vite Js with the Svelte template. But I saw that Svelte ships SvelteKit, based on Vite Js and more optimized for Svelte features. So, I decided to proceed with SvelteKit.

The goal of this post is to show you all the basic steps to have an environment for creating pages; it is not focused on HTML, CSS, and JS development. So I'm going to:

  • install SvelteKit;
  • create index and about pages;
  • add Tailwind in the "SvelteKit" way;
  • set up the process to have a static build ready to be deployed on service with no server-side language.

You can find the source code of the project built with this article here: https://github.com/roberto-butti/example-sveltekit-static

Install SvelteKit

To install SvelteKit, you can use the Svelte CLI via the sv command.

The Svelte team released on October 2024 the new Svelte CLI, a command line tool for creating, enhancing, and upgrading Svelte projects. Here is the official announcement on Introducing the new Svelte CLI

Usually, I use Bun (bun/bunx) for managing packages and node modules and launching JS command (but similarly, you can use Npm or Yarn or Pnpm). To execute the Svelte CLI, you can use bun:

bunx sv create  example-sveltekit-static
Enter fullscreen mode Exit fullscreen mode

The Svelte CLI will create the files to start a SvelteKit project quickly.
The command will ask you a few questions; here is the option I selected for this example (I tried to select the option for a minimal project with Svelte 5):

  • Which template would you like? SvelteKit minimal
  • Add type checking with Typescript? Yes, using Typescript syntax
  • What would you like to add to your project? none
  • Which package manager do you want to install dependencies with? bun

Creating your first SvelteKit web application

Then, once the bunx sv create command has completed the execution, you can enter into the new directory example-sveltekit-static. The dependencies were already installed by the Svelte CLI. and install all the dependencies:

cd example-sveltekit-static
bun dev -- --open
Enter fullscreen mode Exit fullscreen mode

The bun dev ( or the bun run dev) command launches the project, opening the browser's home page. You should see a page with the headline Welcome to SvelteKit.

The new SvelteKit project is up and running

Don't worry about the style. This is a basic unstyled page, which is useful for checking the installation process.

Now that your basic SvelteKit structure is running, you can add new pages, features, and styles.

Create the "About" page

Your index page is in the src/routes directory. By convention, the pages/views in SvelteKit are named +page.svelte. The name of the directories determines, by default, the URL path. Let me list some examples to clarify the basic routing mechanism:

  • src/routes/+page.svelte is the view used for the / URL path;
  • src/routes/about/+page.svelte is the view used for the /about URL path;
  • src/routes/projects/project1/+page.svelte is the view used for the /projects/project1 URL path.

So, if you want to create a new page accessible via the URL path /about, you must create a +page.svelte file in the src/routes/about/ directory.
In other words, there is an implicit convention that the src/routes structure determines the URL path.

So now you can create src/routes/about/+page.svelte file:

<h1>About page</h1>
<div>Ciao!</div>
Enter fullscreen mode Exit fullscreen mode

If you have your bun dev up and running now, you can go to http://localhost:5173/about, you should see the unstyled About page.

Add Tailwind CSS

Now, we can focus on the style, including Tailwind CSS. To do that, I will use the Svelte CLI instead of manually installing the Tailwind and PostCSS packages.

If you used Svelte in the past (Svelte 4, for example), you probably used the Svelte-Add command. There is no longer a need for it, and it is deprecated because we have the new Svelte CLI.

For adding TailwindCSS you can execute:

bunx sv add tailwindcss
Enter fullscreen mode Exit fullscreen mode

The command will ask you if you want to add some TailwindCSS plugin, usually I install the typography one.

The Svelte CLI is very useful for adding Tailwind because it can cover:

  • the package tailwindcss, autoprefixer, and tailwindcss/typography installed in the latest version;
  • the file postcss.config.js created and filled with basic defaullts;
  • the src/app.css created with the proper setup for Tailwind CSS;
  • the src/routes/layout.css created for loading the app.css file
  • the tailwind.config.ts created with basic defaults.

The file src/app.css created is:

@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
Enter fullscreen mode Exit fullscreen mode

The file postcss.config.js created is:

export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {}
  }
};
Enter fullscreen mode Exit fullscreen mode

The file src/routes/+layout.svelte created is:

<script lang="ts">
        import '../app.css';
        let { children } = $props();
</script>

{@render children()}
Enter fullscreen mode Exit fullscreen mode

The file tailwind.config.ts created is:

import typography from '@tailwindcss/typography';
import type { Config } from 'tailwindcss';

export default {
  content: ['./src/**/*.{html,js,svelte,ts}'],

  theme: {
    extend: {}
  },

  plugins: [typography]
} satisfies Config;
Enter fullscreen mode Exit fullscreen mode

Now, you can use your new Tailwind CSS style.

To do that, update your src/routes/about/+page.svelte file, using some Tailwind CSS classes with:

<section class="text-center w-full h-screen bg-gradient-to-r from-yellow-200 via-red-300 to-pink-300">
  <h1 class="pt-10 text-7xl">About page</h1>
  <div class="font-serif pt-12 text-2xl">Ciao!</div>
</section>
Enter fullscreen mode Exit fullscreen mode

The +layout.svelte file, automatically created by the Svelte CLI, loads all the CSS styles. The +layout.css file imports the app.css file, which imports the Tailwind CSS files.

If you have your bun dev up and running, you can see the result on http://localhost:5173/about.

Build statics pages (Static Site Generator)

You need to pre-render HTML pages to serve your pages without using server-side language (bun, node, or something else).
This way, you can use any platform to deliver static assets (surge.sh, Vercel, Netlify, GitHub Pages, Amazon S3 + Amazon CloudFront, etc.).

To do that, SvelteKit needs an "adapter" to use during the building process.

bun add -d @sveltejs/adapter-static
Enter fullscreen mode Exit fullscreen mode

In svelte.config.js, you must replace sveltejs/adapter-auto with the sveltejs/adapter-static.

So, your svelte.config.js file will be something like this one:

import adapter from '@sveltejs/adapter-static';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

/** @type {import('@sveltejs/kit').Config} */
const config = {
    // Consult https://svelte.dev/docs/kit/integrations
    // for more information about preprocessors
    preprocess: vitePreprocess(),

    kit: {
        // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
        // If your environment is not supported, or you settled on a specific environment, switch out the adapter.
        // See https://svelte.dev/docs/kit/adapters for more information about adapters.
        adapter: adapter()
    }
};

export default config;
Enter fullscreen mode Exit fullscreen mode

You must set some parameters in the +layout.ts (or +layout.js if you are using JavaScript instead of TypeScript) file. If the +layout.ts file doesn't exist in your project, you must create it as src/routes/+layout.ts. The file has to define:

// if you want to generate a static html file
// for your page.
// Documentation: https://kit.svelte.dev/docs/page-options#prerender
export const prerender = true;

//If you want to Generate a SPA
//You have to set ssr to false.
// This is not the case (so set it as true or comment on the line)
// Documentation: https://kit.svelte.dev/docs/page-options#ssr
export const ssr = true;

// How to manage the trailing slashes in the URLs
// By default, SvelteKit strips trailing slashes,
// meaning that a request for /about/ will result in a redirect to /about.
//The URL for the about page will be /about with 'never' (default)
//The URL for the about page will be /about/ with 'always'
//The URL for the about page will be /about/ or /about with 'ignore' (not reccomended)
// https://kit.svelte.dev/docs/page-options#trailingslash
export const trailingSlash = 'never';

Enter fullscreen mode Exit fullscreen mode

Now you can build your static files (in the build directory according to the configuration) with the command:

bun run build
Enter fullscreen mode Exit fullscreen mode

For testing your built files locally, you can use

bun run preview
Enter fullscreen mode Exit fullscreen mode

Essentially, it serves locally your built files (not the svelte files, but the built files in your build directory).

To publish your files on the public server (Netlify, Vercel, Surge.sh, GitHub pages etc.) you need to use the content of the build directory.

Fortunately, SvelteKit provides us with some specific adapters for some specific platforms. So you can use a proper adapter for your platform. Adapters for:

  • @sveltejs/adapter-cloudflare for Cloudflare Pages
  • @sveltejs/adapter-netlify for Netlify
  • @sveltejs/adapter-vercel for Vercel
  • svelte-adapter-azure-swa for Azure Static Web Apps
  • svelte-kit-sst for AWS via SST
  • @sveltejs/adapter-node for Google Cloud Run

The list of the adapters is here: https://kit.svelte.dev/docs/adapter-auto

If you are using some service for publishing your website that forces you to use a subdirectory to serve your static files (for example, GitHub pages), you can use paths in config.kit section (in the svelte.config.js file):

paths: {
    base: '/your-sub-directory',
},
Enter fullscreen mode Exit fullscreen mode

Wrap up ...

These steps help you install and set up an environment with SvelteKit and Tailwind CSS.
I know the pages we created are very simple and basic, but with this tutorial, I wanted to focus on the process and the configuration to setup SvelteKit for creating static websites.
Feel free to provide any feedback...

Top comments (4)

Collapse
 
juneikerc profile image
Juneiker

I didn't know that svelte had support for generating static sites.

Collapse
 
robertobutti profile image
Roberto B.

Hi @juneikerc , it is possible thanks to "adapters".
If you are curious about this, you can watch also this video from Svelte Society:
https://www.youtube.com/watch?v=SUrFDhhsJNo&ab_channel=SvelteSociety

Collapse
 
atlante profile image
carlos X

good experience with static sites.

Collapse
 
leactz profile image
Lea

This was great - simple and to the point, just what I was looking for. Thanks!