Nicolas Leport - Blog personnel
Il ne peut plus rien nous arriver d'affreux maintenant
– Red is dead, La cité de la peur
  Temps de lecture estimé : 21 min
Un site performant et (presque) totalement gratuit ? C'est possible !

Un site performant et (presque) totalement gratuit ? C'est possible !

Derrière ce titre accrocheur, une réalité. Nous verrons ici comment conjuguer gratuité et performance sans négliger le tooling, le déploiement continu, la stabilité et la sécurité de l'ensemble. Let's goooo !

Disclaimer : cet article ne mesurera pas l'impact énergétique de la solution ni la sobriété numérique de l'ensemble. Ce n'est pas une stack éco-responsable. Ce sujet fera l'objet de publications et d'expérimentations futures. Maintenant on peut commencer.

Une stack pourtant pas nouvelle mais qui est à la mode depuis quelque temps, je suis sûr que vous avez deviné... je parle bien sûr de la JAMSTACK ! Derrière cet acronyme accrocheur, une signification : Javascript API Markup STACK. C'est ce dont nous allons parler dans cet article.

Résultat final

Le site en ligne : nkcreation.com

Et parce que je n'ai rien à cacher à part mes variables d'environnement, tout le code est ouvert et disponible aux adresse suivantes :

Le dépôt GitHub du site : nkCreation/nkcreation.com

Le dépôt GitHub du CMS : nkCreation/apinkcreation-directus

Un peu d'histoire

Ceux qui fréquentent ce blog depuis un moment (et je sais que vous êtes nombreux, si si) le savent : j'avais commencé un article sur les applications isomorphiques. Rien que pour le nom je trouvais ça énormément stylé. Entre temps l'eau a coulé et de nouvelles choses sont arrivées sur plus ou moins les mêmes stack et mes différentes missions m'ont amené sur d'autres horizons techniques et je n'ai jamais pris le temps de finir cet article pour la simple et bonne raison qu'il était un peu trop ambitieux, car la stack était plus compliquée...

De VueJS avec Nuxt et Directus je suis passé à React avec Gatsby et Strapi puis Netlify CMS (stack actuelle du blog) pour enfin revenir à Nuxt et Directus car 90% de mon temps professionnel aujourd'hui est rempli de VueJS.

Prérequis

  • Une connaissance de Git, et une clé SSH paramétrée.
  • Un compte sur GitHub, Heroku , AWS et Netlify.
  • Un gestionnaire de mot de passe, c'est mieux qu'un bloc note.
  • Savoir lire l'anglais (et oui).
  • Avoir du temps (un peu) devant soi.

Petit tour technique du propriétaire

Nous en avons déjà évoqué un bout dans le chapitre précédent mais en gros, voici ce que nous allons faire : un site web administrable grâce à un CMS. Rien de bien sorcier jusque là et pourtant, nous allons faire tout ce qu'il faut pour faire des trucs compliqués qui feront super bien une fois que vous mettrez tout ça sur votre CV 🤓.

Pour ça, nous allons développer notre site internet avec NuxtJS, qui le générera côté serveur pour créer des pages HTML totalement statiques - ce qui sera bénéfique pour le référencement - grâce à une API issue de Directus, un headless CMS écrit en NodeJS. Ce site sera hébergé sur Netlify, un CDN - vu que ce ne sera que des pages HTML classiques (enfin pas tout à fait, nous verrons après) - et le CMS sera lui hébergé sur Heroku avec des addons PostgreSQL et Redis. Les fichiers seront stockés sur un bucket S3 chez AWS. Le tout disponible en public sur GitHub et sa CI magique : les GitHub Actions.

Architecture schema

Ça donne envie hein ?

Première étape : le CMS

Nous allons commencer avec le CMS, comme ça nous pourrons brancher directement la génération du site dessus quand nous le développerons.

Stack en local

Si vous souhaitez utiliser Directus en local vous devrez créer une base de données. Étant sur macOS je ne pourrai pas vous conseiller pour Windows mais pour macOS c'est très simple, il faut d'abord installer HomeBrew.

