Articles de blog traduits vides avec le déploiement basé sur un manifeste
Le Problème
Après le déploiement sur Cloudflare, les articles de blog traduits (espagnol, allemand, français, etc.) se chargeaient de manière aléatoire avec un contenu vide. Parfois, cela fonctionnait bien, parfois non. La page se rendait, mais le contenu était manquant.
Qu'est-ce qu'un Fichier Manifeste ?
Mes articles de blog sont stockés sous forme de fichiers JSON dans la base de code, et non dans une base de données. Cela me permet d'écrire le contenu dans mon éditeur et de tout suivre dans Git. Simple.
Un fichier manifeste est un fichier JSON pré-généré qui contient toutes les données des articles de blog. Les Workers Cloudflare n'ont pas accès à un système de fichiers traditionnel au moment de l'exécution ; ils ne peuvent utiliser que les fichiers regroupés lors de la construction. Ainsi, au lieu de lire les fichiers d'articles individuels à l'exécution, le processus de construction crée un manifeste unique contenant tous les articles.
Le manifeste est généré au moment de la construction et inclus dans le déploiement. À l'exécution, le code lit à partir de ce manifeste au lieu du système de fichiers.
La Cause
La structure de mon manifeste ressemble à ceci :
{
"slug": "mon-article",
"translatedSlugs": {
"en": "my-post",
"es": "mi-publicacion"
},
"localized": {
"es": { "title": "...", "content": "..." },
"de": { "title": "...", "content": "..." }
}
}
Remarquez : l'anglais n'est PAS dans l'objet localized
. Le contenu anglais se trouve au niveau de base.
Ma fonction getPostByTranslatedSlug
faisait ceci :
// Obtenir l'article avec la locale anglaise pour accéder aux translatedSlugs
const post = getPostBySlug(slug, 'en');
// Vérifier si les translatedSlugs correspondent...
if (post.translatedSlugs[someLocale] === translatedSlug) {
return getPostBySlug(slug, requestedLocale);
}
Lorsque j'appelais getPostBySlug(slug, 'en')
, il essayait d'accéder à manifest.localized.en
, ce qui n'existe pas, et retournait donc un contenu vide.
La Solution
Au lieu d'appeler getPostBySlug(slug, 'en')
, j'ai changé pour utiliser getAllPosts()
qui retourne tous les articles avec les métadonnées de base, y compris translatedSlugs
:
export function getPostByTranslatedSlug(translatedSlug: string, locale: string): BlogPost | null {
// Obtenir tous les articles pour accéder aux métadonnées de base
const allPosts = getAllPosts();
for (const post of allPosts) {
if (post.translatedSlugs) {
for (const [lang, slugValue] of Object.entries(post.translatedSlugs)) {
if (slugValue === translatedSlug) {
// Trouvé ! Maintenant, obtenir la version localisée
return getPostBySlug(post.slug, locale);
}
}
}
}
return null;
}
Utiliser un Fichier Manifeste est-il une Bonne Pratique ?
Cela dépend de votre cible de déploiement :
Pour les Workers Cloudflare / Plateformes Edge : Oui, c'est nécessaire. Ces plateformes n'ont pas accès à un système de fichiers traditionnel, vous devez donc regrouper toutes les données au moment de la construction.
Pour les serveurs Node.js traditionnels (Vercel, AWS, etc.) : Non requis. Vous pouvez lire à partir du système de fichiers au moment de l'exécution, ce qui est plus simple et ne nécessite pas d'étape de construction pour générer le manifeste.
Le compromis : les fichiers manifestes ajoutent de la complexité à votre processus de construction et peuvent causer des bugs comme celui-ci s'ils ne sont pas structurés avec soin. Mais ils permettent le déploiement sur des plateformes edge qui sont plus rapides et moins coûteuses.
Leçon Apprise
Lors de l'utilisation d'un manifeste pour des exportations statiques :
- Ne supposez pas que la locale de base existe dans
localized
- Les métadonnées de base (comme
translatedSlugs
) se trouvent au niveau racine - Seules les locales non-base se trouvent dans
localized