Building a Bilingual Website with Laravel: Lessons from This Portfolio

This portfolio is available in Indonesian and English, and the two are meant to stay separate: an English page should not contain Indonesian text, and the other way round. Getting there in Laravel took a handful of decisions that I would make the same way again.

Put the language in the URL

Every public page lives under /id/... or /en/.... A visitor, a link and a search engine can all tell which language a page is in just by reading the address. The root URL simply redirects to the right one using a saved choice first, then the browser's language, then Indonesian as the default. A small middleware sets the application locale from the URL and makes the language part of every generated link, so the code never has to pass it around by hand.

One column per language

For content stored in the database, such as projects, certificates, events and articles, each translatable field has an English base column and an _id column. A small trait returns the version for the current language and tells you whether a translation exists. That keeps the admin form simple: two fields side by side, no separate translation tables.

Do not show what you cannot translate

The easy mistake is falling back to the other language when a translation is missing. That is how Indonesian text ends up on an English page. Here, lists and pages only show content that exists in the page language, and an article that exists in one language redirects from the other language's address instead of showing a mix.

Tell search engines about the pair

With two versions of a page, search engines need to know they belong together. Each page declares its canonical address and an hreflang link to both versions, and the sitemap lists every version with its alternates. That is how an Indonesian searcher is shown the Indonesian page and an English one the English page.

Translate the small things too

Page titles, meta descriptions, form messages, dates and even the names of certificates need a version per language. They are easy to forget and obvious to a reader.

What I would tell someone starting out

  1. Decide the URL structure first and keep it consistent.
  2. Keep translations next to the content, not in a separate system.
  3. Prefer showing less in one language over showing a mix.
  4. Add hreflang and canonical links from day one.
← All posts