Overview
In this article, we will create a standalone endpoint in SvelteKit and fetch data from the endpoint and load the fetched data into a layout page so that we can access the same data from any descendant pages that are wrapped around by the layout page.
Standalone Endpoints
According to the official SvelteKit doc, Endpoints are:
Endpoints are modules written in .js or .ts files that export request handler functions corresponding to HTTP methods. Their job is to make it possible to read and write data that is only available on the server (for example in a database, or on the filesystem).
There are two types of endpoints in SvelteKit:
Type of Endpoint | Explanation |
---|---|
Page Endpoint | an endpoint that has the same filename as a page(except for the extension) |
Standalone Endpoint | an endpoint that is separate from pages |
Let's say there is a configuration json file in your OS home directory and you want to display that information in a main page of your SvelteKit web application. For example, I created the following file in the home directory on my Mac mini.
1{2 "name": "Youngjae Jay Lim",3 "description": "Human"4}
To read the configuration json file and return as data, you need to create config.js
file in the ./src/routes/
directory like this:
./src/routes/config.js1import os from 'os'2import fs from 'fs'3import path from 'path'45const config = JSON.parse(6 fs.readFileSync(path.join(os.homedir(), 'config.json'), 'utf-8')7)89export async function get() {10 if (config) {11 return {12 body: config,13 }14 }1516 return {17 status: 404,18 }19}
Please open up your web browser and access http://localhost:3000/config
. You should see a result as following:
This is a standalone endpoint because it is not tied to a page with the same filename(say, ./src/routes/config.svelte
). We will fetch data from this enpoint in a layout page in the next section.
Layout Data Loading
What is Layout Page
Now that we've created the endpoint, we can fetch data in a layout page. The layout is an element that should be visible on every page you navigate, which could have a navigation bar or a footer. Without layout components, you have to repeat the nav bar or footer for every page. Due to this nature of layout page, you can also fetch data from any endpoint that will be accessible to any nested pages and components.
How to fetch data in a page
To fetch data in a page, we will utilize a SvelteKit built-in function called load()
that runs before the component is created. This way, we can fetch and manipulate data before the page is rendered. The SvelteKit official documentation puts an emphasis on:
- The
load()
function runs both during server-side rendering and in the client. load
applies to onlypage
andlayout
components(not components thay import). In other words, you can't useload()
in a regular component(for instance, a component in./src/lib/
directory).
To create a default layout in SvelteKit, you create __layout.svelte
in ./src/routes/
directory.
./src/routes/__layout.svelte1<script context="module">2 export async function load({ fetch }) {3 const url = "/config";4 const res = await fetch(url);56 if (res.ok) {7 const config = await res.json();8 return {9 props: {},10 stuff: { config },11 };12 }1314 return {15 status: res.status,16 error: new Error(`Could not load ${url}`),17 };18 }19</script>2021<slot />
What this does
First, we have a script tag <script context="module">
that allows load()
to run before the page is rendered.
Secondly, as you see, load
receives an implementation of SvelteKit-provided fetch
wrapper. This fetch
made a request to our app's own endpoint /config
that we've created earlier without issuing an HTTP. As a result of fetch, we get a copy of the response that is sent embedded in the initial page load.
Please also pay attention to props
and stuff
variables in the return object. I intentionally put config variable to stuff
, not props
because props
will be an empty object for:
- layout components
- pages without endpoints
The stuff
is passed from the layout page to any nested pages, you can literally put any stuffs to stuff
that will be available to subsequesnt load
functions. We will see how we can access stuff
from the nested page in the next section.
Page
Now that we have config
data available through stuff
in our layout page, we can use it in a main page of our app. In similar to what we did in the layout page to fetch data from an endpoint, we will use the same load()
to retrieve stuff
object that is already available to the nested main page via the layout page.
./src/routes/index.svelte1<script context="module">2 export async function load({ stuff }) {3 const { config } = stuff;4 return {5 props: { config },6 };7 }8</script>910<script>11 export let config;12</script>1314<main>15 <h1>Who am I?</h1>16 <p>Name: {config.name}</p>17 <p>Description: {config.description}</p>18</main>
Make sure to spin up dev server and access http://localhost:3000
in a browser:
That's all for this article. Now you can create a simple endpoint and fetch data from it and pass it onto other pages all happenning withing a single SvelteKit web application. If you have any questions, please feel free to leave a commnet below.
Comments