Intro to SvelteKit 1.0: The full stack framework for Svelte

SvelteKit 1.0 is here, and it is packed with features for full stack developers. Here's a quick tour of Svelte’s shiny new JavaScript framework.

interconnecting gears / process / automation / machinery / mechanism / efficiency

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.

The general layout of SvelteKit 1.0

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:

  • How are URLs mapped to front-end pages and back-end endpoints?
  • How are back-end routes accessed by the front end?
  • How are the front-end pages and back-end endpoints defined?

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.

Universal loading function with +page.js

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:

  • export const prerender prerenders the page.
  • export const ssr server-side renders the page.
  • export const csr client-side renders the page.

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.

Server-side load and form actions with +page.server.js

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.)

Server API with +server.js

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:

  • +error.svelte defines an error page. (Learn more about errors here.)
  • +layout.svelte defines a front-end layout component (analogous to +page.svelte).
  • +layout.js defines a load function layout component (analogous to +page.js).
  • +layout.server.js defines a server-side layout (analogous to +page.js).

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

Linking

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.

Strong typing with TypeScript or JSDoc

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. 

Deployment with adaptors

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.

Pre-rendering static content

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.

Create an application

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.

Listing 1. Create a new application with SvelteKit


? Which Svelte app template? › - Use arrow-keys. Return to submit.
❯   SvelteKit demo app
    A demo app showcasing some of the features of SvelteKit - play a word guessing game that works without JavaScript!
    Skeleton project
    Library skeleton project

? Add type checking with TypeScript? › - Use arrow-keys. Return to submit.
❯   Yes, using JavaScript with JSDoc comments
    Yes, using TypeScript syntax
    No

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.

Sverdle: A SvelteKit demo application. IDG

Figure 1. The demo application, Sverdle.

Conclusion

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.

Copyright © 2023 IDG Communications, Inc.