Multilingual Website Development & Localization

A multilingual website gives each audience its own URLs, titles and content, so a customer can read and buy in their language and a search engine can index that version on its own. Translating a menu label in the footer is not the same thing. Done properly, the language switcher never traps a visitor, hreflang tells Google how the versions relate, and new pages have a clear path into every language you support.

At CodeWiz we build multilingual websites on WordPress with Polylang or WPML, and we internationalise custom applications in Laravel, Node.js and mobile. We set up the URL structure, the translation workflow, the SEO signals and the language detection. The content still needs a human who knows the language. We make sure the product can hold that content without breaking the shop, the cache or the index.

This is for companies selling in more than one country, organisations that serve Bosnia and Herzegovina, Serbia, Croatia and Montenegro as well as an international audience, and teams whose translation plugin has started to fight WooCommerce, the theme or the page cache.

For multilingual website, open-source tools are the default when they fit the job.

Multilingual Website: Page of a bilingual dictionary with entries, abbreviations and typographic symbols

WordPress Multilingual Websites with Polylang and WPML

On WordPress, a multilingual website means every public piece has a translation and its own address: pages, posts, products, categories, menus and the strings that live in the theme. Polylang and WPML both do this. They are not interchangeable, and the licence is rarely the reason to pick one.

A multilingual website engagement starts from the system you already run.

PolylangWPMLCustom i18n
Best fitContent sites, blogs, most business sitesComplex WordPress and heavy WooCommerceLaravel, Node.js, mobile apps
Cost shapeFree core, Pro for extra featuresPaid licenceEngineering time, no plugin fee
Where text livesPosts, terms, menus, string translationsPosts plus a string translation and translation-memory layerLanguage files, JSON or database rows
SEOSeparate URLs, hreflang, sitemap supportSeparate URLs, hreflang, sitemap supportYou implement URLs, hreflang and sitemaps
Watch out forSome page builders and shops need the Pro add-onsMore moving parts, and a licence to keep currentEasy to forget emails, PDFs and error messages

How we set WordPress up

  • One language per URL, usually a directory (/en/, /bhs/) on a single domain, so authority and hosting stay simple. Subdomains and country domains are there when a separate legal entity actually needs them.
  • A language switcher that goes to the translation of the current page, not always to the homepage. If a translation is missing, we decide explicitly: hide the link, or send the visitor to a clear fallback. We do not leave a switcher that 404s.
  • Menus, forms, SEO titles, meta descriptions, image alt text and slugs translated with the page. English and BHS slugs on codewizdev.com differ on purpose (/services/ and /bhs/usluge/), which is also how Polylang expects translations to work.
  • WooCommerce products, attributes, shipping notices and transactional emails included in the same workflow, not translated ad hoc in the theme.
  • Cache keys that vary by language. A shared Varnish or Cloudflare cache must not serve the wrong language to the next visitor, which is simple if the HTML for each URL is stable. We have written about keeping pages fast without giving up a correct cache.

codewizdev.com itself runs this way: English and one shared BHS text in Polylang, aimed at readers across Bosnia and Herzegovina, Serbia, Croatia and Montenegro.

The multilingual website work stays in your repository and on your infrastructure.

App Internationalization (i18n)

Internationalization is the engineering that makes translation possible: strings pulled out of components, formats for dates and currencies, and layouts that survive a longer sentence. Localization is the translation itself and the local conventions that go with it.

CodeWiz reviews multilingual website in production, not only in a demo.

Rules we build in from the start

  • No concatenated sentences. "Hello, " + name cannot be reordered for a language that puts the name elsewhere. Messages are complete strings with placeholders.
  • Plurals go through the platform’s plural rules. ICU MessageFormat, Gettext ngettext or the framework equivalent handles languages that do not stop at “one” and “other”.
  • Dates, numbers and currencies use Intl or the framework formatter, with an explicit locale, rather than a hard-coded DD/MM/YYYY.
  • Keys stay stable (cart.items) when the wording changes, so translators are not handed a new file.
  • Layout assumes expansion. A German or BHS label is often longer than the English one, so buttons wrap and navigation does not overflow.
{ "cart.items": "{count, plural, one {# item} other {# items}}", "order.shipped": "Order {id} is on its way" }

In Laravel that lives in language files and trans_choice(). In React or Next.js we use a maintained i18n library. In Flutter it is ARB files and intl. App Store and Google Play descriptions, screenshots and keywords are a separate localization from the app binary.

