In my previous article titled “Svelte: Why Is It an Innovation to Javascript Frameworks?” I talked about how Svelte, the library/compiler made by Rich Harris, represents a great innovation in the universe of front-end production strategies.
Briefly, with Svelte you get:
- A real compiler that acts as an “extension” of the natural development flow by acting as a template engine and as an enhancement of the HTML, CSS, and Javascript standards
- An implementation system with modern reactivity features based on native Javascript/vanilla Javascript, and not on the Virtual DOM
- The coolness of triggering the responsiveness of a variable by simply writing something like… counter++
- Obtaining performance, bundle-size and amount of code currently unmatched among front-end libraries
However, like React and Vue, Svelte is a front-end library, not a full-stack framework.
A front-end library, even if powerful and performing, basically takes care of the front-end tasks of the application: production of the page’s UX and interactivity.
A full-stack framework, on the other hand, is used for the total management of the application, both on the client and server side, performing important tasks such as:
- The retrieval and insertion of data in the database
- Routing, i.e. the connection between “route” (URL) and relative structural logic, complete management of variable paths, the different HTTP verbs that can be used, and the query string data.
- The implementation of “middleware” levels which allow the HTTP request to be analyzed before it reaches the management logic
- More generally, all the main bilateral data transactions between client and server
- The selection of the type of rendering to adopt:
– CSR (Client-Side Rendering) which allows you to render the front-end content of the application by mounting it directly on the client, in the DOM, through the process called “hydration”
– SSR (Server-Side Rendering), which allows to render the application content on the server, and sending it to the client upon receipt of the respective HTTP request, as in a traditional server-side application
You can also use a single render caching system, called “prerendering“, which allows you to compute the contents of a page at build-time rather than request-time. This feature saves the product returned by the server for an HTTP data request avoiding recomputation for each new visit to the same route.
More SvelteKit Features
If for React we have the full-stack framework Next and for Vue, we have the full-stack framework Nuxt, for Svelte we have the full-stack framework stack SvelteKit, which has recently finally reached the stable major version 1.0.
This means that you can build stable full-stack applications not only using the engines of React and Vue, but also of Svelte.
Since SvelteKit is entirely based on the Svelte library/compiler, effectively representing an extension of it, it has practically all the advantages offered by it that I presented in the dedicated article.
But that’s not all: the framework has features that make it a top competitor of all other modern Javascript development tools.
The speed with which SvelteKit allows you to work is highly noticeable and rewarding.
Let’s take a look at them, summarized in three main points: I’ll show you how you can create a blog in SvelteKit in just a few minutes, analyzing and exploiting its primary features?
Speed of Development #1: Routing and Templates
Since SvelteKit is based on Svelte, even performing typical full-stack/server-side tasks gives the same feeling of “naturalness” and extreme compactness that derives from the library.
Each page reached by an HTTP request is a Svelte component, and therefore has its own characteristics:
• the <script> for the computational logic
• the responsive HTML template
• the scoped <style>
So, in order to create and manage a route, you simply need to build a Svelte component.
But it didn’t end there. How can you route the specific HTTP request to a certain component? You don’t need to build a file to handle routing, nor do you need controllers, models, or views. SvelteKit’s routing system is entirely file-based. This means that to manage the HTTP request that is redirected to /app, for example, you just need to create the src/routes/app/+page.svelte directory, which will be the Svelte component we mentioned above. Each route in your system has its own +page.svelte component.
This means that you always have a complete overview of your routing system by simply looking at the contents of the routes directory.
If you want to handle dynamic routes, for example containing path variables, such as /posts/a-sveltekit-overview or /posts/web-development-is-cool, just generate the src/routes/[slug] directory with the relative +page.svelte.
To manage the incoming data, you just need to create a Javascript function called load in the same directory, through the +page.js file if you want this function to be implemented on the client and on the server, or through the +page.server.js file if you want it to be implemented only on the server (for example if it contains sensitive information, environment variables or database connections).
The load function returns an object that is retrieved by the Svelte component connected simply via
<strong>export let data;</strong>
Code language: HTML, XML (xml)
A blog in 5 minutes with SvelteKit
Let’s get started: basically, you can generate a blog (with static data for the sake of simplicity) like this.
Home page
src/routes/+page.svelte.js
<h1>A blog done in 5-minutes!<h1>
Code language: HTML, XML (xml)
Post list management:
src/routes/posts/+page.js
import { error } from '@sveltejs/kit';
import { posts } from '$lib/data/posts';
export function load({params}) {
return {posts}
}
src/routes/posts/+page.svelte
<script>
export let data;
</script>
<h1>Posts</h1>
{#each data.posts as post (post.slug)}
<h2>
<a href={`/posts/${post.slug}`}>{post.title}</a>
</h2>
{/each}
Code language: HTML, XML (xml)
Single post management:
src/routes/posts/[slug]/+page.js
import { error } from '@sveltejs/kit';
import { posts } from '$lib/data/posts';
export function load({ params }) {
const post = posts.find((post) => post.slug === params.slug)
if (!post) throw error(404)
return post
}
src/routes/posts/[slug]/+page.svelte
<script>
export let data;
</script>
<h1>Posts</h1>
{#each data.posts as post (post.slug)}
<h2>
<a href={`/posts/${post.slug}`}>{post.title}</a>
</h2>
{/each}
Code language: HTML, XML (xml)
Static post list
src/lib/data/posts.js
export const posts = [
{
slug: ' web-development-is-cool',
title: '…',
content:'…'
}, {…}
];
Code language: JavaScript (javascript)
That’s it! Your blog is now available at yourhost/posts and yourhost/posts/web-development-is-cool.
Speed of Development #2: Layout and Data Fetching
Of course, in your templates you have a lot of parts that are repeated in the application, such as headers, footers, and navigation bars. No fear. Each individual segment of a URL can be equipped with a component file +layout.svelte which is called in connection with the appropriate http request, which has all the functionality of the Svelte components and can inject the appropriate content via <slot />.
You can also inherit external layouts by extending or overriding them. To load properties in the +layout.svelte, as we did in the final component, you have +layout.js and +layout.server.js, with the same distinction as between +page.js and +page.server.js.
So you can for example have the global layout:
src/routes/+layout.js
<nav>
<a href="/">home</a>
<a href="/posts">posts</a>
</nav>
<slot />
Code language: HTML, XML (xml)
For data fetching, we don’t have to use any particular internal API. We remain in the perspective of a natural extension of the native functions of web development, given that the SvelteKit developers openly declare that they do not want to reinvent the wheel, but rather rely on Web Standards, allowing you to use your existing web development skills.
For this reason, SvelteKit internally uses the Fetch API and its standard implementation for asynchronous requests and to handle asynchronous data generated through different HTTP methods (GET, POST, etc)
This same mentality also extends to the FormData API which is used to manage received form data, the StreamAPI to chunk the response and the URL API to manage components of a URL.
No additional non-standard APIs.
Compact development #3: rendering and deployment
The third important component of speed that can be seen using SvelteKit concerns the rendering of the pages and the deployment on a dedicated platform.
SvelteKit renders all components by default first on the server and then on the client using the HTML generated in the previous step. The component will then be rendered on the client and made interactive through the hydration process.
With SvelteKit you can alter this behavior on a page-by-page basis by setting the desired rendering mode. For example, you can pre-render some routes to maximize speed and performance, server-side render other routes to boost their SEO and accessibility, and finally turn your internal admin pages into a SPA through client-side rendering.
To pre-render a route, simply write:
+page.js
export const prerender = true;
Code language: JavaScript (javascript)
Since by default SvelteKit renders the page on the server and then sends the generated structure to the client for hydration, we can disable one or both of these rendering features by setting them to false:
+page.js
export const ssr = false;
Code language: JavaScript (javascript)
Disable rendering on the server by rendering an empty “shell”. useful in case the page only uses client-side APIs (document.getElementById etc), while:
+page.js
export const csr = false;
Code language: JavaScript (javascript)
disable hydration on the client, e.g. for pages that do not require the use of Javascript.
Finally, the deployment. Before deploying your application, you need to “adapt” it to your platform and environment. This task is done in the svelte.config.js file, by importing the specific adapter for your case:
- Adapter-auto: Attempt to detect the correct adapter for your production environment. It is the correct choice if you want to deploy on Cloudflare Pages (adapter-cloudflare), Netlify (adapter-netlify) and Vercel (adapter-vercel)
- Adapter-node: the correct adapter for Node server environment. In this case, the site build command will generate a self-contained Node app inside the build directory
- Adapter-static: to generate static and pre-rendered content for all application pages
If none of these adapters meet the needs of your environment, you can definitely write a custom one.
As you can see, thanks to SvelteKit, it is possible to bring all the speed of Svelte into a full-stack environment that also includes the server.