Aller au contenu

Storyblok & Astro

Storyblok est un CMS headless basé sur des composants qui vous permet de gérer votre contenu à l’aide de composants réutilisables appelés Bloks.

Dans cette section, vous utiliserez l’intégration Storyblok pour connecter Storyblok à Astro.

Pour commencer, vous devez disposer des éléments suivants :

  1. Un projet Astro - Si vous n’avez pas encore de projet Astro, notre Guide d’installation vous permettra d’être opérationnel en un rien de temps.

  2. Un compte Storyblok et un espace - Si vous n’avez pas encore de compte, inscrivez-vous gratuitement et créez un nouvel espace.

  3. Un jeton de prévisualisation Storyblok - Ce jeton sera utilisé pour récupérer les brouillons et les versions publiées de votre contenu. Vous pouvez trouver et générer votre jeton API dans l’onglet Jetons d’accès des paramètres de votre espace Storyblok.

Pour ajouter vos identifiants Storyblok à Astro, créez un fichier .env à la racine de votre projet avec la variable suivante :

.env
STORYBLOK_TOKEN=YOUR_PREVIEW_TOKEN

Vous devriez maintenant pouvoir utiliser ces variables d’environnement dans votre projet.

Votre répertoire racine doit maintenant contenir ce nouveau fichier :

  • Répertoiresrc/
  • .env
  • astro.config.mjs
  • package.json

Pour connecter Astro à votre espace Storyblok, installez l’intégration officielle Storyblok integration en utilisant la commande ci-dessous pour votre gestionnaire de paquets préféré :

Fenêtre de terminal
npm install @storyblok/astro vite

Modifiez votre fichier de configuration Astro pour inclure l’intégration de Storyblok :

astro.config.mjs
import { defineConfig } from 'astro/config';
import storyblok from '@storyblok/astro';
import { loadEnv } from 'vite';
const env = loadEnv("", process.cwd(), 'STORYBLOK');
export default defineConfig({
integrations: [
storyblok({
accessToken: env.STORYBLOK_TOKEN,
components: {
// Ajoutez vos composants ici
},
apiOptions: {
// Choisissez votre région de l'espace Storyblok
region: 'us', // optional, or 'eu' (default)
},
})
],
});

L’intégration de Storyblok nécessite un objet avec les propriétés suivantes :

  1. accessToken - Ceci fait référence au jeton API de Storyblok que vous avez ajouté dans l’étape précédente.
  1. components - Un objet qui associe les noms des composants Storyblok aux chemins vers vos composants locaux. Ceci est nécessaire pour rendre vos Storyblok Bloks dans Astro.
  1. apiOptions - Un objet contenant les options de l’API Storyblok.

Connexion des Bloks aux composants Astro

Titre de la section Connexion des Bloks aux composants Astro

Pour connecter vos Bloks à Astro, créez un nouveau dossier nommé storyblok dans le répertoire src. Ce dossier contiendra tous les composants Astro qui correspondront à vos Bloks dans votre bibliothèque Storyblok Blok.

Dans cet exemple, vous avez un type de contenu Blok blogPost dans votre bibliothèque Storyblok avec les champs suivants :

  • title - Un champ de texte
  • description - Un champ de texte
  • content - Un champ de texte riche

Notre but est de créer un composant Astro équivalent qui utilisera ces champs pour rendre son contenu. Pour ce faire, créez un nouveau fichier nommé BlogPost.astro dans src/storyblok avec le contenu suivant :

src/storyblok/BlogPost.astro
---
import { storyblokEditable, renderRichText } from '@storyblok/astro'
const { blok } = Astro.props
const content = renderRichText(blok.content)
---
<article {...storyblokEditable(blok)}>
<h1>{blok.title}</h1>
<p>{blok.description}</p>
<Fragment set:html={content} />
</article>

La propriété blok contient les données que vous recevrez de Storyblok. Elle contient également les champs qui ont été définis dans le type de contenu blogPost Blok dans Storyblok.

Pour rendre notre contenu, l’intégration fournit des fonctions utilitaires telles que :

  • storyblokEditable - elle ajoute les attributs nécessaires aux éléments afin que vous puissiez les éditer dans Storyblok.
  • renderRichText - elle transforme le champ de texte riche en HTML.