Decisions about multilingual website follow the business constraint that actually hurts.

hreflang and International SEO

hreflang tells Google which URL is the alternate for which language or region. It does not boost a page. It reduces the chance that the wrong language ranks, or that duplicate translations compete. Google’s documentation on localized versions of a page is the reference we implement against.

What a correct set looks like

Every version lists itself and all alternates, the annotations match both ways, and x-default points at the fallback for visitors who match none of the languages. A condensed example of the pattern we use when one regional text covers several language codes:

<link rel="alternate" hreflang="en" href="https://example.com/pricing/" /> <link rel="alternate" hreflang="bs" href="https://example.com/bhs/cijene/" /> <link rel="alternate" hreflang="hr" href="https://example.com/bhs/cijene/" /> <link rel="alternate" hreflang="sr" href="https://example.com/bhs/cijene/" /> <link rel="alternate" hreflang="x-default" href="https://example.com/pricing/" />

That is how codewizdev.com is marked up. The BHS URLs are alternates for bs, hr and sr, and English is the x-default. The same annotations can live in the sitemap instead of the HTML. They must not point at redirects, at URLs that canonicalise somewhere else, or at pages that return an error.

  • Each language canonicalises to itself. Pointing every translation’s canonical at the English URL tells Google to ignore the translation.
  • Titles, descriptions and visible headings are written in that language. A Bosnian page with an English title wastes the annotation.
  • Hreflang is not a substitute for a useful page. Thin machine translations, indexed in bulk, are a quality problem, not an SEO trick.
  • Search Console, country reports and query data tell you whether the right version is appearing. We use that kind of search data to see which language is earning impressions, instead of assuming the switcher is enough.
Light-coloured world map with colourful pins marking locations in different countries

Translation Workflows That Stay in Sync

A workflow answers a plain question: when a price, a policy or a product description changes in the source language, what happens to the others? If the answer is “someone remembers”, the languages drift, and one of them is wrong in front of a customer.

A practical setup

  • A source language. Usually the language your team writes in. Other languages are translations of that source, not independent copies that get edited in three places.
  • A glossary. Product names, the formal “vi”, and terms that stay in English, such as brand and API names.
  • An exchange format. XLIFF, Gettext PO or the import that Polylang or WPML already supports, so a translator works in a translation tool instead of in the WordPress admin for every string.
  • Machine translation only as a draft. It is a reasonable first pass for internal tools and for low-risk UI chrome, followed by a person. We do not publish unreviewed machine text on pages that state prices, legal terms or medical and financial claims.
  • A missing-translation rule. Show the source string rather than a blank, and do not index a page that is mostly untranslated. New content stays out of the alternate sitemap until it is actually ready.

We are not a translation agency. We build the pipeline, sit with your translators or editors, and keep emails, invoices, push notifications and PDF attachments on the same list as the visible pages. Those are the strings customers notice once the homepage is already done.

Geo-Targeting and Language Detection

Language detection guesses a preferred version. Crawlers, travellers and people who share a link still have to land on a URL that stays itself, so detection cannot be the only way to reach a language.

ApproachFor visitorsFor search engines
Separate URLs and a visible switcherClear, if the switcher keeps the current pageSafe. Each language can be crawled
A banner that suggests another languagePolite, easy to ignoreSafe. The URL does not change underneath the crawler
Country redirect that skips bots and remembers a manual choiceConvenient for first visitsSafe only if every language remains on its own crawlable URL
Redirect of everyone, including crawlers, by IP addressConfusing for travellersRisky. Google may see only one language
One URL, language stored only in a cookieLooks simpleUnsafe. One URL cannot rank as every language

codewizdev.com uses the third pattern. The country comes from Cloudflare’s CF-IPCountry header, read by a small uncached endpoint, so the HTML of the page stays identical for everyone and Varnish and Cloudflare can cache it. Visitors from Bosnia and Herzegovina, Serbia, Croatia and Montenegro who open an English page are sent to the BHS translation when one exists. Bots are not redirected. Anyone who has already picked a language in the switcher keeps that choice. The switcher label can show BS, SR, HR or ME for those countries, while the page content stays the one shared BHS text.

We reuse that idea only when it matches the audience. A shop that serves one country rarely needs it. A catalogue aimed at the region and at an English-speaking market often does. Detection never replaces hreflang, and it never redirects a URL that has no translation.