Base de données

Nous allons installer Postgres et créer l'utilisateur et sa base de données associée. Je vous conseille de créer un utilisateur par application et une base qui va avec.

brew install postgresql

Ensuite, pour le user et la base :

createuser [username] --createdb -P
createdb [databasename] -U [username]

Notez bien le mot de passe que vous choisissez et le nom de la base, vous en aurez besoin pour la suite.

Directus CMS

Pour créer une application Directus, c'est très simple il suffit d'exécuter la commande ci-dessous, en pensant à remplacer my-awesome-projet par le nom de votre projet. Pour plus d'informations n'hésitez pas à consulter le quickstart guide très bien fait sur leur site.

npx create-directus-project my-awesome-projet

Cet utilitaire va vous demander diverses informations, notamment celles sur la base de données qu'on aura créée juste au dessus.

Sans plus attendre, nous allons dès maintenant ajouter dans un fichier .gitignore les lignes suivantes :

.env
node_modules
uploads

Cela nous évitera de pousser par erreur le fichier d'environnement dans lequel il y a tous les secrets disponibles au bon fonctionnement de l'application, ainsi que tous les fichiers que l'on uploadera dans le CMS sur notre machine.

Dépot Git

Une fois fait, vous pouvez créer un dépôt sur GitHub en mode public et suivre les informations données dans la section push an existing folder. C'est sensiblement quelque chose comme ça :

git init
git branch -M main
git add .
git commit -m "Initial commit"
git remote add origin [your_github_url_or_SSH_repository_link]
git push -u origin main

Déploiement sur Heroku

Pourquoi Heroku ? et bien car le premier plan de tarification ne coûte rien et que ça suffira largement pour notre usage. Certes ce n'est pas le plus performant mais vous verrez ensuite que l'API ne sera pas utilisée par les visiteurs du site web mais uniquement au build, donc pas de soucis de performance de ce côté là...

Vous allez devoir créer une nouvelle application sur Heroku et choisir un petit nom mignon et la région qui va bien.

Une fois créée il faut la connecter avec GitHub et choisir le dépot précédemment créé. Vous pouvez choisir la branche à déployer et paramétrer le déploiement automatique au push, ce que je vous conseille de faire.

Les addons : base de données et cache.

Nous allons utiliser PostgreSQL sur notre application. Pour cela, rendez-vous dans l'onglet Resources de votre application sur Heroku et chercher l'addon Heroku Postgres. Ajoutez le. Puis l'addon Heroku Redis.

Ces addons ajouteront dans les variables d'environnement de votre application les informations de connexion à leur services. Ces informations pourront changer dans le temps et nous n'aurons pas besoin de modifier notre application pour que ça reste fonctionnel. Hourra.

Les variables d'environnement

Pour que notre application fonctionne, il va falloir dire à Directus ce qu'il faut faire. Afin de simplifier la chose nous allons ajouter dans notre application un fichier à la racine nommé directus.config.js. Ce fichier va faire du mapping entre les variables du PATH et les valeur que Directus veut lire.