Votre répertoire racine devrait inclure ce nouveau fichier :

  • Répertoiresrc/
  • Répertoirestoryblok/
  • BlogPost.astro
  • .env
  • astro.config.mjs
  • package.json

Enfin, pour connecter le Blok blogPost au composant BlogPost, ajoutez une nouvelle propriété à votre objet components dans votre fichier de configuration Astro.

  • La clé est le nom du Blok dans Storyblok. Dans ce cas, il s’agit de blogPost.
  • La valeur est le chemin vers le composant. Dans ce cas, c’est storyblok/BlogPost.
astro.config.mjs
import { defineConfig } from 'astro/config';
import storyblok from '@storyblok/astro';
import { loadEnv } from 'vite';
const env = loadEnv("", process.cwd(), 'STORYBLOK');
export default defineConfig({
integrations: [
storyblok({
accessToken: env.STORYBLOK_TOKEN,
components: {
blogPost: 'storyblok/BlogPost',
},
apiOptions: {
region: 'us',
},
})
],
});

Pour tester la configuration, dans Storyblok, créez une nouvelle story avec le type de contenu blogPost nommée test-post. Dans Astro, créez une nouvelle page dans le répertoire src/pages/ nommée test-post.astro avec le contenu suivant :

src/pages/test-post.astro
---
import { useStoryblokApi } from '@storyblok/astro'
import StoryblokComponent from '@storyblok/astro/StoryblokComponent.astro'
const storyblokApi = useStoryblokApi()
const { data } = await storyblokApi.get("cdn/stories/test-post", {
version: import.meta.env.DEV ? "draft" : "published",
});
const content = data.story.content;
---
<StoryblokComponent blok={content} />

Pour interroger vos données, utilisez le hook useStoryblokApi. Cela initialisera une nouvelle instance de client en utilisant votre configuration d’intégration.

Pour rendre votre contenu, passez la propriété content de la story au StoryblokComponent en tant que prop blok. Ce composant rendra les Bloks définis dans la propriété content. Dans ce cas, il rendra le composant BlogPost.

Avec l’intégration mise en place, vous pouvez maintenant créer un blog avec Astro et Storyblok.

  1. Un espace Storyblok - Pour ce tutoriel, nous recommandons d’utiliser un nouvel espace. Si vous avez déjà un espace avec des Bloks, n’hésitez pas à les utiliser, mais vous devrez modifier le code pour qu’il corresponde aux noms et aux types de contenu des Bloks.

  2. Un projet Astro intégré à Storyblok - Voir les intégrations avec Astro pour les instructions sur la façon de mettre en place l’intégration.

Pour créer des Bloks, allez dans l’application Storyblok et cliquez sur le bouton Block Library. Cliquez ensuite sur le bouton + New blok et créer les Bloks suivants :

  1. blogPost - Un type de contenu Blok avec les champs suivants :
  • title - Un champ de texte
  • description - Un champ de texte
  • content - Un champ de texte enrichi
  1. blogPostList - Un Blok imbriqué vide

  2. page - Un type de contenu Blok avec les champs suivants :

  • body - Un Blok emboîtable

Pour ajouter un nouveau contenu, accédez à la section Contenu en cliquant sur l’onglet Contenu. En utilisant la bibliothèque Blok que vous avez créée à l’étape précédente, créez les storys suivantes :

  1. Une story de type contenu avec le Blok page. Dans le champ body, ajoutez un Blok blogPostList.

  2. blog/no-javascript - Une story de type de contenu blogPost dans le dossier blog.

title: Pas de JavaScript
description: Un exemple d'article de blog
content: Bonjour à tous ! Cet article de blog qui n'utilise pas de JavaScript.
  1. blog/astro-is-amazing - Une story de type de contenu blogPost dans le dossier blog.
title: Astro est incroyable
description: Nous aimons Astro
content: Bonjour à tous ! Cet article de blog a été créé avec Astro.

Maintenant que votre contenu est prêt, retournez à votre projet Astro et commencez à construire votre blog.

Pour connecter vos Bloks nouvellement créés aux composants Astro, créez un nouveau dossier nommé storyblok dans votre répertoire src et ajoutez les fichiers suivants :

