Leere übersetzte Blogbeiträge bei manifestbasierter Bereitstellung
Das Problem
Nach dem Deployment auf Cloudflare wurden übersetzte Blogbeiträge (Spanisch, Deutsch, Französisch usw.) zufällig ohne Inhalt geladen. Manchmal funktionierten sie einwandfrei, manchmal nicht. Die Seite wurde gerendert, aber der Inhalt fehlte.
Was ist eine Manifestdatei?
Meine Blogbeiträge werden als JSON-Dateien im Code gespeichert, nicht in einer Datenbank. Das ermöglicht es mir, Inhalte in meinem Editor zu schreiben und alles in Git zu verfolgen. Einfach.
Eine Manifestdatei ist eine vorab generierte JSON-Datei, die alle Blogbeitragsdaten enthält. Cloudflare Workers haben zur Laufzeit keinen Zugriff auf ein traditionelles Dateisystem; sie können nur Dateien verwenden, die während des Builds gebündelt wurden. Anstatt also zur Laufzeit einzelne Blogbeitragsdateien zu lesen, erstellt der Build-Prozess ein einziges Manifest mit allen Beiträgen.
Das Manifest wird zur Build-Zeit generiert und in das Deployment aufgenommen. Zur Laufzeit liest der Code aus diesem Manifest anstelle des Dateisystems.
Die Ursache
Meine Manifeststruktur sieht wie folgt aus:
{
"slug": "mein-beitrag",
"translatedSlugs": {
"en": "my-post",
"es": "mi-publicacion"
},
"localized": {
"es": { "title": "...", "content": "..." },
"de": { "title": "...", "content": "..." }
}
}
Beachten Sie: Englisch ist NICHT im localized
-Objekt enthalten. Der englische Inhalt befindet sich auf der Basisebene.
Meine Funktion getPostByTranslatedSlug
tat Folgendes:
// Den Beitrag mit englischer Locale abrufen, um auf translatedSlugs zuzugreifen
const post = getPostBySlug(slug, 'en');
// Prüfen, ob translatedSlugs übereinstimmen...
if (post.translatedSlugs[someLocale] === translatedSlug) {
return getPostBySlug(slug, requestedLocale);
}
Als ich getPostBySlug(slug, 'en')
aufrief, versuchte es, auf manifest.localized.en
zuzugreifen, was nicht existiert, und gab daher leeren Inhalt zurück.
Die Lösung
Anstatt getPostBySlug(slug, 'en')
aufzurufen, habe ich es geändert, um getAllPosts()
zu verwenden, was alle Beiträge mit Basis-Metadaten einschließlich translatedSlugs
zurückgibt:
export function getPostByTranslatedSlug(translatedSlug: string, locale: string): BlogPost | null {
// Alle Beiträge abrufen, um auf Basis-Metadaten zuzugreifen
const allPosts = getAllPosts();
for (const post of allPosts) {
if (post.translatedSlugs) {
for (const [lang, slugValue] of Object.entries(post.translatedSlugs)) {
if (slugValue === translatedSlug) {
// Gefunden! Nun die lokalisierte Version abrufen
return getPostBySlug(post.slug, locale);
}
}
}
}
return null;
}
Ist die Verwendung einer Manifestdatei eine gute Vorgehensweise?
Das hängt von Ihrem Deployment-Ziel ab:
Für Cloudflare Workers / Edge-Plattformen: Ja, es ist notwendig. Diese Plattformen haben keinen Zugriff auf ein traditionelles Dateisystem, daher müssen Sie alle Daten zur Build-Zeit bündeln.
Für traditionelle Node.js-Server (Vercel, AWS usw.): Nicht erforderlich. Sie können zur Laufzeit aus dem Dateisystem lesen, was einfacher ist und keinen Build-Schritt zur Generierung des Manifests erfordert.
Der Kompromiss: Manifestdateien erhöhen die Komplexität Ihres Build-Prozesses und können, wenn sie nicht sorgfältig strukturiert sind, zu Fehlern wie diesem führen. Sie ermöglichen jedoch das Deployment auf Edge-Plattformen, die schneller und kostengünstiger sind.
Gelernte Lektion
Bei der Verwendung eines Manifests für statische Exporte gilt:
- Gehen Sie nicht davon aus, dass die Basis-Locale in
localized
vorhanden ist - Basis-Metadaten (wie
translatedSlugs
) befinden sich auf der Stammebene - Nur Nicht-Basis-Locales sind in
localized
enthalten