module.exports = {
  DB_CONNECTION_STRING:
    (process.env.DB_CONNECTION_STRING || process.env.DATABASE_URL) +
    "?ssl=true&sslmode=no-verify",
  ACCESS_TOKEN_TTL: process.env.ACCESS_TOKEN_TTL,
  ADMIN_EMAIL: process.env.ADMIN_EMAIL,
  ADMIN_PASSWORD: process.env.ADMIN_PASSWORD,
  CACHE_REDIS: process.env.CACHE_REDIS || process.env.REDIS_URL,
  CACHE_ENABLED: process.env.CACHE_ENABLED,
  CACHE_NAMESPACE: process.env.CACHE_NAMESPACE,
  CACHE_AUTO_PURGE: process.env.CACHE_AUTO_PURGE,
  CACHE_STORE: process.env.CACHE_STORE,
  CONFIG_PATH: process.env.CONFIG_PATH,
  DB_CLIENT: process.env.DB_CLIENT,
  EXTENSIONS_PATH: process.env.EXTENSIONS_PATH,
  NODE_ENV: process.env.NODE_ENV,
  PUBLIC_URL: process.env.PUBLIC_URL,
  RATE_LIMITER_REDIS: process.env.RATE_LIMITER_REDIS || process.env.REDIS_URL,
  RATE_LIMITER_DURATION: process.env.RATE_LIMITER_DURATION,
  RATE_LIMITER_ENABLED: process.env.RATE_LIMITER_ENABLED,
  RATE_LIMITER_KEY_PREFIX: process.env.RATE_LIMITER_KEY_PREFIX,
  RATE_LIMITER_POINTS: process.env.RATE_LIMITER_POINTS,
  RATE_LIMITER_STORE: process.env.RATE_LIMITER_STORE,
  REFRESH_TOKEN_COOKIE_NAME: process.env.REFRESH_TOKEN_COOKIE_NAME,
  REFRESH_TOKEN_COOKIE_SAME_SITE: process.env.REFRESH_TOKEN_COOKIE_SAME_SITE,
  REFRESH_TOKEN_TTL: process.env.REFRESH_TOKEN_TTL,
  STORAGE_LOCATIONS: process.env.STORAGE_LOCATIONS,
  STORAGE_S3_BUCKET: process.env.STORAGE_S3_BUCKET,
  STORAGE_S3_DRIVER: process.env.STORAGE_S3_DRIVER,
  STORAGE_S3_ENDPOINT: process.env.STORAGE_S3_ENDPOINT,
  STORAGE_S3_REGION: process.env.STORAGE_S3_REGION,
  TZ: process.env.TZ,
}

Le petit trick ici est le ?ssl=true&sslmode=no-verify à la fin de l'URL, nécessaire pour que Heroku puisse se connecter à la BDD Postgres.

Si jamais il vous manque une variable d'environnement, n'oubliez pas de l'ajouter dans ce fichier après l'avoir ajoutée dans Heroku. Vous ne pourrez pas dire que vous ne le saviez pas.

Maintenant, il faut remplir tout ça 😱 direction les Settings de notre application Heroku, puis dans Config Vars cliquer sur Reveal Config Vars. Vous noterez que certaines sont présentes, n'y touchez pas.

Certaines sont très importantes :

  • ADMIN_EMAIL sera l'email de connexion à Directus du compte Admin.
  • ADMIN_PASSWORD ai-je vraiment besoin d'expliquer ?
  • CONFIG_PATH le lien vers le fichier JS qu'on vient de créer pour que Directus puisse lire notre configuration.
  • DB_CLIENT à bien mettre à pg sinon vous vous demanderez pourquoi rien ne marche.

Voici une partie de la configuration que j'ai mise, n'hésitez pas à modifier les valeurs, tout est expliqué dans la doc de Directus.

ACCESS_TOKEN_TTL                              20m
ADMIN_EMAIL                                   [your_email]
ADMIN_PASSWORD                                [password]
CACHE_AUTO_PURGE                              true
CACHE_ENABLED                                 true
CACHE_NAMESPACE                               cache
CACHE_STORE                                   redis
CONFIG_PATH                                   /app/directus.config.js
DB_CLIENT                                     pg
EXTENSIONS_PATH                               /app/extensions
KEY                                           [key, mettez celle de votre application locale dans le fichier .env]
NODE_ENV                                      production
PGSSLMODE                                     no-verify
PUBLIC_URL                                    /
RATE_LIMITER_DURATION                         1
RATE_LIMITER_ENABLED                          true
RATE_LIMITER_KEY_PREFIX                       rate-limitter
RATE_LIMITER_POINTS                           30
RATE_LIMITER_STORE                            redis
REFRESH_TOKEN_COOKIE_NAME                     directus_refresh_token
REFRESH_TOKEN_COOKIE_SAME_SITE                lax
REFRESH_TOKEN_TTL                             7d
SECRET                                        [idem que la KEY]
STORAGE_LOCATIONS                             s3
STORAGE_S3_BUCKET                             [nom du bucket S3, on verra plus tard]
STORAGE_S3_DRIVER                             s3
STORAGE_S3_ENDPOINT                           s3.amazonaws.com
STORAGE_S3_KEY                                [nous verrons dans la section S3]
STORAGE_S3_REGION                             [region de votre bucket]
STORAGE_S3_SECRET                             [nous verrons dans la section S3]
TZ                                            Europe/Paris

Le démarrage de l'application

Nous allons ensuite devoir créer ce qu'Heroku appelle des Dynos pour lancer l'application. Pour ce faire, ajoutez un fichier nommé Procfile sans extension à la racine de votre application et mettez dedans :

release: npx directus bootstrap
web: npx directus start

La première ligne servira lors des mises à jour de Directus, elle jouera les migrations de la base de données si le schéma change dans le core de Directus. La deuxième permet de lancer l'application, c'est aussi simple que ça.

Le stockage des fichiers sur AWS

Prochaine et dernière étape pour la partie CMS, le stockage des fichiers uploadés. En l'état l'application peut et doit déjà pouvoir se lancer mais vous ne pourrez pas télécharger des fichiers dans le CMS.

Création du bucket

Pour ce faire, connectez-vous sur AWS et rendez-vous dans l'interface de gestion des buckets. Créer un bucket - compartiment en français - et choisissez lui un petit nom. Pas besoin de mettre l'accès aux objets en publique, vous pouvez laisser les réglages tels qu'ils sont.

Pensez à remplir dans Heroku - Settings de votre application les variables STORAGE_S3_BUCKET et STORAGE_S3_REGION par ce que vous avez choisi.

Clé d'accès pour AWS

Notre bucket est créé, nous allons générer une clé d'accès pour que Directus puisse streamer les fichiers depuis le S3. Rendez-vous sur la page des clés d'accès dans l'IAM AWS et créez une clé pour Directus.

Notez bien les informations et reportez les dans les variables d'environnement associées STORAGE_S3_KEY et STORAGE_S3_SECRET.

Votre CMS est maintenant prêt et vous pouvez y accéder via l'URL fournie par Heroku. Simple comme bonjour, non ?

That was easy

Deuxième étape : le site web.

Nous allons maintenant créer le site web qui utilisera cette API. Je ne rentrerai pas dans les détails de comment créer un site web ou comment paramétrer vos pages, je vous donnerai simplement un exemple de comment est configuré mon projet pour que vous puissiez vous inspirer. L'important ici est le branchement de notre API dans Nuxt !

Création du projet Nuxt

Placez-vous dans votre répertoire de travail et lancer la commande npm init nuxt-app [your-nuxt-app-name]. Il vous demandera quelques questions concernant vos préférences de développement, voici ce que j'aurai tendance à choisir par défaut :

✨  Generating Nuxt.js project in your-nuxt-app-name
? Project name: your-nuxt-app-name
? Programming language: JavaScript
? Package manager: Npm
? UI framework: None
? Nuxt.js modules: Axios - Promise based HTTP client, Progressive Web App (PWA)
? Linting tools: ESLint, Prettier
? Testing framework: Jest
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Static (Static/Jamstack hosting)
? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript)
? Continuous integration: GitHub Actions (GitHub only)
? What is your GitHub username? your-github-username
? Version control system: Git

L'important ici est de bien choisir "Static" dans le deployment target pour utiliser Netlify CDN ensuite. Vous remarquerez si vous allez dans le dépôt de mon site que j'ai choisi Typescript. C'est historique et je ne recommande pas spécialement d'utiliser TS avec Vue 2 (et Nuxt 2).

Si vous avez un doute, n'hésitez pas à aller voir la doc de Nuxt, très bien faite, à cette adresse.

Une fois fait, vous pouvez suivre les informations qui sont output dans votre terminal et lancer votre appli ! 🤘

Ajout de l'API Directus à la configuration

Maintenant que votre appli fonctionne nous allons brancher tout ça. Premièrement, créez un fichier .env s'il n'existe pas déjà dans votre répertoire et ajoutez-y une ligne concernant votre url d'API. Ensuite reportez cette valeur dans le nuxt.config.js. Par exemple :

# file .env

API_URL="https://[your-api-name-on-heroku].herokuapp.com/"
// file nuxt.config.js

export default {
  // env object : add this on top of the exported object.
  env: {
    apiUrl: process.env.API_URL,
  },
  // [...]
}

Prenez l'habitude de faire ça pour tout ce qui est spécifique à votre projet (URL API, Token, API KEY, etc...). Cela permet d'éviter de mettre des secrets en clair dans votre dépôt GitHub et surtout de réutiliser l'application branchée sur une autre URL d'API par exemple si vous avez plusieurs environnements (prod, preprod, staging, int...)

BONUS : Création d'une collection sur Directus

Un exemple d'utilisation de votre API pourrait être de générer des pages à la volée (comme pour un blog par exemple) avec un slug. Je ferai certainement un article dédié à ça plus tard, mais pour le moment on va faire quelque chose de simple : une collection singleton qui permettra de modifier un message sur la page d'accueil du site. Simple, efficace, utile, pratique.

  1. Connectez-vous à votre admin et allez dans la section Settings à gauche (la roue crantée) puis dans Data Model et créez un nouvel item, que j'appellerai ici Hero.
  2. Cochez la case Treat as single object dans la section Singleton.
  3. Choisissez par un Primary Key Field id de type Generated UUID. Cela évitera que l'API soit prévisible si quelqu'un en vient à trouver l'URL (/1, /2, etc...)
  4. Ajoutez un champ title de type Text en cliquant sur + Create Field. Vous pouvez choisir dans Interface l'option Textarea, cela permettra de gérer des retours à la ligne par exemple (qu'on transformera avec une regex dans le code).

🎉 Vous avez créé une collection ! Maintenant, il faut la rendre visible. Pour ça direction les Settings toujours mais cette fois dans Roles & Permissions puis dans Public. Ici il faut cocher l'oeil dans votre collection pour rendre accessible via l'API vos données.

Vous pouvez également cliquer sur System Collections et ensuite rendre visible via l'oeil la section Directus Files. Sinon les photos uploadées dans vos collections ne seront pas accessible (et donc pas intégrable dans une balise <img /> par exemple).

Il ne vous reste plus qu'à remplir votre champ title.

Utilisation de l'API dans l'app

Directus est un super projet et, en plus de fournir une API Rest, il fournit aussi une API GraphQL. Nous allons l'utiliser ici car vous verrez par la suite que si vous requêtez plusieurs collections ça va devenir verbeux. Pour ça nous allons utiliser nuxt-graphql-request, qui va nous permettre d'utiliser des Query GraphQL dans notre application.

Si vous ne connaissez pas GraphQL, n'hésitez pas à vous rendre sur le site How to GraphQL qui est très bien fait et permet de prendre en main rapidement et de comprendre l'intérêt de l'outil. Et si vous souhaitez en savoir toujours plus, vous pouvez aussi participer à une formation GraphQL donnée par moi-même ou mes collègues de Zenika. #instantpub

npm install nuxt-graphql-request graphql --save-dev
npm install --save graphql-tag

Et ensuite on ajoute la configuration nécessaire dans le nuxt.config.js à savoir une entrée nuxt-graphql-request dans le tableau buildModules et la configuration GraphQL nécessaire au fonctionnement :

export default {
  // [...]
  // Modules for dev and build (recommended) (https://go.nuxtjs.dev/config-modules)
  buildModules: [
    'nuxt-graphql-request',
    // [...]
  ],
  graphql: {
    clients: {
      default: {
        endpoint: process.env.API_URL + 'graphql',
      },
    },
  },
  // [...]
}

