Getting Started With SvelteKit
In some ways this is a challenging post to write. SvelteKit is an application framework. It exists to help you build… well, applications. That makes it hard to demo. It’s not feasible to build an entire application in a blog post. So instead, we’ll use our imaginations a bit. We’ll build the skeleton of an application, have some empty UI placeholders, and hard-coded static data. The goal isn’t to build an actual application, but instead to show you how SvelteKit’s moving pieces work so you can build an application of your own.
To that end, we’ll build the tried and true To-Do application as an example. But don’t worry, this will be much, much more about seeing how SvelteKit works than creating yet another To-Do app.
Spinning up a new SvelteKit project is simple enough. Run
npm create svelte@latest your-app-name in the terminal and answer the question prompts. Be sure to pick “Skeleton Project” but otherwise make whatever selections you want for TypeScript, ESLint, etc.
Once the project is created, run
npm i and
npm run dev and a dev server should start running. Fire up
localhost:5173 in the browser and you’ll get the placeholder page for the skeleton app.
routes folder under
src. That holds code for all of our routes. There’s already a
+page.svelte file in there with content for the root
/ route. No matter where in the file hierarchy you are, the actual page for that path always has the name
+page.svelte. With that in mind, let’s create pages for
admin/paid-status, and also add some text placeholders for each page.
Your file layout should look something like this:
You should be able to navigate around by changing URL paths in the browser address bar.
We’ll want navigation links in our app, but we certainly don’t want to copy the markup for them on each page we create. So, let’s create a
+layout.svelte file in the root of our
routes folder, which SvelteKit will treat as a global template for all pages. Let’s and add some content to it:
And now we have some navigation! We won’t win any design competitions, but we’re not trying to.
What if we wanted all our admin pages to inherit the normal layout we just built but also share some things common to all admin pages (but only admin pages)? No problem, we add another
+layout.svelte file in our root
admin directory, which will be inherited by everything underneath it. Let’s do that and add this content:
We add a red banner indicating this is an admin page and then, like before, a
<slot /> denoting where we want our page content to go.
Our root layout from before renders. Inside of the root layout is a
<slot /> tag. The nested layout’s content goes into the root layout’s
<slot />. And finally, the nested layout defines its own
<slot />, into which the page content renders.
If you navigate to the admin pages, you should see the new red banner:
OK, let’s render some actual data — or at least, see how we can render some actual data. There’s a hundred ways to create and connect to a database. This post is about SvelteKit though, not managing DynamoDB, so we’ll “load” some static data instead. But, we’ll use all the same machinery to read and update it that you’d use for real data. For a real web app, swap out the functions returning static data with functions connecting and querying to whatever database you happen to use.
A function to return a flat array of our to-do items, a lookup of our tags, and a function to fetch a single to-do (we’ll use that last one in our Details page).
How do we get that data into our Svelte pages? There’s a number of ways, but for now, let’s create a
+page.server.js file in our
list folder, and put this content in it:
We’ve defined a
load() function that pulls in the data needed for the page. Notice that we are not
await-ing calls to our
getTags async functions. Doing so would create a data loading waterfall as we wait for our to-do items to come in before loading our tags. Instead, we return the raw promises from
load, and SvelteKit does the necessary work to
Our List page component now looks like this.
And this should render our to-do items!
Before we move on to the Details page and mutate data, let’s take a peek at a really neat SvelteKit feature: layout groups. We’ve already seen nested layouts for all admin pages, but what if we wanted to share a layout between arbitrary pages at the same level of our file system? In particular, what if we wanted to share a layout between only our List page and our Details page? We already have a global layout at that level. Instead, we can create a new directory, but with a name that’s in parenthesis, like this:
We now have a layout group that covers our List and Details pages. I named it
(todo-management) but you can name it anything you like. To be clear, this name will not affect the URLs of the pages inside of the layout group. The URLs will remain the same; layout groups allow you to add shared layouts to pages without them all comprising the entirety of a directory in
We could add a
+layout.svelte file and some silly
<div> banner saying, “Hey we’re managing to-dos”. But let’s do something more interesting. Layouts can define
load() functions in order to provide data for all routes underneath them. Let’s use this functionality to load our tags — since we’ll be using our tags in our
details page — in addition to the
list page we already have.
In reality, forcing a layout group just to provide a single piece of data is almost certainly not worth it; it’s better to duplicate that data in the
load() function for each page. But for this post, it’ll provide the excuse we need to see a new SvelteKit feature!
First, let’s go into our
+page.server.js file and remove the tags from it.
Our List page should now produce an error since there is no
tags object. Let’s fix this by adding a
+layout.server.js file in our layout group, then define a
load() function that loads our tags.
And, just like that, our List page is rendering again!
Let’s put a fine point on what’s happening here:
We’ll use our Details page to edit a to-do item. First, let’s add a column to the table in our List page that links to the Details page with the to-do item’s ID in the query string.
Now let’s build out our Details page. First, we’ll add a loader to grab the to-do item we’re editing. Create a
/details, with this content:
Our loader comes with a
url property from which we can pull query string values. This makes it easy to look up the to-do item we’re editing. Let’s render that to-do, along with functionality to edit it.
SvelteKit has wonderful built-in mutation capabilities, so long as you use forms. Remember forms? Here’s our Details page. I’ve elided the styles for brevity.
We’re grabbing the tags as before from our layout group’s loader and the to-do item from our page’s loader. We’re grabbing the actual
tag objects from the to-do’s list of tag IDs and then rendering everything. We create a form with a hidden input for the ID and a real input for the title. We display the tags and then provide a button to submit the form.
If you noticed the
use:enhance, that simply tells SvelteKit to use progressive enhancement and Ajax to submit our form. You’ll likely always use that.
action="?/editTodo" attribute on the form itself? This tells us where we want to submit our edited data. For our case, we want to submit to an
Let’s create it by adding the following to the
+page.server.js file we already have for Details (which currently has a
load() function, to grab our to-do):
Form actions give us a
request object, which provides access to our
formData, which has a
get method for our various form fields. We added that hidden input for the ID value so we could grab it here in order to look up the to-do item we’re editing. We simulate a delay, call a new
updateTodo() method, then redirect the user back to the
/list page. The
updateTodo() method merely updates our static data; in real life you’d run some sort of update in whatever datastore you’re using.
Let’s try it out. We’ll go to the List page first:
Now let’s click the Edit button for one of the to-do items to bring up the editing page in
We’re going to add a new title:
Now, click Save. That should get us back to our
/list page, with the new to-do title applied.
A few things you might be wondering…
This mutation update doesn’t seem too impressive. The loaders will re-run whenever you navigate. What if we hadn’t added a redirect in our form action, but stayed on the current page? SvelteKit would perform the update in the form action, like before, but would still re-run all of the loaders for the current page, including the loaders in the page layout(s).
Everything we’ve done throughout this article uses static data and modifies values in memory. If you need to revert everything and start over, stop and restart the
npm run dev Node process.
We’ve barely scratched the surface of SvelteKit, but hopefully you’ve seen enough to get excited about it. I can’t remember the last time I’ve found web development this much fun. With things like bundling, routing, SSR, and deployment all handled out of the box, I get to spend more time coding than configuring.
Here are a few more resources you can use as next steps learning SvelteKit:
If you need help creating a digital marketing strategy for your business, don’t hesitate to contact one of Digidude’s consultants.