
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.
Notice the 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 /list
, /details
, /admin/user-settings
and 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 getTodos
and 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 await
them.
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 routes
.
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 list
page’s +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 +page.server.js
in /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.
Notice the 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 editTodo
“action.”
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 /details
.
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.
Post a Comment
You must be logged in to post a comment.