Ky blog lindi në italisht. Kur shtova gjashtë gjuhët e tjera — anglisht, shqip, portugalisht, spanjisht, frëngjisht dhe gjermanisht — përkthimi i teksteve ishte pjesa e lehtë. Pjesa e vështirë ishte gjithçka tjetër: URL-të, lidhjet e ndara tashmë, motorët e kërkimit dhe një përkthim automatik që dukej se funksiononte, por në fakt e prishte përmbajtjen në heshtje.
Problemi: një URL italisht për shtatë gjuhë
Në fillim çdo artikull kishte një slug të vetëm, atë italisht. Rezultati ishin adresa si /de/blog/perche-il-blog-non-viene-indicizzato: një faqe në gjermanisht me URL në italisht. E shëmtuar për t'u ndarë, e paqartë për lexuesin dhe një humbje për SEO-në, sepse fjalët në URL kanë rëndësi.
Modeli i të dhënave: një artikull, shtatë gjuhë
Zgjodha të mbaj një dokument të vetëm për çdo artikull, me fusha për çdo gjuhë: title_en, content_de, slug_fr e kështu me radhë. Alternativa ishte një dokument për çdo përkthim, por atëherë do të më duhej të mbaja të sinkronizuara etiketat, shikimet dhe statusin e publikimit në shtatë kopje. Me një dokument të vetëm, artikulli mbetet një gjë e vetme.
Slug-e të përkthyera që nuk ndryshojnë kurrë
Çdo slug për gjuhë gjenerohet vetëm një herë, nga titulli i përkthyer, dhe më pas nuk preket më, as kur e korrigjoj titullin: një URL e ndarë tashmë duhet të vazhdojë të funksionojë. Për më tepër, çdo slug duhet të jetë unik mes të gjitha fushave të të gjithë artikujve, që një adresë të çojë gjithmonë te një artikull i vetëm, nga cilado gjuhë të vijë:
// Fill slug_xx from the translated title, only where it's missing.
// Existing slugs are never touched: they're in URLs people have shared.
for (const lang of ['en', 'sq', 'pt', 'es', 'fr', 'de']) {
if (post[`slug_${lang}`]) continue;
const title = post[`title_${lang}`];
if (title?.trim()) {
post[`slug_${lang}`] = await ensureUniqueSlug(title); // unique across ALL slug fields
}
}
Lidhjet e vjetra vazhdojnë të funksionojnë
Para slug-eve të përkthyera, shumë lidhje ishin ndarë tashmë në formën /sq/blog/slug-italisht. T'i prishja do të thoshte faqe 404 dhe sinjale negative për Google. Prandaj build-i e gjeneron çdo artikull edhe me slug-un italisht nën çdo prefiks gjuhe, me canonical-in që tregon versionin e përkthyer: kush vjen nga lidhja e vjetër sheh faqen e duhur, dhe Google e di cila adresë është ajo zyrtare.
SEO për çdo gjuhë
- hreflang në çdo faqe, që lidh mes tyre shtatë versionet e të njëjtit artikull.
- og:locale dinamik, që parapamjet në rrjetet sociale të tregojnë gjuhën, titullin dhe përshkrimin e saktë.
- Sitemap me të gjitha versionet, e përditësuar automatikisht në çdo publikim.
- Faqe të prerenderizuara për çdo gjuhë: pa to, Google shihte vetëm guaskën e aplikacionit, siç e kam treguar në këtë artikull.
Përkthimi automatik që prishte kodin
Për të përkthyer pa prekur HTML-në, zëvendësoja etiketat dhe blloqet e kodit me shenja zëvendësuese, ia dërgoja tekstin përkthyesit dhe pastaj i rivendosja të gjitha. Funksiononte pothuajse gjithmonë. Por kur disa shenja ishin afër njëra-tjetrës — tipike për artikujt me shumë blloqe kodi — përkthyesi ndonjëherë dyfishonte njërën dhe humbiste një tjetër. Nuk ishte gabim i rastësishëm: duke e rinisur, përsëritej identik, sidomos në shqip.
Zgjidhja ishte të mos ia dërgoja fare shenjat përkthyesit: e ndaj tekstin te shenjat dhe përkthej vetëm copat e prozës. Më shumë thirrje, por asnjë mundësi që një shenjë të ndryshohet:
// Split on the placeholders: the translator never sees them
const parts = text.split(/(✦\d+✦)/);
const out = [];
for (const part of parts) {
out.push(/^✦\d+✦$/.test(part) ? part : await translate(part, lang));
}
return out.join('');
Dhe që atëherë, pas çdo përkthimi, e krahasoj strukturën e çdo gjuhe me atë italisht — i njëjti numër titujsh, paragrafësh, tabelash dhe blloqesh kodi — pa iu besuar "asnjë gabimi" që raporton skripti.
Në përmbledhje
Një blog shumëgjuhësh nuk është një blog me një përkthyes të ngjitur: duhen një model i qartë të dhënash, URL të qëndrueshme për çdo gjuhë, lidhje të vjetra që nuk prishen dhe kontrolle automatike mbi përkthimin. Janë të njëjtat zgjedhje që propozoj kur një klient do një faqe në disa gjuhë. Nëse është rasti yt, më shkruaj.