Multilingual Website Mistakes That Cost Rankings

  • One URL for every language, with the text swapped by JavaScript or a cookie.
  • hreflang aimed at a redirect, a 404, or a URL that canonicalises back to another language.
  • Automatic IP redirects that also catch Googlebot, or a switcher that the redirect immediately overrides.
  • Untranslated slugs, alt text, titles and transactional emails, so the “translated” site is only translated above the fold.
  • Indexing machine-translated pages that nobody has read.
  • A language switcher that always goes to the homepage.
  • Forgetting that a second language doubles the pages your cache, your sitemap and your editors must carry.

Shops feel this more than blogs: the wrong language on a price or a shipping rule is a lost order, not an awkward paragraph. The same care shows up in how we build online stores that have to work beyond a single market.

What Drives the Cost of a Multilingual Website

Translation volume is only one part of the cost, and it is often yours to commission. Our side of the estimate is the product work:

  • How many templates, forms, emails and system messages exist, and whether strings are already extracted.
  • WordPress with a plugin versus a custom app that needs i18n built in.
  • A shop catalogue: products, attributes, categories and policies multiply faster than pages.
  • How many languages, and whether any of them are right-to-left or need a different layout.
  • SEO setup: hreflang, sitemaps, canonicals, and Search Console for each version.
  • Whether language detection is in scope, and who will keep translating new content after launch.
Person holding a small world globe under their arm in a sunlit field

How We Work

  1. Audit: we list templates, strings, URLs and the SEO the site already emits, including any hreflang that points the wrong way.
  2. Plan: we choose the URL structure, Polylang, WPML or custom i18n, the source language and the fallback rules, and we agree who translates.
  3. Build: we implement languages, the switcher, hreflang, sitemaps and cache behaviour, and we extract the strings translators will actually see.
  4. Translate: your editors or translators fill the pipeline. We wire review, glossaries and the rule for unfinished pages.
  5. Test: we check switcher targets, hreflang reciprocity, canonicals, emails and a crawl that sees every language.
  6. Launch and support: we release, watch Search Console, and keep the workflow usable when new pages and products appear.

Why CodeWiz

  • We run it ourselves: codewizdev.com is English and BHS on Polylang, with hreflang and country-based language detection that leaves crawlers and caches alone.
  • Full stack: theme, plugin, Laravel or Node.js app, shop and server configuration come from one team, so the language layer is not glued on at the end.
  • SEO and performance together: separate URLs, honest hreflang, and a cache that does not mix languages up.
  • Open-source first: Polylang, WordPress, Laravel and Gettext-style message files keep the content portable.
  • Fair pricing: premium development without premium prices, from Banja Luka, working remotely with clients locally and internationally. More about CodeWiz.

Frequently Asked Questions

Should we use Polylang or WPML?

Polylang fits most WordPress content sites and is what we run on codewizdev.com. WPML earns its place on complex WooCommerce setups that need its translation management and already budget for the licence. For Laravel or Node.js, neither plugin applies and we internationalise the application directly. We recommend one after seeing the theme, the shop and the page builder.

Will a second language hurt our current rankings?

Not if each language has its own URL, its own canonical and correct hreflang. The usual damage comes from redirects that hide a version from crawlers, from canonicals that point every language at English, or from thin automatic translations. A proper second version adds pages. It does not replace the first language.

How do you handle Bosnian, Croatian and Serbian?

When the audience can share one carefully written ijekavian text, one BHS version stays consistent. That is what we do on our own site, with hreflang listing that URL for bs, hr and sr. When a market needs its own wording, legal text or offer, it gets its own locale and URL. We will not split one language into three copies just to look larger.

Can you add a language to an existing site?

Yes. We audit the theme, the plugins and the current URLs, then add the language without breaking pages that already rank. Hard-coded strings in a theme are the usual surprise. They get extracted, rather than translated by hand inside the PHP templates.

Do you translate the content?

We set up the workflow, the glossary and the technical integration, and we can prepare machine-translation drafts for review. Published wording should come from someone accountable for that language, especially where a customer pays or relies on the text. If you already have a translator, we work in their format.

How long does a multilingual website take?

Adding one language to a well-built WordPress site is often a few weeks, including hreflang, templates and the first content through the pipeline. A large shop catalogue, a custom application or several languages with review cycles take longer, because translation and checking are part of the schedule.

Ready to Add a Language Properly?

Tell us which languages you need and what the site is built on, and we will propose the URL structure, the tool and a workflow your editors can keep using. Contact us to go through it, or browse our development services.