@storyblok/svelte (Version 6.x)
@storyblok/svelte is Storyblok’s official development for Svelte applications.
Requirements
Section titled “Requirements”- Svelte version 5.0 or later
- Node.js LTS (version 22.x recommended)
- Modern web browser (e.g., Chrome, Firefox, Safari, Edge – latest versions)
Installation
Section titled “Installation”Add the package to a project by running this command in the terminal:
npm install @storyblok/svelte@latestConfiguration
Section titled “Configuration”Import and initialize the SDK using the access token of a Storyblok space.
import { apiPlugin, storyblokInit } from "@storyblok/svelte";import Page from "./Page.svelte";import Feature from "./Feature.svelte";
storyblokInit({ accessToken: "YOUR_ACCESS_TOKEN", region: "eu", use: [apiPlugin], components: { page: Page, feature: Feature, },});Components
Section titled “Components”Create a Svelte component for each block defined in Storyblok and registered in the configuration (include the page block). Each component will receive a blok prop, containing the content of the block.
<script> import { storyblokEditable } from "@storyblok/svelte";
export let blok;</script>
<div use:storyblokEditable={blok}> <h2>{blok.name}</h2></div>Fetching and rendering
Section titled “Fetching and rendering”In a +page.js file, use the client to fetch a story and render the content using StoryblokComponent.
/** @type {import('./$types').PageLoad} */export async function load({ parent }) { const { storyblokAPI } = await parent(); const response = await storyblokAPI.get("cdn/stories/home"); return { story: response.data.story, };}Then render the content in +page.svelte with StoryblokComponent:
<script> import { StoryblokComponent } from "@storyblok/svelte";
export let data;</script>
<StoryblokComponent blok={data.story.content} />storyblokInit
Section titled “storyblokInit”storyblokInit() creates an instance of the Storyblok API client and loads the Storyblok Bridge.
import { storyblokInit } from "@storyblok/svelte";
storyblokInit(OPTIONS);All options listed in the @storyblok/js reference are available. The following additional options are available:
| Key | Description | Type |
|---|---|---|
components | An object that maps Svelte components to Storyblok blocks. Each component receives a blok prop containing the content of the block. | object |
apiPlugin
Section titled “apiPlugin”apiPlugin configures the implementation of the Storyblok API. It is imported from @storyblok/js.
import { storyblokInit, apiPlugin } from "@storyblok/svelte";storyblokInit({ use: [apiPlugin],});See the @storyblok/js reference for further details.
useStoryblokApi
Section titled “useStoryblokApi”useStoryblokApi() returns the client instantiated in the application.
useStoryblok(URL, API_OPTIONS, BRIDGE_OPTIONS);For the API_OPTIONS, see the storyblok-js-client reference.
getStoryblokApi
Section titled “getStoryblokApi”getStoryblokApi() is an alias of useStoryblokApi().
useStoryblokBridge
Section titled “useStoryblokBridge”useStoryblokBridge() activates the Storyblok Bridge.
import { onMount } from "svelte";import { useStoryblokBridge } from "@storyblok/svelte";onMount(() => { useStoryblokBridge(STORY_ID, CALLBACK, BRIDGE_OPTIONS);});For the BRIDGE_OPTIONS, see the @storyblok/preview-bridge reference.
StoryblokComponent
Section titled “StoryblokComponent”StoryblokComponent is a Svelte component that dynamically renders blocks from Storyblok. It accepts a blok prop, which should be a block from the Storyblok API. Any other props passed to StoryblokComponent will be passed directly to the block component.
<StoryblokComponent blok={blok} />Use it to iterate over blocks fields as follows:
<script> import { StoryblokComponent } from "@storyblok/svelte"; export let blok;</script>{#each blok.body as blok}<StoryblokComponent {blok} />{/each}storyblokEditable
Section titled “storyblokEditable”storyblokEditable() accepts a block from the Storyblok API and returns an object containing the HTML attributes to make elements editable in the Storyblok Visual Editor. See the @storyblok/js reference for further details.
As a Svelte action, storyblokEditable() should be called with Svelte’s use: directive, provided with a blok property:
<script> import { storyblokEditable } from "@storyblok/svelte";
export let blok;</script>
<div use:storyblokEditable={blok}>{blok.title}</div>StoryblokRichText
Section titled “StoryblokRichText”Used to render a rich text field from a Storyblok story.
<script lang="ts"> import { StoryblokRichText } from "@storyblok/svelte";</script>
<StoryblokRichText document={blok.richtext_field} />The component accepts the following optional props:
components: Allows custom Svelte components to be provided for supported rich text nodes and marks.optimizeImage: Allows image optimization options to be configured for image nodes.
See the @storyblok/richtext reference for a complete list of supported nodes, marks, and customization options.
Custom components
Section titled “Custom components”Custom components can be registered using the components prop. The key must match a supported rich text node or mark name.
<script lang="ts">import type { SbSvelteRichTextComponentMap } from "@storyblok/svelte";import CustomHeading from "./CustomHeading.svelte";import CustomLink from "./CustomLink.svelte";import CustomTable from "./CustomTable.svelte";
const components: SbSvelteRichTextComponentMap = { heading: CustomHeading, link: CustomLink, table: CustomTable,};</script>The components can then be passed to StoryblokRichText:
<StoryblokRichText document={blok.richtext_field} components={components} />Example: Custom link component (mark)
Section titled “Example: Custom link component (mark)”Marks receive their rendered child content through Svelte’s {@render ...} snippet.
<script lang="ts">import type { SbSvelteRichTextProps } from "@storyblok/svelte";
const props: SbSvelteRichTextProps<'link'> = $props();</script>
<a href={props.attrs?.href ?? ""} target={props.attrs?.target ?? "_self"}> {@render props.children?.()}</a>Example: Custom heading component (node)
Section titled “Example: Custom heading component (node)”Nodes can use Svelte’s {@render ...} snippet to render child content.
<script lang="ts">import type { SbSvelteRichTextProps } from "@storyblok/svelte";
const props: SbSvelteRichTextProps<'heading'> = $props();const tag = $derived(`h${props.attrs?.level ?? 1}`);</script>
<svelte:element this={tag} data-type="custom-heading" data-level={props.attrs?.level}> {@render props.children?.()}</svelte:element>Example: Custom table component (advanced node)
Section titled “Example: Custom table component (advanced node)”For advanced use cases, nodes can access content and context to recursively render child nodes using StoryblokRichText.
The splitTableRows utility can be used to separate table header rows from body rows when creating custom table components.
<script lang="ts"> import { type SbSvelteRichTextProps, StoryblokRichText, splitTableRows, } from "@storyblok/svelte";
const props: SbSvelteRichTextProps<"table"> = $props();
const { headerRows, bodyRows } = $derived( splitTableRows(props.content) );</script>
<table class="custom-table"> {#if headerRows} <thead> <StoryblokRichText document={headerRows} {...props.context} /> </thead> {/if}
<tbody> <StoryblokRichText document={bodyRows} {...props.context} /> </tbody></table>Utility helpers
Section titled “Utility helpers”The Svelte SDK also exports the core rich text utilities from @storyblok/richtext. These can be useful when implementing advanced custom components, such as custom image or table rendering.
Available utilities include:
renderRichText: The core rich text rendering function.buildStoryblokImage: Generates optimized Storyblok Image Service URLs.splitTableRows: Splits table rows intoheaderRowsandbodyRows.
Further resources
Section titled “Further resources”Previous versions
Section titled “Previous versions”Was this page helpful?
This site uses reCAPTCHA and Google's Privacy Policy (opens in a new window) . Terms of Service (opens in a new window) apply.
Get in touch with the Storyblok community