banner
Home / News / Intro to SvelteKit 1.0: The full stack framework for Svelte
News

Intro to SvelteKit 1.0: The full stack framework for Svelte

Jan 05, 2024Jan 05, 2024

By Matthew Tyson

Software Architect, InfoWorld |

As recently announced, SvelteKit has arrived at its much anticipated 1.0 milestone, following a long beta. SvelteKit 1.0 brings a fully realized application framework for building full-stack JavaScript applications with Svelte front ends. Let's take a look.

Svelte is a front-end reactive framework, comparable to React or Vue at a high level, but with its own angle on things. SvelteKit is the full-stack application framework for Svelte, along the lines of Next or Nuxt, but again with its own conventions.

The nature of a full-stack application framework is that it must be able to unite the front-end and back-end of your application under a single umbrella. A full-stack framework must answer these questions:

At the heart of every application framework is the routing engine, which associates the code that generates the pages to the URLs in the browser. Most JavaScript frameworks like SvelteKit have settled into the general layout that Next.js uses, wherein the files and directories are mapped to the URL path.

SvelteKit's root directory is /src/routes (by default). So /src/routes corresponds to the root URL, for example localhost:5173/ in the browser. Subdirectories map to the URL path, so /src/routes/foo/bar becomes localhost:5173/foo/bar.

Several file conventions within the directories define the pages and endpoints. These file types begin with a plus sign (+), indicating that they have a special significance for the framework. (All other files will be ignored, so you can put helper files in the same directories.)

Each page is a Svelte component, defined in a +page.svelte file. A file at /src/routes/foo/bar/+page.svelte becomes the web page at localhost:5173/foo/bar, defined by the Svelte component created in that file. (By serving the default page at the route, this file acts in a similar role to index.jsx in other frameworks.) In other words, +page.svelte is just a standard Svelte component following normal Svelte syntax.

Although +page.svelte is just a front-end Svelte component, it can rely on other special files to do its work. SvelteKit also has some handy optimizations up its sleeve. By default, SvelteKit will server-side render +page.svelte. It uses the sibling file +page.js (with the .js extension) to control this process. The two components, +page.svelte and +page.js work together to define the page's full-stack behavior.

The +page.js component allows us to define a load function that can perform up-front work that the page component will need, as well as control how the framework treats the page with regard to rendering behavior. This component supports three const exports:

You can learn more about page rendering with these options from the SvelteKit documentation. Here, we will focus on the load function exported by +page.js. By default, it is run alongside +page.svelte on both the server and the client. The load function communicates with the Svelte component with a data variable. Whatever the +page.js export function returns will be set on the export let data variable of +page.svelte.

Because the +page.js load function runs on both client and server, it must contain functionality that will work in both the browser and back-end environments. When you need a function that runs on the server alone, you can use +page.server.js. The load function there executes on the back end alone. When server-side rendering (SSR) is in control, the data can be integrated into the render; when client-side rendering is active, the code will execute on the server and be serialized and transmitted. (See the SvelteKit documentation to learn more about choosing between a "universal" load function and a server-side-only load function.)

In addition to load, +page.server.js can define an actions function to handle form data. (This is similar to how Remix does forms and allows forms to function when JavaScript is unavailable.)

If you need a URL parameter (aka a "slug"), you can enclose it in brackets. For example, /src/routes/foo/bar/[id] will expose an id variable to the +page.js (or +page.server.js) as part of the parameter argument to the load function: export async function load({ fetch }) { param.id }.

You can also define server-only routes to handle API endpoints with +server.js. This function handles the familiar REST methods like GET, PUT, and so on. Each of these is handled by exporting a function that corresponds to the method; for example, export function GET({ url }) will handle the GET method that arrives at that file. So a /src/routes/foo/bar/+server.js GET function will respond to a localhost:5173/foo/bar GET request.

While we won't cover them here, there are a few more special pages to know about:

Note that layouts support hierarchical layouts and you can fine-tune their behavior.

Links are plain <a> links, rather than a special component. SvelteKit examines the links in the application and if they refer to a page within the application itself (rather than an external link), SvelteKit's navigation takes over. SvelteKit honors web standard directives like prefetch on links.

The areas of connection between application layers, where the front and back ends communicate, support strong typing via TypeScript or JSDoc @typedef annotations in JavaScript. As an example, if you were using JavaScript, the load() function would be decorated with an annotation like /** @type {import('./$types').PageLoad} */. SvelteKit would use this instruction to ensure type safety. It would also ensure the type of object that arrived in the data object of the +page.svelte file was a PageData class as defined by /** @type {import('./$types').PageData} */.

Similarly, for +page.server.js, load functions are decorated with /** @type {import('./$types').PageServerLoad} */. All these types are auto-generated by SvelteKit for you to use in your applications.

One of the biggest ways that a framework can ease development is to simplify the application's deployment to production. SvelteKit answers this need with adaptors, which transform the dev-mode app into a deployable package for a variety of target environments. You can deploy to a static site, a Node or Express stack, or on the edge with a service like Vercel.

By default, SvelteKit uses an "auto" adapter that requires no intervention when deploying to Cloudflare, Netlify, or Vercel. Once you have configured a platform to consume the application code, the default adaptor will build and deploy your project for you.

You may have pages that are pure static content, even amidst an otherwise dynamic single-page application (Svelte founder Rich Harris calls this type of application "transitional"). For example, an About page might only serve static content that is the same for everyone. Pre-rendering such a page would yield the utmost speed with no hydration involved. This is where you could set the export prerender option in +page.js to false.

If you in fact have an entire site that can be prerendered, it is possible to output the whole site as a static application by using a static build output. Learn more about prerendering in the SvelteKit documentation.

If you want to get started with SvelteKit 1.0, you can begin by creating an application on the command-line interface, using the following command: npm create svelte@latest sveltekit-demo. This will launch the short interactive prompt shown in Listing 1.

Notice in the first question that you can choose between a skeleton project and a library skeleton project. SvelteKit supports libraries in addition to typical web applications. Whereas a web application is a set of libraries whose end product is a usable UI, a library is a set of libraries that are consumed by other projects and whose UI is usually the documentation for the library. See the SvelteKit documentation for more about the difference between packaging for a lib or UI distribution.

Next, you are asked whether you want to use JSDoc or TypeScript to define the application. You’ve already seen the JSDoc typedef in action. Here is where you can tell the generator what syntax you want to use.

If you select the "guessing game" option, the app creator will output an application that uses many of the features we’ve discussed here. These will be placed in a directory named whatever you've specified— for instance, sveltekit-demo.

You’ll notice that the application is built with the Vite bundler, and most of the commands for the application are Vite commands. As an example, after installing the dependencies with npm install, you can run the dev server with npm run dev. (If you are not on localhost, use the --host switch to expose the application to the network.) You can then open the demo application and click the "Sverdle" link to see the game in action, as shown in the following screenshot.

Figure 1. The demo application, Sverdle.

Although there is a lot more to SvelteKit and many options to explore, you’ve seen the basics. SvelteKit is a full-featured answer to the demand for an application framework for using Svelte. As a framework, it is similar to others like Next. Not only does it do the job, it is a well thought out response to the ongoing conversation around building software smarter for the web. The ideas found in SvelteKit will surely influence the future direction of that conversation.

Next read this:

Matthew Tyson is a founder of Dark Horse Group, Inc. He believes in people-first technology. When not playing guitar, Matt explores the backcountry and the philosophical hinterlands. He has written for JavaWorld and InfoWorld since 2007.

Copyright © 2023 IDG Communications, Inc.

❯ SvelteKit demo app Yes, using JavaScript with JSDoc comments Next read this: