Artikel
Verwenden Sie ein reines Frontend, um ein mehrsprachiges Blog mit „Dynamik + Artikeln“ zu erstellen
Ich habe meine Website in einen mehrsprachigen Blog mit „Dynamik + Artikeln“ umgewandelt: Der Inhalt wird mit Markdown verwaltet, die Übersetzung wird beim Posten abgeschlossen, statische Seiten werden während der Erstellung generiert und der Browser ist für das Lesen und Wechseln der Sprachen verantwortlich. In diesem Artikel werden das Inhaltsmodell, gemeinsame Pipelines, Kompromisse zwischen On-Demand-Laden und SEO sowie die genauen Einsparungen durch das reine Frontend erläutert.
· 8 Min. Lesezeit
Ich hoffe, dass meine Website dazu genutzt werden kann, einen Gedankenabsatz niederzuschreiben oder ein komplettes technisches Problem klar und deutlich aufzuschreiben. Schreiben Sie „Dynamik“ in die kurze und „Artikel“ in die lange. Beides kann miteinander verknüpft werden, und wenn der Besucher die Sprache wechselt, muss auch der Inhalt gemeinsam umgeschaltet werden.
Diese Anforderung scheint sehr gewöhnlich zu sein, aber wenn Sie von Anfang an eine Datenbank, ein Backend und eine Inhalts-API hinzufügen und dann die Versionen jeder Sprache verwalten, wird es bald zu einem weiteren Produkt, das eine langfristige Wartung erfordert.
Ich habe mich entschieden, die Anforderungen zunächst auf das zu beschränken, was ich wirklich nutzen kann: **Ein Autor, den Inhalt in Git eingeben und die Website nach der Veröffentlichung neu erstellen. Der Reader benötigt lediglich statische Dateien und einen Browser. ** Dies ist die aktuelle „dynamische + Artikel“-Struktur von stephen.taipei.
Reines Frontend bezieht sich auf das Leseende#
Lassen Sie uns zunächst die Grenzen klarstellen. Dieses Projekt verwendet React, Vite und Tailwind. Node.js wird weiterhin für die Inhaltsverarbeitung, Bildkonvertierung und Skripterstellung benötigt; Die Übersetzung wird während der Veröffentlichungsphase auch externe Dienste in Anspruch nehmen. Nach der Bereitstellung werden statische Dateien von Nginx bereitgestellt.
Mit reinem Frontend meine ich also, dass Leser, wenn sie die Website öffnen, kein spezielles Blog-Backend benötigen, um in Echtzeit nach Informationen zu suchen, Seiten zu gruppieren oder zu übersetzen. Es verfügt über einen Build-Prozess und einen Host, aber keine dauerhafte Anwendungs-API oder Datenbank zum Lesen von Artikeln.
Wenn die Arbeit im Voraus erledigt wird, wird das Leseende viel einfacher.
Nachrichten und Artikel haben dieselbe Quelle, jeder hat sein eigenes Modell#
Der Inhalt ist in content/ konzentriert und der Originaltext besteht ausschließlich aus Markdown. Die beiden Inhalte werden nicht in dasselbe Format gebracht:
content/
tags.yaml
tags.locales.yaml
notes/2026/20261004-0944.md
notes/2026/20261004-0944.locales.yaml
articles/frontend-only-multilingual-blog/
index.md
locales.yaml
cover.webp
Dynamik ist eine kurze Karte. Der Dateiname verwendet als ID die Minute der Taipei-Zeit. Es kann mit Ideen, Lernen, Online, Schummeln oder Lesen markiert werden. Dies kann durch einfaches Schreiben eines Absatzes erreicht werden, ohne sich jedes Mal einen Titel ausdenken zu müssen. Bei mehr als 500 Wörtern erscheint eine Erinnerung, bei mehr als 1.000 Wörtern sollte der Artikel in einen Artikel umgewandelt werden.
Artikel haben einen festen Slug, Titel, Abstract, Datum und können auch ein Cover und eine Aktualisierungszeit haben. Die URL wird nach der Veröffentlichung nicht geändert, um zu verhindern, dass der ursprünglich freigegebene Link ungültig wird.
Die beiden werden durch article: miteinander in Beziehung gesetzt. Für Updates können Sie zuerst die Frage aufschreiben und dann auf den vollständigen Artikel verlinken; Auf der Artikelseite werden die Aktualisierungen aufgelistet, die umgekehrt darauf verweisen. Der kurze Inhalt behält den aktuellen Startpunkt bei und der lange Inhalt ist für den Abschluss der Ableitung verantwortlich. Es ist nicht erforderlich, auf beiden Seiten denselben Volltext zu veröffentlichen.
Lassen Sie Inhaltsregeln Fehler vor dem Erstellen blockieren#
Wenn Markdown einfach ins Spiel gebracht würde, würden viele Probleme erst nach der Live-Schaltung sichtbar: falsche Daten, nicht verbundene Artikel, Bilder ohne Alts oder das gleiche Thema, das mit drei ähnlichen Tags geschrieben wird.
Ich habe diese Regeln in die Pipeline für freigegebene Inhalte eingefügt. loadContent Lesen Sie die Datei, überprüfen Sie die Felder mit Zod und verarbeiten Sie dann Markdown, Bilder, Sprache und Inhaltsbeziehungen. Sowohl die CLI-Inspektion als auch die Vite-Konstruktion verwenden diese Pipeline, um die Lücke zwischen „Der lokale Computer sagt, dass es funktioniert, die offizielle Umgebung funktioniert jedoch nicht“ zu verringern.
Der Tag akzeptiert nur tags.yaml registrierte Schlüssel; Es müssen dynamisch referenzierte Artikel und andere Dynamiken vorhanden sein. Die lokale Vorschau kann Entwürfe lesen und der offizielle Build schließt Entwürfe aus. Diese Regeln basieren nicht auf der Erinnerung an sie beim Posten, sondern blockieren tatsächlich Inspektionen.
Auch für Markdown gelten klare Ausgabegrenzen: Raw HTML wird nicht direkt ausgegeben, erzeugtes HTML wird bereinigt und Codeblöcke werden beim Build hervorgehoben. Inhaltsbilder, die über lokale relative Pfade eingebunden sind, werden in WebP mit maximal 1600px Breite umgewandelt; dabei werden EXIF-Metadaten einschließlich GPS-Daten entfernt. Artikel, Karten und Vorschauen zum Teilen verwenden dieselben aufbereiteten Bilder. Entfernte Bilder und Bilder mit absoluten Pfaden ab dem Stammverzeichnis durchlaufen diese lokale Umwandlung nicht.
Die Kosten für das mehrsprachige System werden bei Veröffentlichung des Artikels bezahlt.#
Die Website unterstützt derzeit 22 Sprachen. Der ursprüngliche traditionelle chinesische Text wird einmal geschrieben und die Titel, Zusammenfassungen, Text- und Bildbeschreibungen der anderen 21 Sprachen werden in der locales.yaml daneben gespeichert.
Hier ist eine Entscheidung, die mir am Herzen liegt: **Leser müssen nicht auf die Übersetzung warten. ** content:localize Übersetzungen beim Posten generieren. Der offizielle Build liest nur vorhandene Dateien und ruft den Übersetzungsdienst nicht bei jeder Bereitstellung erneut auf.
Verwenden Sie den Quellauszug, um den Originaltext und den übersetzten Text zu vergleichen. Bei einer Änderung des Originaltextes kann die alte Übersetzung nicht mehr als aktuelle Fassung angesehen werden; Wenn eine Sprachfamilie fehlt oder die Übersetzung veraltet ist, schlägt content:check fehl. Der Übersetzungsprozess schützt den Code, den Inline-Code und die Linkziele vor der Übersetzung technischer Identifikatoren oder URLs.
Dies bedeutet nicht, dass die automatische Übersetzung die Qualität einer menschlichen Bearbeitung hat. Es geht um Vollständigkeit und aktualisierte Konsistenz, und professionelle Sprache und Ton erfordern immer noch Korrekturlesen. Der Originaltext, der nicht geändert wurde, behält die vorhandene Übersetzung bei und der manuell geänderte Text wird durch eine erneute Ausführung nicht überschrieben.
Lesen Sie die Zusammenfassung in der Liste und klicken Sie, um den Artikel zu laden#
Wenn nach der Erweiterung des Inhalts die Homepage den vollständigen Text jedes Artikels und jeder Sprachfamilie lädt, ist das reine Front-End sehr langsam.
Das Vite-Plugin teilt die Inhalte in drei Einstiegspunkte auf: virtual:content/latest für die Startseite, virtual:content/index für Inhaltsseiten und ein eigenes virtual:content/article/<slug> für jeden Artikel. Auf der Startseite erscheinen die drei neuesten Kurzbeiträge und drei Artikelkarten. Die Kurzbeitragsdaten enthalten weiterhin den vollständigen Text und die Übersetzungen; auf der Karte wird die Anzeige lediglich gekürzt. Karten für längere Artikel enthalten nur Zusammenfassungen und zugehörige Daten. Der vollständige Text jedes Artikels wird per dynamic import separat geladen.
Suspense von React ist für das Warten auf den Text verantwortlich, und die äußere Fehlergrenze ist für die Anzeige der Meldung über einen Ladefehler verantwortlich. Wenn die Textanforderung fehlschlägt, bleiben Titel, Zusammenfassung und Seitennavigation erhalten.
Auch hier gibt es Kompromisse: Derzeit gibt es einen Textblock pro Artikel, der Übersetzungen für jede Sprachfamilie enthält, und dieser wurde noch nicht in einen Textblock pro Sprachfamilie aufgeteilt. Dynamische Volltexte und Übersetzungen werden in den Inhaltsindex eingetragen. Da das Inhaltsvolumen weiter zunimmt, sind die Indexgröße und die Anzahl der Downloads mehrsprachiger Texte die nächsten zu messenden Schritte.
Es muss eine Front-End-Umschaltung und ein Eingang zum statischen Lesen vorhanden sein.#
Wir machen nur SPA und wenn wir es teilen, sehen wir oft nur den Titel und das Bild auf der Homepage. Das reicht für den Artikel nicht aus.
Daher verfügt jede dynamische, Artikel- und Tag-URL beim Einrichten über eine eigene HTML-Shell, die Titel, Beschreibung, Kanonik, Open Graph und JSON-LD enthält, und der lesbare Originaltext wird in noscript platziert. Sie können den Inhalt und das exklusive Cover dieses Artikels erhalten, ohne JavaScript auszuführen.
Derselbe Inhalt erzeugt auch feed.xml, sitemap-content.xml, die Markdown-Version des Artikels und den Artikelindex für llms.txt. Hierbei handelt es sich um erstellte Produkte, nicht um weitere Inhalte, die eine manuelle Synchronisierung erfordern.
Allerdings müssen auch die Grenzen der mehrsprachigen SEO deutlich gemacht werden: **Derzeit haben Updates und Artikel in jeder Sprache die gleiche URL und die Sprache wird vom Frontend umgeschaltet; Statische Inhaltsseiten, Feeds und Markdown-Versionen behalten den Originaltext bei. ** Die Homepage verfügt außerdem über ein Pre-Rendering für Sprache sowie Hell- und Dunkelmodi. Dies bedeutet nicht, dass jeder Artikel auch über 22 unabhängig indexierbare Sprachseiten verfügt.
Wenn Sie in Zukunft zulassen möchten, dass jede Sprachfamilie von Suchmaschinen einbezogen wird, müssen Sie Sprachfamilien-Routing, entsprechende statische Seiten und Hreflang hinzufügen. Das ist eine weitere Anforderung, die dieses Set noch nicht erfüllt.
Auch das Posten ist ein Liefervorgang#
Mein Veröffentlichungsprozess besteht darin, den Originaltext zu schreiben, die Übersetzung zu erstellen, den Inhalt zu überprüfen, ihn an Git zu übermitteln und ihn dann in main zusammenzuführen. Vorhandene GitHub-Aktionen erstellen die Website neu und stellen sie bereit.
npm run content:localize
npm run content:check
npm run test:content
npm run build
Wenn noch Sprachen fehlen, ergänze ich zuerst die Übersetzungen. Artikel im Entwurfsstatus bleiben in der lokalen Vorschau. Die Produktionsausgabe prüft außerdem, dass keine Entwurfsseiten vorhanden sind, und durchsucht wichtige öffentliche Dateien wie Feed, Sitemap, Startseite und JavaScript-Bundles nach Entwurfsmarkierungen. Wie Code hat auch der Inhalt Diffs und eine Versionshistorie und kann gemeinsam mit ihm zurückgesetzt werden.
Diese Methode opfert Aktualisierungen in Echtzeit: Wenn Sie einen Text ändern, müssen Sie auf eine Bereitstellung warten. Aber für meine technische Website bin ich bereit, diese Wartezeit gegen ein Backend weniger, eine Abhängigkeit vom Ausführungszeitraum weniger und einen Änderungsdatensatz einzutauschen, der einfacher zu verfolgen ist.
Wann ist es angebracht, dies zu tun?#
Wenn Sie Autor sind, die Häufigkeit der Veröffentlichungen rekonstruiert werden kann, der Inhalt hauptsächlich aus Text besteht und Sie an Git gewöhnt sind, ist diese Architektur sehr gut geeignet. Kurze Aktualisierungen senken die Schreibschwelle, der Artikel behält seine vollständige Ableitung bei und die Mehrsprachigkeit ermöglicht es, dass derselbe Inhalt von mehr Menschen gelesen wird.
Wenn die Anforderungen Echtzeit-Zusammenarbeit zwischen mehreren Personen, Berechtigungsverwaltung, Leserkommentare, Anmeldung oder Abonnement umfassen, müssen das CMS und das Backend neu bewertet werden. Ein reines Frontend wird diese Anforderungen nicht automatisch verschwinden lassen, aber ich habe sie derzeit nicht in den Rahmen dieses Blogs aufgenommen.
Die Entwurfsprinzipien ähneln dieses Mal sehr dem, was ich in Architekturmuster für mehrere Layouts und Themes geschrieben habe: Trennen Sie zuerst die Verantwortlichkeiten klar und sorgen Sie dann dafür, dass gemeinsame Regeln die Konsistenz wahren.
Bei dieser Website geht es vor allem darum, dass ich bei jeder Veröffentlichung weiter schreiben kann und weiß, welche Inhalte tatsächlich bereitgestellt werden.