Page.astro est un composant de type Block emboîtable qui rendra récursivement tous les Bloks à l’intérieur de la propriété body du Blok page. Il ajoute également les attributs storyblokEditable à l’élément parent, ce qui nous permettra d’éditer la page dans Storyblok.

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>

BlogPost.astro rendra les propriétés title, description et content du Blok blogPost.

Pour transformer la propriété content d’un champ de texte riche en HTML, vous pouvez utiliser la fonction d’aide renderRichText.

src/storyblok/BlogPost.astro
---
import { storyblokEditable, renderRichText } from '@storyblok/astro'
const { blok } = Astro.props
const content = renderRichText(blok.content)
---
<article {...storyblokEditable(blok)}>
<h1>{blok.title}</h1>
<p>{blok.description}</p>
<Fragment set:html={content} />
</article>

BlogPostList.astro est un composant de type Blok imbriquable qui rendra une liste d’aperçus d’articles de blogs.

Il utilise le hook useStoryblokApi pour récupérer toutes les story avec le type de contenu blogPost. Il utilise le paramètre de requête version pour récupérer les versions préliminaires des articles lorsqu’il est en mode développement et les versions publiées lorsqu’il est en mode production.

Astro.props est utilisé pour configurer l’éditeur dans Storyblok. Des props supplémentaires peuvent également être passés à votre composant ici, si nécessaire.

src/storyblok/BlogPostList.astro
---
import { storyblokEditable } from '@storyblok/astro'
import { useStoryblokApi } from '@storyblok/astro'
const storyblokApi = useStoryblokApi();
const { data } = await storyblokApi.get('cdn/stories', {
version: import.meta.env.DEV ? "draft" : "published",
content_type: 'blogPost',
})
const posts = data.stories.map(story => {
return {
title: story.content.title,
date: new Date(story.published_at).toLocaleDateString("en-US", {dateStyle: "full"}),
description: story.content.description,
slug: story.full_slug,
}
})
const { blok } = Astro.props
---
<ul {...storyblokEditable(blok)}>
{posts.map(post => (
<li>
<time>{post.date}</time>
<a href={post.slug}>{post.title}</a>
<p>{post.description}</p>
</li>
))}
</ul>

Enfin, ajoutez vos composants à la propriété components de l’objet de configuration storyblok dans astro.config.mjs. La clé est le nom du Blok dans Storyblok, et la valeur est le chemin vers le composant relatif à src.

astro.config.mjs
import { defineConfig } from 'astro/config';
import storyblok from '@storyblok/astro';
import { loadEnv } from 'vite';
const env = loadEnv("", process.cwd(), 'STORYBLOK');
export default defineConfig({
integrations: [
storyblok({
accessToken: env.STORYBLOK_TOKEN,
components: {
blogPost: 'storyblok/BlogPost',
blogPostList: 'storyblok/BlogPostList',
page: 'storyblok/Page',
},
apiOptions: {
region: 'us',
},
})
],
});

Pour créer une route pour une page spécifique, vous pouvez récupérer son contenu directement à partir de l’API Storyblok et le passer au composant StoryblokComponent. N’oubliez pas de vous assurer que vous avez ajouté le composant Page à votre astro.config.mjs.

Créez un fichier index.astro dans src/pages/ pour rendre la page home :

src/pages/index.astro
---
import { useStoryblokApi } from '@storyblok/astro'
import StoryblokComponent from '@storyblok/astro/StoryblokComponent.astro'
import BaseLayout from '../layouts/BaseLayout.astro'
const storyblokApi = useStoryblokApi();
const { data } = await storyblokApi.get('cdn/stories/home', {
version: import.meta.env.DEV ? "draft" : "published",
});
const content = data.story.content;
---
<html lang="en">
<head>
<title>Storyblok & Astro</title>
</head>
<body>
<StoryblokComponent blok={content} />
</body>
</html>

Pour générer des pages pour tous les articles de votre blog, créez une page .astro qui créera des routes dynamiques. Cette approche varie selon que vous utilisez la génération de site statique (par défaut) ou le rendu côté serveur.

Si vous utilisez la génération de site statique par défaut d’Astro, vous utiliserez les routes dynamiques et la fonction getStaticPaths pour générer les pages de votre projet.

