---
title: Integrate Svelte with Storyblok
description: This guide walks you through integrating Storyblok as a headless CMS, fetching content, and building components to render it effectively in your Svelte project.
url: https://storyblok.com/docs/guides/svelte
---

# Integrate Svelte with Storyblok

Use Storyblok to manage the content of your Svelte application.

> [!NOTE]
> 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](https://svelte.dev/docs/kit/creating-a-project) from the SvelteKit official documentation.

If you already have a Storyblok account, visit [app.storyblok.com](http://app.storyblok.com/#/signup) or [log in with GitHub](https://github.com/login?client_id=Iv23liC8pLXD6VcT2EbS&return_to=%2Flogin%2Foauth%2Fauthorize%3Fclient_id%3DIv23liC8pLXD6VcT2EbS%26redirect_uri%3Dhttps%253A%252F%252Fapp.storyblok.com%252F#/login) to continue.

Create a [new blank space](https://app.storyblok.com/#/me/spaces/new?tab=select-plan) to follow the tutorial from scratch, or start from the [core blueprint](https://app.storyblok.com/#/spaces/new/blueprint?blueprintReference=starter).

[Create one and start a free Storyblok space](https://app.storyblok.com/#/signup) No Storyblok account yet?

## Installation

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

```bash
npm install @storyblok/svelte
```

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

.env

```plaintext
VITE_STORYBLOK_DELIVERY_API_TOKEN=<YOUR-ACCESS-TOKEN>
```

> [!NOTE]
> Learn how to get an [access token](/docs/concepts/access-tokens) for your Storyblok project.

In the root layout, initialize the Storyblok client.

src/routes/+layout.js

```javascript
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

Create a `src/routes/[...slug]/+page.js` file and get access the `storyblokAPI` client using the `parent` function.

src/routes/\[...slug\]/+page.js

```javascript
/** @type {import('./$types').PageLoad} */
export async function load({ params, parent }) {

  const { storyblokAPI } = await parent();

  const response = await storyblokAPI.get("cdn/stories/home", {
    version: 'draft',
  });

  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/[...slug]/+page.svelte`.

src/routes/\[...slug\]/+page.svelte

```html
<script>
  import { StoryblokComponent } from '@storyblok/svelte';
  export let data
</script>

<StoryblokComponent blok={data.story.content} />
```

`@storyblok/svelte` provides a component to handle your blocks, `StoryblokComponent`.

## Create and register blocks

Create `Page.svelte` component to render all stories of the `page` content type, such as the home story.

src/lib/Page.svelte

```html
<script>
 import { StoryblokComponent } from "@storyblok/svelte"

 export let blok;
</script>

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

> [!WARNING]
> Svelte blocks (such as `{#each}`, `{#for}`, and `{#if}`) aren't related to Storyblok blocks (for example, `feature`, `hero`, and `grid`).  
> Svelte blocks are templating utilities, while Storyblok blocks are content pieces.

Using `StoryblokComponent` iterate through the `body` field and render the blocks in it.

Stories might contain a `body` or similar field which consists of an array with several blocks of custom types (for example, Feature, Teaser, Grid) in it.

Create the code for these components as follows.

src/lib/Feature.svelte

```html
<script>
  export let blok;
</script>


<div class="feature">
  <span>{blok.name}</span>
</div>
```

src/lib/Teaser.svelte

```html
<script>
  export let blok;
</script>

<div class="teaser">
  <h2>{blok.headline}</h2>
</div>
```

src/lib/Grid.svelte

```html
<script>
  import { StoryblokComponent } from "@storyblok/svelte";

  export let blok;
</script>

<div class="grid">
{#each blok.columns as nestedBlok}
  <StoryblokComponent blok={nestedBlok} />
{/each}
</div>
```

Similar to `Page.svelte`, `Grid.svelte` iterates over the `columns` block field.

Add all these new components to the layout file.

src/routes/+layout.js

```javascript
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,
  };
}
```

Run the server and visit the site in your browser.

```bash
npm run dev
```

## Related resources

[Storyblok's Svelte Blueprint Repository](https://github.com/storyblok/blueprint-core-svelte)

[@storyblok/svelte Package Reference](https://www.storyblok.com/docs/libraries/js/svelte-sdk)

[Concept: Blocks](/docs/concepts/blocks)

[Content Delivery API: Retrieve a Single Story](/docs/api/content-delivery/v2/stories/retrieve-a-single-story)

[Svelte Docs](https://svelte.dev/docs)

  

## Pagination

-   [Next: Visual Preview in Svelte](/docs/guides/svelte/visual-preview)