Remarquez ici l'utilisation encore une fois de notre variable d'environnement.

Maintenant il ne nous reste plus qu'à faire une requête et afficher le résultat ! Rendez-vous dans le fichier pages/index.vue et collez-y le code suivant.

<template>
  <div>
    <h1 v-html="title"></h1>
  </div>
</template>

<script>
import { gql } from 'graphql-tag'

export default {
  async asyncData({ $graphql }) {
    const query = gql`
      query homeData {
        hero {
          title
        }
      }
    `

    const { hero } = await $graphql.default.request(query)

    return {
      title: hero.title.replace(/\n/g, '<br />'),
    }
  },
}
</script>

Décomposons un peu tout ça.

La partie <template> est assez simple, elle affiche dans un <h1> du HTML provenant de la variable title de notre composant Vue.

La partie <script> est notre composant Vue, ici chargée en tant que Page Nuxt. Afin de charger les données côté serveur nous utilisons un hook custom à Nuxt qui ne sera pas appelé côté client et qui permet de faire quelque chose de vraiment complètement statique une fois la génération faite. Ce hook est asyncData qui est - comme son nom l'indique - asynchrone.

Ce hook met à disposition en paramètre un contexte contenant diverses choses. Ici, je décompose le paramètre avec la syntaxe de décomposition et ne récupère que l'objet $graphql qui se trouve dans l'objet de contexte.

Nous créons ensuite dans cette méthode une query GraphQL en appelant la méthode gql importée du paquet correspondant. Ici c'est de la syntaxe GraphQL de base et on indique à notre API vouloir récupérer le champ title de notre collection hero.

Si vous avez appelez votre collection différemment n'oubliez pas de changer le nom de la collection appelée. C'est ici tout l'intérêt de GraphQL, ne sélectionner que les champs voulus et utiles pour notre application.

