Kickstart a new CMS project
with your favorite technology
Storyblok is a Headless CMS that works with all modern frameworks and platforms so you are completely free to choose the best option for your project. Get started in a matter of minutes!
Storyblok and Next.js
Helpful resources
-
Get started with Next.js 13
Read our latest in-depth tutorial to start using Storyblok with Next.js 13.
-
Next.js Technology Hub
Check out our technology hub to learn more about the combined power of Storyblok and Next.js.
-
Storyblok Discord
Join our supportive community of Storyblok and Next.js developers in the #nextjs channel of our Discord server.
-
Learning Hub
Comprehensive developer guides, API documentation, technology hubs and more.
-
Kickstart a new project
Copy the command below by clicking on it and run it in your terminal. Choose Next.js 12 as your technology, follow the steps, and you're ready to go!
-
-
-
-
-
-
npm i @storyblok/react
-
- pages/_app.js
import { storyblokInit, apiPlugin } from "@storyblok/react"; storyblokInit({ accessToken: "<your-access-token>", use: [apiPlugin] });
-
3. Fetching a Story
In
pages/index.js
, fetch the home story of your Storyblok space. -
- pages/index.js
import Head from "next/head" import styles from "../styles/Home.module.css" import { getStoryblokApi } from "@storyblok/react" export default function Home(props) { return ( <div className={styles.container}> <Head> <title>Create Next App</title> <link rel="icon" href="/favicon.ico" /> </Head> <header> <h1> { props.story ? props.story.name : 'My Site' } </h1> </header> <main> </main> </div> ) } export async function getStaticProps() { // home is the default slug for the homepage in Storyblok let slug = "home"; // load the draft version let sbParams = { version: "draft", // or 'published' }; const storyblokApi = getStoryblokApi(); let { data } = await storyblokApi.get(`cdn/stories/${slug}`, sbParams); return { props: { story: data ? data.story : false, key: data ? data.story.id : false, }, revalidate: 3600, // revalidate every hour }; }
-
4. Create Storyblok components
Create the counterparts to the components defined in your Storyblok space.
StoryblokComponent
handles all of your nestable blocks automatically. -
- components/Page.js
import { storyblokEditable, StoryblokComponent } from "@storyblok/react"; const Page = ({ blok }) => ( <main {...storyblokEditable(blok)}> {blok.body.map((nestedBlok) => ( <StoryblokComponent blok={nestedBlok} key={nestedBlok._uid} /> ))} </main> ); export default Page;
-
Next Steps
Follow our Ultimate Tutorial and learn how to build a complete website using Storyblok and Next.js. Alternatively, check out our other Next.js-related tutorials.
Note: if you use Next.js 14+ with App Router, we released a new version of our React SDK fully supporting Server Components, with live editor enabled for developers. You can find a detailed guide in the README of our repo.
-
-
Storyblok and Nuxt
Helpful resources
-
Nuxt Technology Hub
Check out our technology hub to learn more about the combined power of Storyblok and Nuxt.
-
Storyblok Discord
Join our supportive community of Storyblok and Nuxt developers in the #nuxtjs channel of our Discord server.
-
Official SDK
Learn how to make the most out of @storyblok/nuxt. Feel free to share your feature requests, issues, or code contributions.
-
Learning Hub
Comprehensive developer guides, API documentation, technology hubs and more.
-
Kickstart a new project
Copy the command below by clicking on it and run it in your terminal. Choose Nuxt as your technology, follow the steps, and you're ready to go!
-
-
-
-
-
-
npm i @storyblok/nuxt
-
- nuxt.config.js
export default defineNuxtConfig({ modules: [ [ '@storyblok/nuxt', { accessToken: '<your-access-token>', }, ], ], })
-
3. Fetching a Story
In
pages/index.vue
, fetch the home story of your Storyblok space.StoryblokComponent
will resolve and render all of your Storyblok components. -
- pages/index.vue
<script setup> const story = await useStoryblok('home', { version: 'draft' }); </script> <template> <StoryblokComponent v-if="story" :blok="story.content" /> </template>
-
4. Create Storyblok components
Create the counterparts to the components defined in your Storyblok space in
storyblok
. Again,StoryblokComponent
handles all of your nestable blocks automatically. The Storyblok Bridge relies on thev-editable
directive. -
- storyblok/page.vue
<template> <div v-editable="blok" class="px-4"> <StoryblokComponent v-for="blok in blok.body" :key="blok._uid" :blok="blok" /> </div> </template> <script setup> defineProps({ blok: Object }) </script>
-
-
Storyblok and React
Helpful resources
-
React Technology Hub
Check out our technology hub to learn more about the combined power of Storyblok and React.
-
Storyblok Discord
Join our supportive community of Storyblok and React developers in the #react channel of our Discord server.
-
Official SDK
Learn how to make the most out of @storyblok/react. Feel free to share your feature requests, issues, or code contributions.
-
Learning Hub
Comprehensive developer guides, API documentation, technology hubs and more.
-
Kickstart a new project
Copy the command below by clicking on it and run it in your terminal. Choose React as your technology, follow the steps, and you’re ready to go!
-
-
-
-
-
-
npm i @storyblok/react
-
- index.js
import { storyblokInit, apiPlugin } from '@storyblok/react' import Page from './components/Page' import Grid from './components/Grid' import Feature from './components/Feature' import Teaser from './components/Teaser' storyblokInit({ accessToken: 'YOUR_PREVIEW_TOKEN', use: [apiPlugin], components: { page: Page, teaser: Teaser, feature: Feature, grid: Grid, }, })
-
3. Fetching a Story
In
App.jsx
, fetch the home story of your Storyblok space.StoryblokComponent
will resolve and render all of your Storyblok components. -
- App.jsx
import { useStoryblok, StoryblokComponent } from '@storyblok/react' function App() { let slug = window.location.pathname === '/' ? 'home' : window.location.pathname.replace('/', '') const story = useStoryblok(slug, { version: 'draft' }) if (!story || !story.content) { return <div>Loading...</div> } return <StoryblokComponent blok={story.content} /> } export default App
-
4. Create Storyblok components
Create the counterparts to the components defined in your Storyblok space in
src/components
. Again,StoryblokComponent
handles all of your nestable blocks automatically. The Storyblok Bridge relies onstoryblokEditable
. -
- components/Page.js
import { StoryblokComponent, storyblokEditable } from "@storyblok/react"; const Page = ({ blok }) => ( <main {...storyblokEditable(blok)}> {blok.body ? blok.body.map((blok) => ( <StoryblokComponent blok={blok} key={blok._uid} /> )) : null} </main> ); export default Page;
-
-
Storyblok and Vue
Helpful resources
-
Vue Technology Hub
Check out our technology hub to learn more about the combined power of Storyblok and Vue.
-
Storyblok Discord
Join our supportive community of Storyblok and Vue developers in the #vuejs channel of our Discord server.
-
Official SDK
Learn how to make the most out of @storyblok/vue. Feel free to share your feature requests, issues, or code contributions.
-
Learning Hub
Comprehensive developer guides, API documentation, technology hubs and more.
-
Kickstart a new project
Copy the command below by clicking on it and run it in your terminal. Choose Vue as your technology, follow the steps, and you’re ready to go!
-
-
-
-
-
-
npm i @storyblok/vue
-
- src/main.js
import { createApp } from 'vue' import { StoryblokVue, apiPlugin } from '@storyblok/vue' import App from './App.vue' import Grid from './components/Grid.vue' import Page from './components/Page.vue' import Teaser from './components/Teaser.vue' import Feature from './components/Feature.vue' const app = createApp(App) app.use(StoryblokVue, { accessToken: '9I0NMaGJZQaJQ4Qzmm5cHwtt', use: [apiPlugin], }) app.component('Grid', Grid) app.component('Page', Page) app.component('Teaser', Teaser) app.component('Feature', Feature) app.mount('#app')
-
3. Fetching a Story
In
src/pages/Home.vue
, fetch the home story of your Storyblok space.StoryblokComponent
will resolve and render all of your Storyblok components. -
- src/pages/Home.vue
<script setup> import { useStoryblok } from '@storyblok/vue'; const story = await useStoryblok('home', { version: 'draft' }); </script> <template> <StoryblokComponent v-if="story" :blok="story.content" /> </template>
-
4. Create Storyblok components
Create the counterparts to the components defined in your Storyblok space in
src/components
. Again,StoryblokComponent
handles all of your nestable blocks automatically. The Storyblok Bridge relies on thev-editable
directive. -
- src/components/Page.vue
<script setup> defineProps({ blok: Object }) </script> <template> <div v-editable="blok" class="px-6"> <StoryblokComponent v-for="inblok in blok.body" :blok="inblok" :key="inblok._uid" /> </div> </template>
-
-
Storyblok and Astro
Helpful resources
-
Astro Technology Hub
Check out our technology hub to learn more about the combined power of Storyblok and Astro.
-
Storyblok Discord
Join our supportive community of Storyblok and Astro developers in the #astro channel of our Discord server.
-
Official SDK
Learn how to make the most out of @storyblok/astro. Feel free to share your feature requests, issues, or code contributions.
-
Learning Hub
Comprehensive developer guides, API documentation, technology hubs and more.
-
Kickstart a new project
Copy the command below by clicking on it and run it in your terminal. Choose Astro as your technology, follow the steps, and you're ready to go!
-
-
-
-
-
-
npm i @storyblok/astro
-
- astro.config.mjs
import { defineConfig } from 'astro/config' import storyblok from '@storyblok/astro' export default defineConfig({ integrations: [ storyblok({ accessToken: '<your-access-token>', components: { page: 'storyblok/Page', feature: 'storyblok/Feature', grid: 'storyblok/Grid', teaser: 'storyblok/Teaser', }, }), ], })
-
3. Fetching a Story
In
src/pages/index.astro
, fetch the home story of your Storyblok space.StoryblokComponent
will resolve and render all of your Storyblok components. -
- src/pages/index.astro
--- import { useStoryblokApi } from "@storyblok/astro"; import StoryblokComponent from "@storyblok/astro/StoryblokComponent.astro"; const storyblokApi = useStoryblokApi(); const { data } = await storyblokApi.get("cdn/stories/home", { version: "draft", }); const story = data.story; --- <StoryblokComponent blok="{story.content}" />
-
4. Create Storyblok components
Create the counterparts to the components defined in your Storyblok space in
src/storyblok
. Again,StoryblokComponent
handles all of your nestable blocks automatically. The Storyblok Bridge relies onstoryblokEditable
. -
- 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 => {return <StoryblokComponent blok={blok} />})} </main>
-
-
Storyblok and SvelteKit
Helpful resources
-
SvelteKit Technology Hub
Check out our technology hub to learn more about the combined power of Storyblok and SvelteKit.
-
Storyblok Discord
Join our supportive community of Storyblok and Svelte developers in the #svelte channel of our Discord server.
-
Official SDK
Learn how to make the most out of @storyblok/svelte. Feel free to share your feature requests, issues, or code contributions.
-
Learning Hub
Comprehensive developer guides, API documentation, technology hubs and more.
-
Kickstart a new project
Copy the command below by clicking on it and run it in your terminal. Choose SvelteKit as your technology, follow the steps, and you're ready to go!
-
-
-
-
-
-
npm i @storyblok/svelte
-
- main.js
import App from './App.svelte' import { storyblokInit, apiPlugin } from '@storyblok/svelte' storyblokInit({ accessToken: '<your-access-token>', use: [apiPlugin], components: { page: Page, feature: Feature, grid: Grid, teaser: Teaser, }, })
-
3. Fetching a Story
In
src/routes/+page.js
, fetch the home story of your Storyblok space. The Storyblok Bridge is enabled insrc/routes/+page.svelte
.StoryblokComponent
resolves and renders all of your Storyblok components. -
- src/routes/+page.js
/** @type {import('./$types').PageLoad} */ export async function load({ parent }) { const { storyblokApi } = await parent() const dataStory = await storyblokApi.get('cdn/stories/home', { version: 'draft', }) return { story: dataStory.data.story, } }
- src/routes/+page.svelte
<script> import { onMount } from "svelte"; import { useStoryblokBridge, StoryblokComponent } from "@storyblok/svelte"; export let data; onMount(() => { if (data.story) { useStoryblokBridge(data.story.id, (newStory) => (data.story = newStory)); } }); </script> <div> {#if data.story} <StoryblokComponent blok={data.story.content} /> {/if} </div>
-
4. Create Storyblok components
Create the counterparts to the components defined in your Storyblok space. Again,
StoryblokComponent
handles all of your nestable blocks automatically. The Storyblok Bridge relies onstoryblokEditable
. -
- src/components/Page.svelte
<script> import { storyblokEditable, StoryblokComponent } from "@storyblok/svelte"; export let blok; </script> {#key blok} <div use:storyblokEditable={blok} class="px-6"> {#each blok.body as blok} <StoryblokComponent {blok} /> {/each} </div> {/key}
-
-
Storyblok and Remix
Helpful resources
-
Remix Technology Hub
Check out our technology hub to learn more about the combined power of Storyblok and Remix.
-
Storyblok Discord
Join our supportive community of Storyblok and Remix developers in the #remix channel of our Discord server.
-
Learning Hub
Comprehensive developer guides, API documentation, technology hubs and more.
-
Kickstart a new project
Copy the command below by clicking on it and run it in your terminal. Choose Remix as your technology, follow the steps, and you're ready to go!
-
-
-
-
-
-
npm i @storyblok/react
-
- app/root.jsx
import { storyblokInit, apiPlugin } from "@storyblok/react"; import Feature from "./components/Feature"; import Grid from "./components/Grid"; import Page from "./components/Page"; import Teaser from "./components/Teaser"; const components = { feature: Feature, grid: Grid, teaser: Teaser, page: Page, }; storyblokInit({ accessToken: "your-preview-token", use: [apiPlugin], components, });
-
3. Fetching Stories
In
app/routes/$slug.jsx
, you can dynamically fetch the stories of your Storyblok space.StoryblokComponent
will resolve and render all of your Storyblok components. -
- app/routes/$slug.jsx
import { json } from "@remix-run/node"; import { useLoaderData } from "@remix-run/react"; import { getStoryblokApi, useStoryblokState, StoryblokComponent, } from "@storyblok/react"; export const loader = async ({ params }) => { const slug = params.slug ?? "home"; let sbParams = { version: "draft", }; let { data } = await getStoryblokApi().get(`cdn/stories/${slug}`, sbParams); return json(data?.story); }; export default function Page() { let story = useLoaderData(); story = useStoryblokState(story); return <StoryblokComponent blok={story.content} />; }
-
4. Create Storyblok components
Create the counterparts to the components defined in your Storyblok space in
app/components
. Again,StoryblokComponent
handles all of your nestable blocks automatically. The Storyblok Bridge relies onstoryblokEditable
. -
- app/components/Page.jsx
import { storyblokEditable, StoryblokComponent } from "@storyblok/react"; const Page = ({ blok }) => ( <main {...storyblokEditable(blok)} key={blok._uid}> {blok.body.map((nestedBlok) => ( <StoryblokComponent blok={nestedBlok} key={nestedBlok._uid} /> ))} </main> ); export default Page;
-
-
Storyblok and Gatsby
Helpful resources
-
Gatsby Technology Hub
Check out our technology hub to learn more about the combined power of Storyblok and Gatsby.
-
Storyblok Discord
Join our supportive community of Storyblok and Gatsby developers in the #gatsbyjs channel of our Discord server.
-
Official SDK
Learn how to make the most out of @storyblok/gatsby-source-storyblok. Feel free to share your feature requests, issues, or code contributions.
-
Learning Hub
Comprehensive developer guides, API documentation, technology hubs and more.
-
Kickstart a new project
Copy the command below by clicking on it and run it in your terminal. Choose Gatsby as your technology, follow the steps, and you’re ready to go!
-
-
-
-
-
-
npm i gatsby-source-storyblok
-
- gatsby-config.js
module.exports = { flags: { PARTIAL_HYDRATION: true // Required for Partial Hydration (RSC) }, plugins: [ { resolve: 'gatsby-source-storyblok', options: { accessToken:'<your-access-token>', } } ], }
-
- src/components/layout.jsx
"use client"; import React from "react" import PropTypes from "prop-types" import { storyblokInit, apiPlugin } from "gatsby-source-storyblok" import Teaser from './Teaser' import Grid from './Grid' import Page from './Page' import Feature from './Feature' storyblokInit({ accessToken: "your-access-token", use: [apiPlugin], components: { teaser: Teaser, grid: Grid, feature: Feature, page: Page } }); const Layout = ({ children }) => { return ( <div> <main>{children}</main> </div> ) } Layout.propTypes = { children: PropTypes.node.isRequired, } export default Layout
-
- src/pages/index.js
import * as React from "react" import { graphql } from "gatsby" import { StoryblokStory } from "gatsby-source-storyblok" import Layout from "../components/layout" const IndexPage = ({ data }) => { if (typeof data.storyblokEntry.content === "string") data.storyblokEntry.content = JSON.parse(data.storyblokEntry.content); return ( <Layout> <StoryblokStory story={data.storyblokEntry} /> </Layout> ) } export default IndexPage export const query = graphql` query HomeQuery { storyblokEntry(full_slug: { eq: "home" }) { content name full_slug id } } `
-
- src/components/Page.tsx
import React from "react"; import { storyblokEditable, StoryblokComponent } from "gatsby-source-storyblok"; const Page = ({ blok }) => { return ( <main {...storyblokEditable(blok)}> {blok.body.map((nestedBlok) => ( <StoryblokComponent blok={nestedBlok} key={nestedBlok._uid} /> ))} </main> ) }; export default Page;
-
-
Other Technologies
We are working hard to create comprehensive learning hubs for every popular technology. The following resources will help you kickstart your project and learn how Storyblok can be used with your technology of choice.
-
Choose your technology
-
JavaScript
Use the Universal JavaScript SDK to integrate with the Storyblok APIs in any JavaScript project.
-
TypeScript
Learn how to utilize the power of TypeScript in your Storyblok projects.
-
Angular
Learn how to use Storyblok with Angular.
-
Preact
Learn how to use Storyblok with Preact.
-
PHP
Use the official PHP Client to integrate with the Storyblok APIs in any PHP project.
-
Laravel
Learn how to use Storyblok with Laravel.
-
Python
Use the official Python Client to integrate with the Storyblok APIs in any Python project.
-
Ruby
This article will show you how to use Storyblok in combination with Ruby on Rails.
-
Django
Learn how to combine Python, Django, and Jinja2 to render data from Storyblok.
-
ASP.NET
Learn how to integrate the Storyblok API with an ASP.NET application and enable a real-time content preview in the Visual Editor.
-