Packages
@httpjpg/storyblok-api
Type-safe Storyblok Content Delivery API client
@httpjpg/storyblok-api
Type-safe client for Storyblok Content Delivery API with caching and error handling.
Installation
pnpm add @httpjpg/storyblok-apiSetup
Configure environment variables:
STORYBLOK_PREVIEW_TOKEN=your-preview-tokenBasic Usage
Get API Instance
import { getStoryblokApi } from '@httpjpg/storyblok-api';
const api = getStoryblokApi();Fetch Story
const { data } = await api.get('cdn/stories/home', {
version: 'draft', // or 'published'
});
const story = data.story;Fetch Multiple Stories
const { data } = await api.get('cdn/stories', {
version: 'draft',
starts_with: 'blog/',
per_page: 10,
});
const stories = data.stories;API Methods
get()
Fetch content from Storyblok:
api.get(slug: string, params?: StoryblokParams)Parameters:
slug- Story slug or endpoint pathparams- Query parameters
Common Parameters:
{
version: 'draft' | 'published',
resolve_links: 'url' | 'story',
resolve_relations: string,
cv: number, // Cache version
language: string,
fallback_lang: string,
}Caching
The API client includes built-in ISR caching:
export const revalidate = 3600; // 1 hour
async function getData() {
const api = getStoryblokApi();
const { data } = await api.get('cdn/stories/home', {
version: 'published',
});
return data.story;
}Error Handling
try {
const { data } = await api.get('cdn/stories/not-found');
} catch (error) {
if (error.status === 404) {
console.error('Story not found');
}
}TypeScript Types
import type {
ISbStoryData,
ISbStoriesParams,
ISbResult
} from '@httpjpg/storyblok-api';Examples
Fetch Blog Posts
const { data } = await api.get('cdn/stories', {
version: 'published',
starts_with: 'blog/',
sort_by: 'created_at:desc',
per_page: 100,
});
const posts = data.stories;Fetch with Relations
const { data } = await api.get('cdn/stories/page', {
version: 'draft',
resolve_relations: 'post.author',
});Fetch with Link Resolution
const { data } = await api.get('cdn/stories/home', {
version: 'draft',
resolve_links: 'url', // Convert internal links to URLs
});Next.js Integration
Server Component
import { getStoryblokApi } from '@httpjpg/storyblok-api';
export default async function Page() {
const api = getStoryblokApi();
const { data } = await api.get('cdn/stories/home', {
version: 'draft',
});
return <div>{data.story.content.title}</div>;
}With ISR
export const revalidate = 3600; // Revalidate every hour
export default async function Page() {
// Same as above
}Generate Static Params
export async function generateStaticParams() {
const api = getStoryblokApi();
const { data } = await api.get('cdn/stories', {
version: 'published',
starts_with: 'blog/',
});
return data.stories.map((story) => ({
slug: story.slug,
}));
}Best Practices
- Use
publishedversion in production - Enable ISR caching with
revalidate - Resolve links when needed for navigation
- Handle 404 errors gracefully
- Use TypeScript types for type safety