Artikel
Gunakan bahagian hadapan tulen untuk mencipta blog berbilang bahasa "dinamik + artikel".
Saya menjadikan tapak web saya sebagai blog berbilang bahasa "dinamik + artikel": kandungan diurus dengan Markdown, terjemahan selesai apabila disiarkan, halaman statik dijana semasa pembinaan dan penyemak imbas bertanggungjawab untuk membaca dan menukar bahasa. Artikel ini menguraikan model kandungan, saluran paip yang dikongsi, pertukaran antara pemuatan atas permintaan dan SEO, dan apa sebenarnya yang disimpan oleh bahagian hadapan tulen.
· 8 minit bacaan
Saya berharap laman web saya boleh digunakan untuk mencatat perenggan pemikiran, atau untuk menulis isu teknikal yang lengkap dengan jelas. Letakkan "dinamik" dalam yang pendek dan "artikel" dalam yang panjang. Kedua-duanya boleh dipautkan antara satu sama lain, dan apabila pelawat menukar bahasa, kandungan juga mesti ditukar bersama.
Keperluan ini kelihatan sangat biasa, tetapi jika anda menambah pangkalan data, bahagian belakang dan API kandungan dari awal, dan kemudian mengendalikan versi setiap bahasa, ia akan menjadi produk lain yang memerlukan penyelenggaraan jangka panjang tidak lama lagi.
Saya memilih untuk mengecilkan dahulu keperluan kepada perkara yang benar-benar boleh saya gunakan: **Seorang pengarang, masukkan kandungan ke dalam Git dan bina semula tapak web selepas diterbitkan. Pembaca hanya memerlukan fail statik dan penyemak imbas. ** Ini ialah struktur "dinamik + artikel" semasa stephen.taipei.
Bahagian hadapan tulen merujuk kepada hujung bacaan#
Mari kita jelaskan sempadannya terlebih dahulu. Projek ini menggunakan React, Vite dan Tailwind. Node.js masih diperlukan untuk pemprosesan kandungan, penukaran imej dan penciptaan skrip; terjemahan juga akan memanggil perkhidmatan luar semasa peringkat penerbitan. Selepas penggunaan, fail statik disediakan oleh Nginx.
Jadi apa yang saya maksudkan dengan bahagian hadapan tulen ialah apabila pembaca membuka tapak web, mereka tidak memerlukan bahagian belakang Blog khas untuk mencari maklumat, halaman kumpulan atau menterjemah dalam masa nyata. Ia mempunyai proses binaan dan hos, tetapi tiada API aplikasi atau pangkalan data yang berterusan untuk membaca artikel.
Jika kerja dilakukan lebih awal, akhir bacaan akan menjadi lebih mudah.
Berita dan artikel berkongsi sumber yang sama, masing-masing mempunyai modelnya sendiri#
Kandungan tertumpu dalam content/, dan teks asal adalah semua Markdown. Kedua-dua kandungan itu tidak disarung kasut ke dalam format yang sama:
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
Dinamik adalah kad pendek. Nama fail menggunakan minit waktu Taipei sebagai ID. Ia boleh ditandakan dengan idea, pembelajaran, dalam talian, menipu atau membaca. Ia boleh diwujudkan dengan hanya menulis perenggan tanpa perlu memikirkan tajuk setiap masa. Peringatan akan muncul jika melebihi 500 patah perkataan, dan ia harus diubah menjadi artikel jika melebihi 1,000 patah perkataan.
Artikel mempunyai slug tetap, tajuk, abstrak, tarikh, dan juga boleh mempunyai masa perlindungan dan kemas kini. URL tidak akan ditukar selepas ia didedahkan kepada umum untuk mengelakkan pautan kongsi asal daripada menjadi tidak sah.
Kedua-duanya berkaitan menggunakan article:. Untuk kemas kini, anda boleh menulis soalan dahulu dan kemudian memaut ke artikel lengkap; halaman artikel akan menyenaraikan kemas kini yang merujuknya secara terbalik. Kandungan pendek mengekalkan titik permulaan semasa, dan kandungan panjang bertanggungjawab untuk menamatkan terbitan. Tidak perlu menyiarkan teks penuh yang sama pada kedua-dua belah pihak.
Biarkan peraturan kandungan menyekat ralat sebelum membina#
Jika Markdown hanya dilemparkan ke dalam gambar, banyak masalah tidak akan dilihat sehingga selepas ia disiarkan secara langsung: tarikh yang salah, artikel tidak bersambung, imej tanpa alt atau topik yang sama ditulis dengan tiga tag yang serupa.
Saya meletakkan peraturan ini ke dalam saluran paip kandungan yang dikongsi. loadContent Baca fail, semak medan dengan Zod, dan kemudian proses Markdown, imej, bahasa dan hubungan kandungan. Kedua-dua pemeriksaan CLI dan pembinaan Vite menggunakan saluran paip ini untuk mengurangkan jurang antara "mesin tempatan mengatakan ia berfungsi, tetapi persekitaran rasmi tidak."
Tag hanya menerima tags.yaml kunci berdaftar; artikel yang dirujuk secara dinamik dan dinamik lain mesti wujud; pratonton tempatan boleh membaca draf, dan binaan rasmi akan mengecualikan draf. Peraturan ini tidak berdasarkan mengingatinya semasa menyiarkan, tetapi ia benar-benar menyekat pemeriksaan.
Markdown juga mempunyai sempadan output yang jelas: raw HTML tidak dikeluarkan secara langsung, HTML yang dijana dibersihkan, dan blok kod diserlahkan semasa build. Imej kandungan yang dirujuk melalui laluan relatif setempat ditukar kepada WebP dengan lebar maksimum 1600px, dan metadata EXIF termasuk data GPS dibuang. Artikel, kad dan pratonton perkongsian menggunakan imej yang telah diproses. Imej jauh serta imej yang dirujuk melalui laluan mutlak dari root tidak melalui proses penukaran setempat ini.
Kos sistem berbilang bahasa akan dibayar semasa menerbitkan artikel.#
Laman web pada masa ini menyokong 22 bahasa. Teks Cina Tradisional asal ditulis sekali, dan tajuk, abstrak, teks dan penerangan gambar bagi 21 bahasa lain disimpan dalam locales.yaml di sebelahnya.
Inilah keputusan yang saya ambil berat: **Pembaca tidak perlu menunggu terjemahan. ** content:localize Hasilkan terjemahan apabila menyiarkan. Binaan rasmi hanya membaca fail sedia ada dan tidak memanggil perkhidmatan terjemahan sekali lagi setiap kali ia digunakan.
Gunakan ringkasan sumber untuk membandingkan teks asal dan teks terjemahan. Jika teks asal ditukar, terjemahan lama tidak lagi boleh dianggap sebagai versi terkini; jika satu keluarga bahasa hilang atau terjemahan sudah lapuk, content:check akan gagal. Proses terjemahan melindungi kod, kod sebaris dan sasaran pautan daripada menterjemah pengecam teknikal atau URL.
Ini tidak bermakna terjemahan automatik mempunyai kualiti penyuntingan manusia. Ia menangani kesempurnaan dan konsistensi yang dikemas kini, dan bahasa dan nada profesional masih memerlukan pembacaan pruf. Teks asal yang tidak diubah akan mengekalkan terjemahan sedia ada dan teks yang diubah suai secara manual tidak akan ditimpa dengan dijalankan semula.
Baca abstrak dalam senarai, klik untuk memuatkan artikel#
Selepas kandungan ditambah, jika halaman utama memuatkan teks penuh setiap artikel dan setiap keluarga bahasa, bahagian hadapan tulen akan menjadi sangat perlahan.
Vite plugin membahagikan kandungan kepada tiga titik masuk: virtual:content/latest untuk halaman utama, virtual:content/index untuk halaman kandungan dan virtual:content/article/<slug> yang berasingan bagi setiap artikel. Halaman utama memaparkan tiga catatan terkini dan tiga kad artikel. Data catatan masih mengandungi teks penuh serta terjemahannya; kad hanya memendekkan paparan. Kad artikel panjang hanya membawa ringkasan dan data berkaitan, manakala isi penuhnya dimuatkan mengikut artikel melalui dynamic import.
Suspense React bertanggungjawab untuk menunggu teks, dan sempadan ralat luar bertanggungjawab untuk memaparkan mesej kegagalan pemuatan. Apabila permintaan teks gagal, tajuk, abstrak dan navigasi halaman kekal.
Terdapat juga pertukaran di sini: pada masa ini, terdapat satu ketulan teks setiap artikel, yang mengandungi terjemahan setiap keluarga bahasa, dan ia belum lagi dipecahkan kepada satu ketulan bagi setiap keluarga bahasa. Teks penuh dinamik dan terjemahan dimasukkan ke dalam indeks kandungan. Apabila volum kandungan terus meningkat, saiz indeks dan bilangan muat turun teks berbilang bahasa adalah langkah seterusnya yang perlu diukur.
Mesti ada pensuisan bahagian hadapan dan pintu masuk untuk bacaan statik.#
Kami hanya melakukan SPA, dan apabila kami berkongsi, kami selalunya hanya melihat tajuk dan gambar di laman utama. Ini tidak mencukupi untuk artikel itu.
Oleh itu, apabila menyediakan, setiap URL dinamik, artikel dan teg mempunyai cangkerang HTML sendiri, yang mengandungi tajuk, perihalan, kanonik, Graf Terbuka dan JSON-LD, dan teks asal yang boleh dibaca diletakkan dalam noscript. Anda boleh mendapatkan kandungan dan kulit eksklusif artikel ini tanpa melaksanakan JavaScript.
Kandungan yang sama juga akan menghasilkan feed.xml, sitemap-content.xml, versi Markdown artikel dan indeks artikel untuk llms.txt. Ini adalah produk terbina, bukan satu lagi set kandungan yang memerlukan penyegerakan manual.
Walau bagaimanapun, sempadan SEO berbilang bahasa juga mesti dijelaskan: **Pada masa ini, kemas kini dan artikel berkongsi URL yang sama dalam setiap bahasa, dan bahasa itu ditukar oleh bahagian hadapan; halaman kandungan statik, suapan dan versi Markdown mengekalkan teks asal. ** Halaman utama juga mempunyai prapemarahan untuk bahasa dan mod terang dan gelap. Ini tidak bermakna bahawa setiap artikel juga mempunyai 22 halaman bahasa yang boleh diindeks secara bebas.
Jika anda perlu membenarkan setiap keluarga bahasa disertakan oleh enjin carian pada masa hadapan, anda perlu menambah penghalaan keluarga bahasa, halaman statik dan hreflang yang sepadan. Itu satu lagi keperluan yang masih belum dipenuhi oleh set ini.
Pengeposan juga merupakan proses penghantaran#
Proses penerbitan saya ialah: tulis teks asal, hasilkan terjemahan, semak kandungan, serahkan kepada Git, dan kemudian gabungkannya ke dalam main. Tindakan GitHub yang sedia ada akan membina semula tapak web dan menggunakannya.
npm run content:localize
npm run content:check
npm run test:content
npm run build
Jika semua bahasa belum lengkap, saya lengkapkan terjemahan yang tertinggal dahulu. Artikel yang masih berupa draf kekal dalam pratonton setempat. Output produksi turut memastikan halaman draf tiada dan mengimbas artifak awam utama seperti feed, sitemap, halaman utama dan bundle JavaScript untuk mencari penanda draf. Seperti kod, kandungan mempunyai diff dan sejarah versi, serta boleh dipulihkan bersama-sama.
Kaedah ini mengorbankan kemas kini masa nyata: jika anda menukar sekeping teks, anda perlu menunggu untuk penempatan. Tetapi untuk tapak web teknikal saya, saya bersedia menukar penantian ini sebagai pertukaran untuk mengurangkan satu bahagian belakang, mengurangkan satu pergantungan tempoh pelaksanaan dan rekod perubahan yang lebih mudah untuk dijejaki.
Bilakah sesuai untuk melakukan ini?#
Jika anda seorang pengarang, kekerapan penyiaran boleh dibina semula, kandungannya terutamanya teks, dan anda sudah biasa dengan Git, seni bina ini sangat sesuai. Kemas kini pendek menurunkan ambang penulisan, artikel mengekalkan terbitan lengkap dan berbilang bahasa membolehkan kandungan yang sama dibaca oleh lebih ramai orang.
Jika keperluan menjadi kerjasama masa nyata antara berbilang orang, pengurusan kebenaran, ulasan pembaca, log masuk atau langganan, maka CMS dan bahagian belakang perlu dinilai semula. Bahagian hadapan yang tulen tidak akan membuatkan keperluan ini hilang secara automatik, tetapi saya belum meletakkannya ke dalam skop blog ini pada masa ini.
Prinsip reka bentuk kali ini sangat hampir dengan apa yang saya tulis dalam Corak Reka Bentuk Seni Bina Berbilang Susun Atur dan Tema: mula-mula pisahkan tanggungjawab dengan jelas, dan kemudian biarkan peraturan yang dikongsi mengekalkan konsistensi.
Untuk laman web ini, perkara utama adalah untuk membolehkan saya terus menulis dan mengetahui kandungan yang sebenarnya disampaikan setiap kali saya menerbitkan.