Skip to content

@storyblok/astro

@storyblok/astro is Storyblok’s official development for Astro applications.

  • Astro version 3.0 or later
  • Node.js LTS (version 22.x recommended)
  • Modern web browser (e.g., Chrome, Firefox, Safari, Edge – latest versions)

Add the package to a project by running this command in the terminal:

Terminal window
npm install @storyblok/astro@latest

Import and initialize the SDK using the access token of a Storyblok space.

astro.config.mjs
import { defineConfig } from "astro/config";
import { storyblok } from "@storyblok/astro";
export default defineConfig({
integrations: [
storyblok({
accessToken: "YOUR_ACCESS_TOKEN",
apiOptions: {
region: "eu",
},
components: {
page: "storyblok/Page",
feature: "storyblok/Feature",
},
}),
],
});

Create an Astro component for each block defined in Storyblok and registered in the configuration. Each component will receive a blok prop, containing the content of the block.

src/storyblok/Feature.astro
---
import { storyblokEditable } from "@storyblok/astro";
const { blok } = Astro.props
---
<div {...storyblokEditable(blok)}>
<h2>{blok.headline}</h2>
</div>

Use <StoryblokComponent> to automatically render nested components (provided they are registered globally).

src/storyblok/Page.astro
---
import { storyblokEditable } from '@storyblok/astro';
import StoryblokComponent from '@storyblok/astro/StoryblokComponent.astro';
const { blok } = Astro.props;
---
<main {...storyblokEditable(blok)}>{blok.body?.map((blok) => <StoryblokComponent blok="{blok}" />)}</main>

In an Astro page or component, use the client to fetch a story and render the content using StoryblokComponent.

src/pages/index.astro
---
import { useStoryblokApi } from "@storyblok/astro";
import StoryblokComponent from "@storyblok/astro/StoryblokComponent.astro";
import BaseLayout from "../layouts/BaseLayout.astro";
const sbApi = useStoryblokApi();
const { data } = await sbApi.get("cdn/stories/home", {
version: "draft",
resolve_relations: ["featured-articles.posts"],
});
const story = data.story;
---
<BaseLayout>
<StoryblokComponent blok="{story.content}" />
</BaseLayout>

Import and initialize the SDK to access and configure all features.

import { defineConfig } from "astro/config";
import { storyblok } from "@storyblok/astro";
export default defineConfig({
integrations: [storyblok(OPTIONS)],
});

All options listed in the @storyblok/js package reference are available. The following additional options are available:

KeyDescriptionType
bridgeEnable or disable the Storyblok Bridge. Without livePreview being enabled, the Bridge is configured to refresh on saving and publishing the story. Pass an object with Bridge options for additional configuration. See example below.boolean | object
componentsRegister Astro components intended to render Storyblok blocks. Located in the src directory by default. See example below.object
componentsDirDefine a custom directory other than src as the location of components.string
livePreviewEnable or disable live preview. Disabled by default.boolean
enableFallbackComponentEnable or disable a fallback component to be rendered if no React component has been defined for a Storyblok block. Disabled by default.boolean
customFallbackComponentRegister a custom fallback component. Requires enableFallbackComponent to be enabled. See example below.string
useCustomApiBy default, the apiPlugin from @storyblok/js is loaded. Disable this behavior by setting useCustomApi to true to optimize the final bundle when using a custom method to fetch data from Storyblok.boolean

Register components as follows. The key represents the technical name of the Storyblok block, the value represents the location of the Astro component. The src folder is prepended, the .astro file extension is appended.

storyblok({
components: {
page: "storyblok/Page",
feature: "storyblok/Feature",
grid: "storyblok/Grid",
teaser: "storyblok/Teaser",
},
});
storyblok({
enableFallbackComponent: true,
customFallbackComponent: "storyblok/MyCustomFallback",
});

Learn more in the @storyblok/preview-bridge reference. Note that resolveRelations and resolveLinks only become effective when livePreview is enabled.

storyblok({
bridge: {
customParent?: string,
preventClicks?: boolean, // Defaults to false.
resolveRelations?: strings[],
resolveLinks?: string
},
});

useStoryblokApi() returns the client instantiated in the application.

---
import { useStoryblokApi } from '@storyblok/astro';
const storyblokApi = useStoryblokApi();
const { data } = await storyblokApi.get(URL, API_OPTIONS);
---

For the API_OPTIONS, see the storyblok-js-client reference.

This function returns the updated story object whenever changes are made in the Storyblok Visual Editor, providing a real-time editing experience. Requires livePreview to be enabled.

await getLiveStory(Astro);
---
import { getLiveStory, useStoryblokApi } from '@storyblok/astro';
import StoryblokComponent from "@storyblok/astro/StoryblokComponent.astro";
const { slug } = Astro.params;
let story = null;
const liveStory = await getLiveStory(Astro);
if (liveStory) {
story = liveStory;
} else {
const storyblokApi = useStoryblokApi();
const { data } = await storyblokApi.get(\`cdn/stories/\${ slug || 'home' } \`, {
version: 'draft',
resolve_relations: ['featured-articles.posts'],
});
story = data?.story;
}
---
<StoryblokComponent blok="{story.content}" />

Event to be used to trigger a callback function whenever the DOM has been updated in live preview mode.

<script>
document.addEventListener("storyblok-live-preview-updated", () => {
console.log("Storyblok live preview: DOM updated");
});
</script>

This component automatically renders Storyblok blocks for corresponding Astro components registered using the components option of the storyblok Astro integration. It requires a blok property. Any additional passed properties are forwarded to the Astro component.

<StoryblokComponent blok={story.content}

Use it to iterate over blocks fields as follows:

{
blok.nested_bloks?.map((currentBlok) => <StoryblokComponent blok={currentBlok} />);
}

This function connects Astro components to their Storyblok counterparts, adding HTML attributes that allow the Storyblok Bridge to work. See the @storyblok/js reference for further details.

---
import { storyblokEditable } from '@storyblok/astro';
const { blok } = Astro.props;
---
<section {...storyblokEditable(blok)}>{blok.title}</section>

This function converts a Storyblok rich text field into HTML.

---
import { renderRichText } from "@storyblok/astro";
const { blok } = Astro.props;
const renderedRichText = renderRichText(blok.richtext_field);
---
<div set:html="{renderedRichText}" />

See the @storyblok/richtext reference for further details.