Nous appelons notre api avec en paramètre notre query en décomposant la sortie (qui a la même structure que l'entrée) puis nous retournons les valeurs souhaitées en fin de fonction. Ces valeurs seront fusionnées avec celles de la propriété data du composant Vue. La petite astuce ici consiste à remplacer les \n de notre champ de type textarea par des <br /> afin de mettre des retours à la ligne valides en HTML.

Tadaaa ! Notre application est maintenant branchée sur notre CMS !

Plugged in

Déploiement sur Netlify

Nous avons dorénavant un CMS et une application Nuxt qui génère un site statique... C'est bien beau tout ça mais ça se met où ? Plusieurs choix s'offrent à nous mais pour la démo nous utiliserons Netlify.

Netlify fonctionnera de notre côté en CDN : nous lui enverrons nos pages HTML et nos images, et il offrira ce contenu à nos utilisateurs. Il offre quelques fonctionnalités fort sympathiques en se branchant sur notre dépôt GitHub telles que le déploiement continu, des prévisualisations lorsqu'on crée des Pull Request et la gestion des formulaires pour par exemple recevoir un message lorsque quelqu'un en remplit un. Pratique.

Une fois inscrit sur Netlify connectez-vous et dans la section Sites cliquez sur New site from git pour créer un site depuis votre dépôt. De là nous avons un formulaire à remplir :

  1. Choisissez le provider GitHub;
  2. Après l'autorisation d'accès, cherchez votre dépôt précédemment créé et sélectionnez-le;
  3. Choisissez la branche à déployer à savoir main dans notre cas;
  4. Changez ensuite la commande de build pour npm run generate au lieu de npm run build;
  5. Laissez le répertoire de sortie sur dist;
  6. Cliquez sur Deploy et Netlify lancera une installation et déploiera votre site sur un nom de domaine à lui.

Après la pipeline, vous aurez accès à votre site sur la page d'accueil de votre espace Netlify 🚀.

Nom de domaine

Supposons que vous ayez fait l'acquisition d'un nom de domaine pour votre super site qui n'affiche qu'un titre, vous pouvez l'ajouter en tant que domaine principal sur Netlify à la place du nom aléatoire fourni par ce dernier.

Dans un premier temps il s'agira d'ajouter un champ de type CNAME dans votre table de DNS sur votre registrar.

OVH est un bon registrar pour les noms de domaines et l'interface de gestion des DNS est pas trop mal fichue. Vous avez en prime la recette habituelle avec des emails associés au domaine acquis.

Chez OVH par exemple, c'est dans la section Web Cloud du menu supérieur puis dans Noms de domaines > Votre domaine > Zone DNS. Cliquez ensuite sur Ajouter une entrée puis ajoutez un champ type CNAME. Il devrait vous afficher un exemple de cette forme :

www IN CNAME [unique-app-name-id].netlify.com.

Pour vérifier la propagation de vos DNS vous pouvez utiliser WhatsMyDNS

Ensuite, rendez-vous dans la section Site settings sur Netlify puis dans Domain Management et enfin cliquez sur Add domain alias, renseignez votre URL puis cliquez sur Save.

Gestion des images

En allant plus loin dans l'utilisation de cette stack vous serez certainement confronté à une problématique d'image : rappelez-vous, notre CMS hébergé sur Heroku est automatiquement Shutdown après un certain temps, ce qui rendrait nos images inaccessibles sur notre site web, vu qu'elles pointent sur le CMS... Qu'à cela ne tienne, il existe un plugin pour Nuxt nommé nuxt-image-extractor qui permettra de parser nos fichiers HTML générés, de télécharger toutes les images externes, de les ajouter dans un dossier puis de changer les balises src dans les fichiers HTML précédemment parcourus. Nice.

On commence par installer le plugin :

npm i nuxt-image-extractor

Puis on le paramètre dans le fichier nuxt.config.js :

export default {
  // [...]
  // Modules for dev and build (recommended) (https://go.nuxtjs.dev/config-modules)
  modules: [
    [
      'nuxt-image-extractor',
      {
        baseUrl: process.env.API_URL,
        path: '/_images',
      },
    ],
    // [...]
  ],
  // [...]
}

N'hésitez pas à regarder les options disponibles sur la doc du plugin.

Directus par défaut nous propose d'afficher nos images sans extension de fichier ce qui provoque le non-fonctionnement du plugin que l'on vient d'installer. Pour corriger ça, soit vous forkez le plugin soit vous forcez Directus à ajouter des extensions. Nous allons opter pour ce second choix et utiliser la clé filename_disk de l'asset Directus plutôt que son ID (dans le cas ou le nom du fichier n'est pas changé). Voir la documentation.

Dernière étape : pour aller plus loin

Vous êtes arrivés jusqu'ici : toutes mes félicitations. Ce n'était pas simple. Mais maintenant, vous vous ennuyez et je comprends...

Quelques pistes d'améliorations :

  • Paramétrez Nuxt pour générer des pages dynamiquement : pour des articles de blog, nous n'allons pas créer un fichier par article dans le dossier pages, ça n'a pas de sens. Nous allons plutôt utiliser un slug et de la génération dynamique.
  • Ajoutez des tests sur votre application Nuxt, car les tests c'est bien 👌
  • Utilisez les GitHub Actions pour lancer les tests puis un npm run generate à chaque pull request, histoire d'être sur que vous n'enverrez pas de 💩 en production.
  • Pimpez Directus en lui ajoutant des plugins, comme par l'exemple l'excellent EditorJS pour gérer le contenu de vos pages. Voir son implémentation dans Directus

Conclusion

Merci d'avoir eu la patience de lire l'article jusqu'au bout et j'espère que ces informations ont été utiles. Si vous avez la moindre question n'hésitez pas à me contacter je me ferai un plaisir de vous répondre.

Keep rockin' 🤘

Thank you

Et un grand merci à tous mes collègues adorés pour les différentes relectures. 🙏

Sommaire