⚠️Draft Content
Storyblok
Search Storyblok's Documentation
  1. Integrate Svelte with Storyblok

Integrate Svelte with Storyblok

Use Storyblok to manage the content of your SvelteKit application.

This guide has been tested with the following package versions:

  • svelte@5.0.0
  • @sveltejs/kit@2.16.0
  • @storyblok/svelte@5.0.2
  • node@22.13.0

Setup

Create a new Svelte project in a few simple steps by following the Creating a project page from the SvelteKit official documentation.

If you don’t already have a Storyblok space, create one at app.storyblok.com and add some content to the home story.

Installation

In your terminal, cd into your SvelteKit application and install @storyblok/svelte:

npm install @storyblok/svelte

In the root of your project, create a .env file with the access token from your space.

.env
VITE_STORYBLOK_DELIVERY_API_TOKEN="EXAMPLE_ACCESS_TOKEN"

In your Storyblok Space, Go to Settings > Access Token and generate a public access token.

Learn how to get an access token for your Storyblok project.

In the root layout, initialize the Storyblok client.

src/routes/+layout.js
import { apiPlugin, storyblokInit, useStoryblokApi } from "@storyblok/svelte";
 
export async function load() {
  storyblokInit({
    accessToken: import.meta.env.VITE_STORYBLOK_DELIVERY_API_TOKEN,
    apiOptions: {
      region: 'eu', // Choose the correct region from your Space.
    },  
    use: [apiPlugin],
  });
  
  const storyblokAPI = await useStoryblokApi();
 
  return {
    storyblokAPI,
  };
}

This approach will give access to the storyblokAPI via the parent parameter to all descendant load functions.

Fetch a single story

Add a src/routes/+page.js file and get access the storyblokAPI client using the parent function.

src/routes/[slug]/+page.js
/** @type {import('./$types').PageLoad} */
export async function load({ params, parent }) {

  const { storyblokAPI } = await parent();

  const response = await storyblokAPI.get("cdn/stories/home")

  return {
    story: response.data.story,
  };
}

The +page.js file passes the story to the corresponding +page.svelte file’s data prop. Paste the following code into src/routes/+page.svelte.

src/routes/+page.svelte
<script>
  export let data
</script>

<pre>{JSON.stringify(data, null, 2)}</pre>

Now run npm run dev. Once the development server is running, open http://localhost:5173 in your browser. You should see the the JSON of your home story.

Next, we will render that JSON as blocks.

Create blocks

All content in Storyblok is made of blocks. The content of each story is a block, and each component in the content is a nested block.

If you have started from scratch with a new space in Storyblok, then your home story will have a body array that contains zero or more blocks of different types. Each new space in Storyblok includes four default blocks:

  • page
  • feature
  • hero
  • grid

(If you are using a space that you have configured yourself, you will probably have different blocks.)

Note that Svelte blocks (e.g. {#each}, {#for} and {#if}) are are not related to Storyblok blocks (e.g. feature, hero, and grid). Svelte blocks are templating utilities. Storyblok blocks are content.

@storyblok/svelte provides a component to handle your blocks, StoryblokComponent. Import that component, use a Svelte {#each} block to iterate over your array, and render each Storyblok block with the StoryblokComponent.

src/routes/+page.svelte
<script>
  import { StoryblokComponent } from "@storyblok/svelte"

  export let data;
</script>

{#each data.story.content.body as blok}
  <StoryblokComponent {blok} />
{/each}

This code has no effect… yet.

To render your blocks, you will need to create a Svelte component for each of them and then add each of those components to your config in src/routes/+layout.js.

In src/lib/, Create a Svelte component for one of your blocks, like this one:

src/lib/Teaser.svelte
<script> 
  export let blok;
</script>

<div>
  <h2>{blok.headline}</h2>
</div>

Then, import that component to your root layout. In storyblokInit(), add a components property to list your block components. Each component should have the block’s API ID as the key (teaser) and the Svelte component as the value (Teaser).

src/routes/+layout.js
import { apiPlugin, storyblokInit, useStoryblokApi } from "@storyblok/svelte";
import Teaser from "$lib/Teaser.svelte"
 
/** @type {import('./$types').LayoutLoad} */
export async function load() {
  storyblokInit({
    accessToken: "W1vLyxT5rQ15jBpANjnv0gtt",
    use: [apiPlugin],
    components: {
	    teaser: Teaser // List your block components
    }
  });
  
  let storyblokApi = await useStoryblokApi();
 
  return {
    storyblokApi: storyblokApi,
  };
}

Create components for all of your blocks and them to your configuration.

Create a page block

Note that even pages are blocks in Storyblok, so you should add a Page component to your components object. Your Page component might look like this:

src/lib/Page.svelte
<script>
  import { StoryblokComponent } from "@storyblok/svelte"

  export let blok;
</script>

{#each blok.body as blok}
  <StoryblokComponent {blok} />
{/each}

Wrap-up

Once you have added all of your components, your src/routes/+layout.js file should look something like this:

src/routes/layout.js
import { apiPlugin, storyblokInit, useStoryblokApi } from "@storyblok/svelte";
import Teaser from "$lib/Teaser.svelte"
import Feature from "$lib/Feature.svelte"
import Grid from "$lib/Grid.svelte"
import Page from "$lib/Page.svelte"

export async function load() {
  storyblokInit({
    accessToken: import.meta.env.VITE_STORYBLOK_DELIVERY_API_TOKEN,
    apiOptions: {
      region: 'eu', // Choose the correct region from your Space.
    },
    use: [apiPlugin],
    components: {
      teaser: Teaser,
      feature: Feature,
      grid: Grid,
      page: Page,
    }
  });

  const storyblokAPI = await useStoryblokApi();

  return {
    storyblokAPI,
  };
}

Now you can create content in your Storyblok space and view in via http on localhost.

Storyblok really shines when you connect your Svelte application to the Storyblok editor — unlocking live previews and WYSWIG editing. To unlock that superpower, read check out Visual Previews.