Building for 14 Languages: What I Learned About Internationalisation in Next.js

From routing strategy to right-to-left layout support — lessons from shipping a multilingual SaaS that serves users in 14 languages, including Arabic and Turkish.

Supporting 14 languages in a SaaS is mostly a content problem, not a code problem

When I built Life in the UK Online, I knew from day one that the product needed to serve users who didn't speak English as a first language. The UK citizenship test is taken by people from every corner of the world — Turkish, Arabic, Bengali, Urdu, Polish, French speakers and more. Supporting 14 languages wasn't an afterthought. It was the product's core differentiator. Here's what I learned about building multilingual apps in Next.js, and what most tutorials don't tell you.

Next.js i18n routing: what the official docs don't tell you

Next.js has built-in internationalisation support, but the App Router introduced in Next.js 13 changed how i18n works significantly. The old Pages Router approach — setting a i18n key in next.config.js — doesn't apply to the App Router. Instead, you handle locale routing manually via a middleware that detects the user's locale and redirects to the appropriate locale prefix (e.g., /tr/ for Turkish, /ar/ for Arabic).

The generateStaticParams function becomes essential here: for each locale, you generate a separate static route. A page that exists in 14 languages generates 14 static HTML files at build time — which is fast, SEO-friendly, and requires no runtime locale detection. Each page can have its own hreflang tag pointing to its equivalents in other languages, which is the correct signal to Google for multilingual content.

One thing the Next.js docs gloss over: locale detection via the Accept-Language header should happen in middleware, not in a client component. Doing it client-side means the wrong language flashes briefly before the correct one renders — a poor experience that undermines trust.

Handling RTL layouts without losing your mind

Arabic is read right-to-left. This means not just flipping text alignment — it means the entire layout mirrors. Buttons that were on the right move to the left. Navigation that flows left-to-right reverses. Icons with directional meaning (arrows, chevrons) need to flip. This is not a CSS afterthought; it needs to be built into the layout system from the start.

The modern approach uses CSS logical properties instead of physical ones. Instead of padding-left, you write padding-inline-start. Instead of margin-right, you write margin-inline-end. When the dir="rtl" attribute is applied to the root HTML element (which Next.js middleware can set dynamically based on locale), logical properties automatically flip. Tailwind CSS v4 supports logical properties natively, making this significantly easier than it was in previous versions.

The trap to avoid: using absolute positioning or fixed pixel values for layout elements. These don't respond to RTL direction changes and create subtle layout bugs that are hard to spot if you don't test with Arabic or Hebrew content.

The business case for going multilingual early

The conventional wisdom is to launch in English first and add languages later. The problem with this approach is that "later" is expensive — retrofitting i18n into a codebase that wasn't designed for it requires touching almost every component and string in the application. Building with i18n in mind from the start adds perhaps 15–20% to the initial development cost, but makes adding each subsequent language a content task rather than a development task.

For Life in the UK Online, the multilingual support opened the product to a dramatically larger audience without any change to the core application. Turkish and Arabic were the two highest-demand languages after English — and those users were significantly underserved by existing tools. The SEO benefit of 14 localised versions of each page is also substantial: content in users' native languages ranks for search queries in those languages, reaching audiences that English-only content simply cannot.

Key takeaways for businesses

  • Build with i18n in mind from day one. The cost of adding it later is 3–5x the cost of including it upfront.
  • Use CSS logical properties (inline-start, inline-end, block-start, block-end) instead of physical properties for any layout that may need RTL support.
  • Locale routing should happen in middleware at the edge, not in client components, to avoid language flash on page load.

Frequently Asked Questions

How do I add multiple languages to a Next.js app?

In the Next.js App Router, add a [lang] dynamic segment to your route structure, handle locale detection in middleware, use generateStaticParams to pre-generate all locale variants at build time, and store translations in JSON files keyed by locale. Libraries like next-intl handle much of the boilerplate.

What is hreflang and why does it matter for multilingual sites?

Hreflang is an HTML attribute that tells Google which version of a page is intended for which language and region. Without it, Google may index only one language version of your content and ignore the others. Correctly implemented hreflang tags ensure every language version gets indexed and ranks for the right audience.

How much does internationalisation cost to add to an existing web app?

Retrofitting i18n into an existing codebase typically costs 30–50% of the original build cost. For a new project, adding i18n support from the start adds approximately 15–20% to the initial estimate. Building it in from the beginning is significantly cheaper long-term.

Building a multilingual product?

I've shipped production Next.js apps in 14 languages including Arabic RTL support. If you're building for an international audience, let's talk about the architecture.