Intégrer Strapi sur Nuxt
Publié le 28 janvier 2024
C’est quoi Strapi ?
Strapi est un CMS headless, ce qui vous permet de créer votre propre API et de le diffuser sans avoir de contraintes.
Strapi
Un CMS headless open-source pour créer et diffuser votre contenu partout.
Backend avec Strapi
Installation de Strapi
Avant d’installer le CMS, veuillez vous prémunir de Node.js v20.
npx create-strapi-app@latest my-project
Ou avec yarn :
yarn create strapi-app my-project --quickstart
Avec cette commande, vous allez suivre un simple process pour l’installer. Rien de plus simple. Pour la suite, nous utilisons SQLite (par défaut) dans cet exemple, mais libre à vous d’installer ce que vous voulez en base de donnée.
thomasbnt@thomasbnt:~/lab$ yarn create strapi-app my-project --quickstart
yarn create v1.22.19
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Installed "create-strapi-app@4.19.0" with binaries:
- create-strapi-app
Creating a quickstart project.
Creating a new Strapi application at /lab/my-project.
Creating files.
Dependencies installed successfully.
Initialized a git repository.
Your application was created at /lab/my-project.
Available commands in your project:
yarn develop
Start Strapi in watch mode. (Changes in Strapi project files will trigger a server restart)
yarn start
Start Strapi without watch mode.
yarn build
Build Strapi admin panel.
yarn strapi
Display all available commands.
You can start by doing:
cd /lab/my-project
yarn develop
Running your Strapi application.
> my-project@0.1.0 develop
> strapi develop
⠋ Building build context
⠙ Building build context[INFO] Including the following ENV variables as part of the JS bundle:
- ADMIN_PATH
- STRAPI_ADMIN_BACKEND_URL
- STRAPI_TELEMETRY_DISABLED
✔ Building build context (100ms)
✔ Creating admin (10071ms)
⠸ Loading Strapi[2024-01-27 18:49:09.061] info: The Users & Permissions plugin automatically generated a jwt secret and stored it in .env under the name JWT_SECRET.
✔ Loading Strapi (2075ms)
✔ Generating types (320ms)
Project information
┌────────────────────┬──────────────────────────────────────────────────┐
│ Time │ Sat Jan 27 2024 18:49:10 GMT+0100 (Central Euro… │
│ Launched in │ 2405 ms │
│ Environment │ development │
│ Process PID │ 19885 │
│ Version │ 4.19.0 (node v20.2.0) │
│ Edition │ Community │
│ Database │ sqlite │
└────────────────────┴──────────────────────────────────────────────────┘
Actions available
One more thing...
Create your first administrator 💻 by going to the administration panel at:
┌─────────────────────────────┐
│ http://localhost:1337/admin │
└─────────────────────────────┘
[2024-01-27 18:49:11.419] http: GET /admin (12 ms) 200
[2024-01-27 18:49:11.454] http: GET /admin/runtime~main.b145af60.js (6 ms) 200
[2024-01-27 18:49:11.463] http: GET /admin/main.5eaa19e8.js (2 ms) 200
[2024-01-27 18:49:11.827] http: GET /admin/project-type (2 ms) 200
[2024-01-27 18:49:11.846] http: GET /admin/6707.d7b87269.chunk.js (2 ms) 200
[2024-01-27 18:49:11.983] http: GET /admin/6538.27d4c381.chunk.js (3 ms) 200
[2024-01-27 18:49:11.984] http: GET /admin/9719.fe70b828.chunk.js (2 ms) 200
[2024-01-27 18:49:11.984] http: GET /admin/1025.2d854ef2.chunk.js (2 ms) 200
[2024-01-27 18:49:11.989] http: GET /admin/5019.0d8113a1.chunk.js (3 ms) 200
[2024-01-27 18:49:11.990] http: GET /admin/4944.c9cc5f7f.chunk.js (3 ms) 200
[2024-01-27 18:49:11.991] http: GET /admin/9170.6aa61d26.chunk.js (3 ms) 200
[2024-01-27 18:49:11.994] http: GET /admin/1727.8847f948.chunk.js (1 ms) 200
[2024-01-27 18:49:12.048] http: POST /admin/renew-token (9 ms) 400
[2024-01-27 18:49:12.051] http: GET /admin/init (16 ms) 200
[2024-01-27 18:49:12.054] http: GET /admin/users/me (18 ms) 401
[2024-01-27 18:49:12.144] http: GET /admin/3067.4f4141cb.chunk.js (1 ms) 200
[2024-01-27 18:49:12.149] http: GET /admin/telemetry-properties (2 ms) 401
[2024-01-27 18:49:12.354] http: GET /admin (2 ms) 200
[2024-01-27 18:49:12.588] http: GET /admin/project-type (1 ms) 200
[2024-01-27 18:49:12.686] http: GET /admin/init (2 ms) 200
[2024-01-27 18:49:12.811] http: GET /favicon.ico (0 ms) 200
Vous avez toute la documentation de disponible.
Après avoir tout installé ainsi que les dépendances, le serveur se lance automatiquement comme vous pouvez le voir juste au-dessus. Cependant, si cela n’a pas été exécuté, faites yarn develop
.
Créer votre compte sur le dashboard
Quand vous allez sur http://localhost:1337 pour la première fois, on vous demandera de créer un compte Super Admin.
Youhou ! Vous avez accès à Strapi ! ✨🚀
Création de la Collection
Dans cet exemple, nous allons créer une collection pour afficher les dernières mises à jour d’un robot Discord, comme ça, on pourra l’afficher où on le souhaite, dans ce cas-là, sur le site web sous Nuxt mais aussi avec une commande Slash sur la plateforme Discord à travers le robot !
Allons dans Content-Type Builder → Collections Types → Create new collection type.
Nous allons lui donner un nom propre "ChangelogMrRobotApp” (Ici Mr. Robot fait référence au nom du robot). Puis créer des champs “fields” en cliquant sur le bouton Add new field.
Dans mon cas, je veux simplement afficher :
- Le titre
- La version
- La date de release
- Le contenu de la version (content)
- Le slug
- Et une bannière, mais qui est optionnelle
Puis, nous remplissons tous ces champs dans l’onglet Content Manager. Et nous pourrons passer au front !
Intégration sur le front sous Nuxt
Je prends Nuxt pour la partie front, car le site web du robot est sous ce framework. Mais libre à vous de l’arranger comme bon vous semble. Ce n’est qu’une requête fetch et du JavaScript.
Création du token API
Avant de continuer sur le code, nous allons créer un Token API, Settings → API Tokens → Add new API Token. Ce que nous voulons, c’est simplement GET la Collection, sans avoir d’autres permissions. Il nous permettra de récupérer les informations depuis l’API. Ce token devrait être privé.
- Token type en “Read-only”
- Token duration en “Unlimited”
- Et permissions seulement sur “find” et “findOne” sur la Collection
Récupération des données avec les call API
Maintenant, nous allons pouvoir récupérer depuis l’API de Strapi les données de la Collection. Ayant un contenu sous Markdown, nous devons procéder à une étape en plus, celle de transformer le texte markdown en HTML. Pour ce faire, j’utilise le paquet markdown-it
.
Première fonction : Récupérer la data depuis l’API
Tout simplement avec useFetch
de Nuxt. On récupère notre data, et on peut la mettre dans une ref.
const config = useRuntimeConfig();
let changelogs = ref([]);
await useFetch(`${config.public.backendStrapiUrl}changelogs-mr-robot-app?populate=*&sort[0]=version:desc`, {
headers: {
Authorization: `Bearer ${config.public.backendStrapiPublicAPIToken}`
}
}).then((response) => {
changelogs = response.data._value;
});
- Ici,
backendStrapiUrl
contient l’URL de Strapi avec l’API endpoint pour récupérer la Collection des changelogs, en populate (voir ce que c’est le populate) et trié en fonction de la version en descendant. - Et
backendStrapiPublicAPIToken
comme son nom l’indique est votre Token !
On obtient bien un tableau avec tout ce qu’on souhaite. Magie !
Transformer le contenu (content) du Markdown → HTML
Avec markdown-it
, nous allons pouvoir faire encore plus de magie. Installez le paquet, et ajoutez-le dans le component/page.
import MarkdownIt from "markdown-it";
const md = new MarkdownIt();
changelogs.data.forEach((changelog) => {
changelog.attributes.content = md.render(changelog.attributes.content);
});
function formatDate(date) {
const options = { year: "numeric", month: "long", day: "numeric" };
return new Date(date).toLocaleDateString("fr", options);
}
J’ai ajouté une fonction en plus nommé formatDate
, elle permet tout simplement de mettre la date au bon format.
Résultat sur une page
Et maintenant… (roulement de tambours)… il faut intégrer cette partie dans votre corps HTML !
<article v-for="l in changelogs.data" :key="l.id" v-show="changelogs">
<NuxtLink :to="'#' + l.attributes.slug">
<h3 class="changelog_title" v-if="l.attributes.title" :id="l.attributes.slug">{{ l.attributes.title }}</h3>
</NuxtLink>
<div class="changelog_infos">
<div
v-if="l.attributes.releasedAt">
<Icon name="lucide:calendar" />
Sorti le {{ formatDate(l.attributes.releasedAt) }}
</div>
—
<div v-if="l.attributes.version">v.{{ l.attributes.version }}</div>
</div>
<div v-html="l.attributes.content" v-if="l.attributes.content"></div>
</article>
Avec un peu de CSS, on rend ça avec style, et voici le résultat !
Cette page web est disponible sur mrrobot.app/changelog si vous êtes curieux. 🚀
Conclusion
J'ai découvert Strapi, il y a pas mal de temps. Et je n'avais rien créé avec, jusqu'à que j'ai eu un projet, où j'ai je l'ai proposé. Depuis, je l'aime beaucoup. Pour sa facilité d'utilisation, sa documentation, sa gestion d'API, et surtout, sa simplicité d'intégration avec n'importe quel framework.
Publié le 28 janvier 2024