On this page
Build a SvelteKit App
SvelteKit is a web framework built on top of Svelte, a modern front-end compiler that builds highly optimized vanilla JavaScript. SvelteKit provides features like file-based routing, server-side rendering, and full-stack capabilities.
In this tutorial we'll build a simple SvelteKit app with Deno. The app will display a list of dinosaurs. When you click on one, it'll take you to a dinosaur page with more details. You can see the finished app on GitHub.
You can see a live version of the app on Deno Deploy.
You can deploy your own version of this svelte app to Deno Deploy immediately. Just click the button!
Create a SvelteKit app with Deno Jump to heading
We'll use SvelteKit to create a new SvelteKit app. In your terminal, run the following command to create a new SvelteKit app:
deno run -A npm:create-svelte
When prompted, give your app a name and select the "Skeleton project" template. Choose "Yes, using TypeScript syntax" when asked about TypeScript.
Once created, cd
into your new project and run the following command to
install dependencies:
deno install
Then, run the following command to serve your new SvelteKit app:
deno task dev
Deno will run the dev
task from the package.json
file which will start the
Vite development server. Click the output link to localhost to see your app in
the browser.
Configure the formatter Jump to heading
deno fmt
supports Svelte files with the
--unstable-component
flag. To use it, run this command:
deno fmt --unstable-component
To configure deno fmt
to always format your Svelte files, add this at the top
level of your deno.json
file:
"unstable": ["fmt-component"]
Add a backend API Jump to heading
We'll build API routes using SvelteKit's built-in API capabilities. SvelteKit
allows you to create API endpoints by creating +server.js
or +server.ts
files in your routes directory.
In the src/routes
directory, create an api
folder. In that folder, create a
data.json
, which will contain the hard coded dinosaur data.
Copy and paste
this json file
into the src/routes/api/data.json
file. (If you were building a real app, you
would probably fetch this data from a database or an external API.)
We're going to build out some API routes that return dinosaur information. SvelteKit provides a simple way to create API endpoints using server files.
Create src/routes/api/dinosaurs/+server.ts
to handle the /api/dinosaurs
endpoint. This will return all dinosaurs:
import { json } from "@sveltejs/kit";
import data from "../data.json" with { type: "json" };
export function GET() {
return json(data);
}
Then create src/routes/api/dinosaurs/[id]/+server.ts
to handle individual
dinosaur requests at /api/dinosaurs/:id
:
import { json } from "@sveltejs/kit";
import type { RequestHandler } from "./$types";
import data from "../../data.json" with { type: "json" };
export const GET: RequestHandler = ({ params }) => {
const dinosaur = data.find((item) => {
return item.name.toLowerCase() === params.id.toLowerCase();
});
if (dinosaur) {
return json(dinosaur);
}
return json({ error: "Not found" }, { status: 404 });
};
SvelteKit automatically handles routing based on the file structure. The
+server.ts
files define API endpoints, and the [id]
folder creates a dynamic
route parameter.
Build the frontend Jump to heading
File-based routing and data loading Jump to heading
SvelteKit uses file-based routing, where the structure of your src/routes
directory determines your app's routes. Unlike Vue Router, you don't need to
configure routes manually - SvelteKit automatically creates routes based on your
file structure.
In SvelteKit, +page.svelte
files define page components, and +page.ts
files
define data loading functions that run before the page loads. This provides
built-in server-side rendering and data fetching capabilities.
The pages and components Jump to heading
SvelteKit organizes the frontend into pages and components. Pages are defined by
+page.svelte
files in the routes directory, while components can be reusable
pieces of code stored anywhere in your project.
Each Svelte component file contains three optional sections: <script>
,
<template>
(the HTML), and <style>
. The <script>
tag contains the
JavaScript/TypeScript logic, the template contains the HTML markup, and the
<style>
tag contains scoped CSS.
We'll create pages for the home page and individual dinosaur details, along with data loading functions to fetch dinosaur information from our API.
The home page Jump to heading
The home page will display a list of dinosaurs fetched from our API. First,
create src/routes/+page.ts
to load the dinosaur data:
import type { PageLoad } from "./$types";
export const load: PageLoad = async ({ fetch }) => {
const res = await fetch(`/api/dinosaurs`);
const dinosaurs = await res.json();
return { dinosaurs };
};
This load function runs on both the server and client, and the data is passed to
the page component. The fetch
function is provided by SvelteKit and works in
both server and client environments.
Next, update src/routes/+page.svelte
to display the dinosaur list:
<script lang="ts">
import type { PageProps } from "./$types";
let { data }: PageProps = $props();
let dinosaurs = data.dinosaurs;
</script>
<main>
<h1>🦕 Dinosaur app</h1>
<p>Click on a dinosaur below to learn more.</p>
{#each dinosaurs as dinosaur (dinosaur.name)}
<a href="/{dinosaur.name.toLowerCase()}" class="dinosaur">
{dinosaur.name}
</a>
{/each}
</main>
This code uses Svelte's each block
to iterate over the dinosaurs
array and render each dinosaur as a link. The
{#each}
block is Svelte's way of rendering lists, and the (dinosaur.name)
provides a unique key for each item.
The Dinosaur detail page Jump to heading
The dinosaur detail page will display information about a specific dinosaur.
SvelteKit uses folder names in square brackets to create dynamic routes. The
[dinosaur]
folder creates a route that captures the dinosaur name from the
URL.
First, create src/routes/[dinosaur]/+page.ts
to load individual dinosaur data:
import type { PageLoad } from "./$types";
import { error } from "@sveltejs/kit";
export const load: PageLoad = async ({ fetch, params }) => {
const res = await fetch(`/api/dinosaurs/${params.dinosaur}`);
const dinosaur = await res.json() as { name: string; description: string };
if (res.status === 404) {
return error(404, "No dinosaur found");
}
return { dinosaur };
};
This load function uses the params
object to access the dinosaur
parameter
from the URL. If the API returns a 404, we use SvelteKit's error
function to
throw a 404 error.
Next, create src/routes/[dinosaur]/+page.svelte
to display the dinosaur
details:
<script lang="ts">
import type { PageProps } from "./$types";
let { data }: PageProps = $props();
let dinosaur = data.dinosaur;
</script>
<div>
<h1>{dinosaur.name}</h1>
<p>{dinosaur.description}</p>
<a href="/">ðŸ Back to all dinosaurs</a>
</div>
This page displays the dinosaur's name and description, along with a link back to the home page. The data comes from the load function and is automatically available in the component.
Run the app Jump to heading
Now that we've set up the frontend and backend API routes, we can run the app. In your terminal, run the following command:
deno task dev
This will start the SvelteKit development server with Vite. SvelteKit automatically handles both the frontend pages and the API routes we created, so you don't need to run separate servers.
Visit http://localhost:5173
in your browser to see the app. Click on a
dinosaur to see more details!
You can see a live version of the app on Deno Deploy.
Build and deploy Jump to heading
SvelteKit comes with built-in build capabilities. We configured it to use the Deno adapter, which optimizes the build for deployment on Deno-compatible platforms. Run the following command to build the app in production mode:
deno task build
This will:
- Build the SvelteKit app using Vite
- Generate optimized production assets
- Create server-side code compatible with Deno
The built app will be ready for deployment on platforms that support Deno, such as Deno Deploy.
You can deploy this app to your favorite cloud provider. We recommend using Deno Deploy for a simple and easy deployment experience. You can deploy your app directly from GitHub, simply create a GitHub repository and push your code there, then connect it to Deno Deploy.
Create a GitHub repository Jump to heading
Create a new GitHub repository, then initialize and push your app to GitHub:
git init -b main
git remote add origin https://github.com/<your_github_username>/<your_repo_name>.git
git add .
git commit -am 'my svelte app'
git push -u origin main
Deploy to Deno Deploy Jump to heading
Once your app is on GitHub, you can deploy it on the Deno DeployEA dashboard. Deploy my app
For a walkthrough of deploying your app, check out the Deno Deploy tutorial.
🦕 Now that you can run a SvelteKit app in Deno with the Deno adapter you're ready to build real world applications!