Skip to content
PN Scripts

Development

Building a multilingual website: URLs, hreflang and translation

  • PN Scripts Team
  • 7 min read

A multilingual website works when every language has its own stable URL, search engines are told which pages are translations of each other, and each version is written for its readers instead of translated word for word. In practice that means a language prefix or separate domain per language, hreflang annotations and self-referencing canonicals, locale-aware dates, numbers and plurals, and a CMS that lets editors manage each language without breaking the others. Only offer a language where the content actually exists in it.

#Give every language its own URL

Search engines index URLs, so each language version needs an address of its own. There are three common structures:

StructureExampleGood fit when
Subdirectoryexample.com/bg/One site, one team, shared hosting and domain authority. The simplest choice for most projects.
Subdomainbg.example.comLanguage versions run on separate systems or are managed by separate teams.
Country domainexample.bgYou target countries, not only languages, and want a strong local signal. Each domain must be registered and renewed.

Avoid two patterns. Query parameters such as ?lang=bg are easy to lose in links and harder to manage in search tools. Switching the language by cookie or browser setting alone, with the same URL for every language, means search engines see only one version, because crawlers generally visit without your cookies or language preferences.

Also avoid forced redirects based on the visitor's location or browser language. A Bulgarian speaker in Germany, or a tester using an English browser, should still reach the page they asked for. A small, dismissible banner suggesting another language is a friendlier option.

#Hreflang and canonical tags

Hreflang tells search engines that several URLs are the same page in different languages, so the right version can appear in each market. You can add it as <link rel="alternate" hreflang="..."> tags in the page head, in HTTP headers, or in the XML sitemap. A few rules matter more than the method:

  • Use correct codes. The value is a language code such as en or bg, optionally followed by a region, such as en-GB. A region on its own is not valid.
  • List every version on every version. Each page lists all its alternates, including itself. If the English page points to the Bulgarian one, the Bulgarian page must point back, or the annotation may be ignored.
  • Add x-default. It names the page to show when no language matches, often the language picker or the main language version.
  • Point only to pages that exist and return a normal response. Redirected or missing alternates weaken the whole set.

The canonical tag on each language version should point to itself. A common mistake is to point every translation's canonical to the English page, which tells search engines the translations are duplicates and can keep them out of results.

Set the lang attribute on the <html> element to the page's language as well. Screen readers use it to choose the right pronunciation, and browsers use it for hyphenation and translation prompts.

#Only advertise a language the content is written in

Many sites show a Bulgarian flag, a /bg/ URL and Bulgarian navigation, while the article body falls back to English because nobody translated it. To visitors this looks broken. To search engines it is a duplicate page with a misleading language label.

  • If a page has no translation, leave it out of that language's menus, sitemap and hreflang set, or show a clear note with a link to the version that exists.
  • Do not publish machine output as a finished translation. Use it as a draft for a person who writes the language natively.
  • Translate the whole page: titles, meta descriptions, image alt text, buttons, form errors and emails. A translated page with English validation messages still feels unfinished.

#Write natively instead of translating literally

A literal translation keeps the words and loses the meaning. Idioms, sentence length, formality and the terms people search for all differ between languages. Bulgarian readers, for example, expect the formal "вие" in business copy, and they search with Bulgarian phrases even for technical services.

Give translators context: what the page is for, who reads it, where each string appears and how long it may be. A short glossary of product terms and the words to keep in English saves many corrections. Ideally the native-language writer can restructure a paragraph when the original structure does not work in their language.

#Dates, currencies, plurals and slugs

Dates and numbers

The same date and amount look different in each locale. US English writes the month first, while Bulgarian and most of Europe put the day first. Decimal and thousands separators swap between a point and a comma, and the currency symbol may come before or after the amount. Format these with your platform's locale tools, such as Intl.DateTimeFormat and Intl.NumberFormat in JavaScript, or the intl extension in PHP, which use the Unicode CLDR data. Hand-written formats are where errors appear.

Currencies

Translating a page does not change its prices. Decide separately which currencies you show, where exchange rates come from and which amount is the one the customer pays. During the switch from leva to euro many Bulgarian shops show both. Our article on showing prices in leva and euro in PrestaShop covers one way to do it.

Plural rules

English and Bulgarian each have two plural forms, but many languages have more: Polish and Russian have several, and Arabic has six categories. Never build a sentence like count + " item" + "s". Use your framework's pluralization support or ICU message format, so each language can define its own forms.

Cyrillic or Latin slugs

A Cyrillic slug such as /блог/ is readable to Bulgarian visitors and works in modern browsers, but when it is copied into many emails, chat apps or documents it turns into percent-encoded text such as /%D0%B1%D0%BB%D0%BE%D0%B3/. Transliterated Latin slugs such as /blog/ or /uslugi/ stay short everywhere. If you transliterate Bulgarian, follow the official transliteration system consistently, for example "ж" as "zh" and "щ" as "sht". Either choice works for search. What matters is picking one rule and keeping each slug stable once it is published, with a redirect if you ever change it.

#Editor workflow in the CMS

A multilingual site is only as good as the process behind it. When choosing or building a CMS, check that it supports:

  • Separate fields per language for titles, body, slugs, SEO title and description, and alt text.
  • A visible translation status, so editors can see which pages are missing a language before publishing.
  • Publishing per language, so an English update can go live without exposing an unfinished translation.
  • Clear fallback rules that you choose deliberately, instead of silently showing the main language.
  • Automatic hreflang and sitemap generation from the published translations, so editors never write tags by hand.
  • Translated interface strings for menus, forms and emails, kept in language files or CMS fields alongside the content.

Whether a traditional or headless CMS suits you better depends on your team and channels. Our article on headless CMS or traditional CMS compares the two.

#How PN Scripts can help

PN Scripts builds websites in English and Bulgarian, and we set up language URLs, hreflang, locale formatting and CMS workflows as part of web projects. If you are planning a multilingual site or fixing an existing one, see how we approach custom web development.

Keep reading

Keep reading

Comments

Comments

Be the first to leave a comment.

Leave a comment

Next step

pnscripts.com/contact

Talk to the team

Ask about an article, or tell us about a project you want built. We reply within one business day.

Write to us

The PN Scripts family

Other PN Scripts sites

Hosting, games and the blog each have their own site, run by the same company.

  • pnscripts.com

    PN Scripts

    Software engineering

    Custom web, mobile, API and game development, plus our open-source products and plugins.

  • games.pnscripts.com

    Games

    Games and game servers

    The home for PN Scripts games and game servers. The catalog is empty for now and fills up as titles and servers go live.

  • hosting.pnscripts.com

    Hosting

    Hosting and infrastructure

    Shared hosting, KVM VPS, dedicated servers and domains, from the same company that builds your project.

  • blog.pnscripts.com

    Blog

    Articles and field notes

    Plain articles on hosting, servers, domains and security, written by the people who work with them.

    You are here