A content loader for Astro Content Layer that fetches content from Storyblok's API.
- Astro 5.18.1 or higher (required for Content Layer API), tested to work on 6.0.4
- @storyblok/astro 8.1.0 or higher
Compatibility note (March 12, 2026): @storyblok/[email protected] declares peer support for Astro 3–5 only, but this loader has been verified to work with Astro 6.0.4. The package's peerDependencies currently track Astro 5.x for compatibility with @storyblok/astro. If you are using Astro 6, you can still install and use this loader; expect a peer dependency warning until @storyblok/astro updates its Astro peer range.
- Intended to be used for build process, not in development mode or using Storyblok's Live Preview.
- Internationalization support has not been tested. Use with caution and please report any issues you encounter.
Using npm:
npm install @nonsponsored/storyblok-loader
Using yarn:
yarn add @nonsponsored/storyblok-loader
- Set up your environment variables in
.env:
STORYBLOK_API_KEY: Your Storyblok API tokenSTORYBLOK_API_VERSION: "draft" or "published"
Note: In production, the loader will always use the "published" version regardless of the STORYBLOK_API_VERSION setting.
- Configure your content collection in
src/content/config.ts:
import { defineCollection } from "astro:content";
import { storyblokLoader } from "@nonsponsored/storyblok-loader";
const storyblokCollection = defineCollection({
loader: storyblokLoader({
accessToken: import.meta.env.STORYBLOK_API_KEY,
version: import.meta.env.MODE === "production" ? "published" : import.meta.env.STORYBLOK_API_VERSION,
region: "us",
language: "en",
contentType: "blog",
resolve_relations: ["author.posts", "related_posts"],
resolve_links: "url",
sort_by: "content.published_date:desc",
filter_query: {
"content.category": "technology"
}
})
});
export const collections = {
storyblok: storyblokCollection,
};
The loader accepts the following options:
| Option | Type | Default | Description |
|---|---|---|---|
accessToken |
string |
Required | Your Storyblok API token |
version |
"published" | "draft" |
"published" |
Content version to fetch |
region |
"us" | "eu" |
"us" |
Storyblok API region |
language |
string |
undefined | Language/locale code (e.g., "en", "de") |
contentType |
string |
undefined | Filter by content type |
sort_by |
string |
undefined | Sort entries by field |
filter_query |
Record<string, any> |
undefined | Filter by field values |
resolve_relations |
string[] |
undefined | Resolve relationships |
resolve_links |
"url" | "story" | "0" | "1" | "2" |
undefined | Resolve links to other stories |
The loader returns an array of stories with the following structure:
interface Story {
id: string;
uuid: string;
slug: string;
content: unknown;
name: string;
created_at: string;
published_at: string;
editable?: string;
is_folder?: boolean;
full_slug: string;
language?: string;
translated_slugs?: Array<{
lang: string;
name: string;
path: string;
}>;
}
const storyblokCollection = defineCollection({
loader: storyblokLoader({
accessToken: import.meta.env.STORYBLOK_API_KEY,
version: import.meta.env.MODE === "production" ? "published" : "draft",
region: "us"
})
});
export const collections = {
storyblok: storyblokCollection,
};
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License