Créez un nouveau répertoire src/pages/blog/ et ajoutez un nouveau fichier appelé [...slug].astro avec le code suivant :

src/pages/blog/[...slug].astro
---
import { useStoryblokApi } from '@storyblok/astro'
import StoryblokComponent from '@storyblok/astro/StoryblokComponent.astro'
export async function getStaticPaths() {
const sbApi = useStoryblokApi();
const { data } = await sbApi.get("cdn/stories", {
content_type: "blogPost",
version: import.meta.env.DEV ? "draft" : "published",
});
const stories = Object.values(data.stories);
return stories.map((story) => {
return {
params: { slug: story.slug },
};
});
}
const sbApi = useStoryblokApi();
const { slug } = Astro.params;
const { data } = await sbApi.get(`cdn/stories/blog/${slug}`, {
version: import.meta.env.DEV ? "draft" : "published",
});
const story = data.story;
---
<html lang="en">
<head>
<title>Storyblok & Astro</title>
</head>
<body>
<StoryblokComponent blok={story.content} />
</body>
</html>

Ce fichier génère une page pour chaque story, avec le titre et le contenu récupérés de l’API Storyblok.

Si vous avez opté pour le mode SSR, vous utiliserez des routes dynamiques pour récupérer les données des pages de Storyblok.

Créez un nouveau répertoire src/pages/blog/ et ajoutez un nouveau fichier appelé [...slug].astro avec le code suivant :

src/pages/blog/[...slug].astro
---
import { useStoryblokApi } from '@storyblok/astro'
import StoryblokComponent from '@storyblok/astro/StoryblokComponent.astro'
const storyblokApi = useStoryblokApi()
const slug = Astro.params.slug;
let content;
try {
const { data } = await storyblokApi.get(`cdn/stories/blog/${slug}`, {
version: import.meta.env.DEV ? "draft" : "published",
});
content = data.story.content
} catch (error) {
return Astro.redirect('/404')
}
---
<html lang="en">
<head>
<title>Storyblok & Astro</title>
</head>
<body>
<StoryblokComponent blok={content} />
</body>
</html>

Ce fichier va chercher et rendre les données de la page de Storyblok qui correspondent au paramètre dynamique slug.

Puisque vous utilisez une redirection vers /404, créez une page 404 dans src/pages :

src/pages/404.astro
<html lang="fr">
<head>
<title>Non trouvé</title>
</head>
<body>
<p>Désolé, cette page n'existe pas.</p>
</body>
</html>

Si la story n’est pas trouvée, la demande sera redirigée vers la page 404.

Pour déployer votre site, consultez nos guides de déploiement et suivez les instructions de votre hébergeur préféré.

Reconstruction sur les changements de Storyblok

Titre de la section Reconstruction sur les changements de Storyblok

Si votre projet utilise le mode statique par défaut d’Astro, vous devrez configurer un webhook pour déclencher une nouvelle construction lorsque votre contenu change. Si vous utilisez Netlify ou Vercel comme hébergeur, vous pouvez utiliser sa fonction webhook pour déclencher une nouvelle compilation à partir des événements Storyblok.

Pour configurer un webhook dans Netlify :

  1. Allez sur le tableau de bord de votre site et cliquez sur Build & deploy.

  2. Sous l’onglet Continuous Deployment, trouvez la section Build hooks et cliquez sur Add build hook.

  3. Donnez un nom à votre webhook et sélectionnez la branche sur laquelle vous souhaitez déclencher la construction. Cliquez sur Save et copiez l’URL générée.

Pour configurer un webhook dans Vercel :

  1. Allez sur le tableau de bord de votre projet et cliquez sur Settings.

  2. Sous l’onglet Git, trouvez la section Deploy hooks.

  3. Donnez un nom à votre webhook et indiquez la branche sur laquelle vous souhaitez déclencher la construction. Cliquez sur Add et copiez l’URL générée.

Dans votre espace Storyblok Settings, cliquez sur l’onglet Webhooks. Collez l’URL du webhook que vous avez copié dans le champ Story published & unpublished et cliquez sur Save pour créer un webhook.

Désormais, chaque fois que vous publierez un nouvel article, une nouvelle construction sera déclenchée et votre blog sera mis à jour.

Plus de guides sur les CMS