Integrate Astro with Storyblok
Use Storyblok to manage the content of your Astro website.
This guide has been tested with the following package versions:
astro@5.7.14
storyblok-astro@6.2.0
- Node.js v22.13.0
Setup
Create a new Astro project following the official installation page.
If you already have a Storyblok account, go to app.storyblok.com or log in with GitHub to continue.
Create a new blank space to follow the tutorial from scratch, or start from the core blueprint.
No Storyblok account yet?
Create one and start a free Storyblok space Opens in new tabInstallation
In the terminal, cd
into the Astro project and install the @storyblok/astro
package.
npm install @storyblok/astro
In the astro.config.mjs
file, initialize the Storyblok module:
import { defineConfig } from 'astro/config';
import { storyblok } from '@storyblok/astro';
import { loadEnv } from 'vite';
const env = loadEnv('', process.cwd(), 'STORYBLOK');
const { STORYBLOK_DELIVERY_API_TOKEN } = loadEnv(
import.meta.env.MODE,
process.cwd(),
'',
);
export default defineConfig({
integrations: [
storyblok({
accessToken: env.STORYBLOK_DELIVERY_API_TOKEN,
apiOptions: {
region: 'eu',
},
}),
],
output: 'server',
});
Ensure to set the correct region
value depending on the server location of your Storyblok space. Learn more in the @storyblok/js package reference.
In the root of the project, create a .env
file to store the Storyblok access token.
STORYBLOK_DELIVERY_API_TOKEN=<YOUR-ACCESS-TOKEN>
Learn how to get an access token for your Storyblok project.
The Storyblok integration will make features like fetching, components registration and bridge available across your project.
Fetch a single story
In the src/pages/index.astro
file, replace Astro's default contents with the following.
---
import { useStoryblokApi } from "@storyblok/astro";
import StoryblokComponent from "@storyblok/astro/StoryblokComponent.astro";
import Layout from "../layouts/Layout.astro";
const storyblokApi = useStoryblokApi()
const { data } = await storyblokApi.get("cdn/stories/home", {
version: "draft",
});
const { story } = data;
---
<Layout>
<StoryblokComponent blok={story.content} />
</Layout>
The StoryblokComponent
dynamically renders content type and nestable blocks. In this case, it looks for the content type block of the home story.
Create and register blocks
Create Page.astro
component to render all stories of the page
content type, such as the home story.
---
import StoryblokComponent from "@storyblok/astro/StoryblokComponent.astro";
const { blok } = Astro.props;
---
<main>
{
blok.body?.map((blok) => {
return <StoryblokComponent blok={blok} />;
})
}
</main>
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 (e.g. Feature, Teaser, Grid) in it.
Create the code for these components as follows.
---
const { blok } = Astro.props
---
<div class="feature">
<span>{blok.name}<span>
</div>
---
const { blok } = Astro.props;
---
<div class="teaser">
<h2>{blok.headline}</h2>
</div>
---
import StoryblokComponent from "@storyblok/astro/StoryblokComponent.astro";
const { blok } = Astro.props;
---
<div class="grid">
{
blok.columns?.map((nestedBlok) => {
return <StoryblokComponent blok={nestedBlok} />
})
}
</div>
Similar to Page.astro
, Grid.astro
iterates over the columns
block field.
Add these components to the astro.config.mjs
file.
import { defineConfig } from "astro/config";
import { storyblok } from "@storyblok/astro";
import { loadEnv } from "vite";
const env = loadEnv("", process.cwd(), "STORYBLOK");const { STORYBLOK_DELIVERY_API_TOKEN} = loadEnv(import.meta.env.MODE, process.cwd(), "");
export default defineConfig({
integrations: [
storyblok({
accessToken: env.STORYBLOK_DELIVERY_API_TOKEN,
apiOptions: {
region: "eu", // Optional. Defaults to "eu"
},
components: {
page: "storyblok/Page",
grid: "storyblok/Grid",
feature: "storyblok/Feature",
teaser: "storyblok/Teaser",
}
}),
],
output: 'server',
});
Run the server and visit the site in your browser.
npm run dev
Next Part
Visual Preview in Astro