How to Make a Next.js Site Multilingual with next-intl: A Real-World Experience

This article is part of the series "Rebuilding a Website with AI". If you haven't read the first episode, start there.
The Problem
My site was 100% in French. No language switcher, no multilingual structure, nothing. Yet a significant part of my professional network is English-speaking, and my Brazilian roots had been pushing me for a long time to add Portuguese.
Internationalizing a Next.js App Router site is the project everyone keeps postponing. And for good reason: it touches absolutely everything. Routes, layouts, metadata, components, content. Every single file is affected.
The Technical Foundation: next-intl and Middleware
First step: install next-intl and set up the multilingual routing infrastructure. Claude Code generated the middleware.ts with automatic browser language detection and redirection to the appropriate locale. It created the i18n/routing.ts file to configure the locales (fr, en, pt) with French as the default language, along with i18n/request.ts for dynamically loading translation files based on the active locale.
Migrating Every Single Route
This is the trickiest part. Every page on the site had to be moved into an app/[locale]/ folder. The homepage app/page.tsx became app/[locale]/page.tsx. The blog page app/blog/page.tsx became app/[locale]/blog/page.tsx. And so on for every route on the site.
But it's not just moving files around. Each page had to be modified to receive the locale parameter from props, use useTranslations() or getTranslations() for text strings, and generate SEO metadata in the correct language.
Over 385 Translation Keys Per Language
Claude Code created three complete translation files: messages/fr.json, messages/en.json, and messages/pt.json. Each contains over 385 keys covering navigation (main menu, links, breadcrumbs), service pages (Sprint, SaaS, Labs with every section, title, and paragraph), the homepage (hero, services, testimonials, FAQ), the blog (filters, categories, reading time, pagination), SEO (title, description, OpenGraph for each page), and the entire user interface (buttons, forms, 404 page, footer).
All consistent across the three languages — not word-for-word translation, but genuine localization adapted to each culture.
The LanguageSwitch
A component in the footer that lets users switch between languages. Simple on the surface, but with a technical subtlety: when you're on a blog post, the switch needs to take you to the translated version of that article (if it exists) rather than to the target language's homepage.
Claude Code implemented a slug resolution system using an AlternatePathProvider that tracks the mapping between articles and their translations.
The Multilingual Slug Trap
A problem you don't see coming: some articles have different slugs depending on the language. When you're on /fr/blog/2022/thibault-jaime and switch to English, the URL should become /en/blog/2022/thibault-jaime. But what if the English file has a different slug?
Claude Code solved this by adding a detection system that looks for the corresponding .en.mdx or .pt.mdx file matching the same id in the frontmatter, regardless of the file's naming convention.
The Result
Every page on the site is now accessible in 3 languages, with clean URLs (/fr/blog/..., /en/blog/..., /pt/blog/...), localized SEO metadata for each page and each language, automatic browser language detection, smooth navigation between language versions, and content filtering by locale so each visitor only sees articles in their language.
All without breaking any existing URLs, thanks to the middleware redirects.
Time Spent
This i18n project took about 2 hours of actual work. To put that in perspective: the last time I did an internationalization from scratch on a Next.js project, it took me an entire week.
The difference? I didn't have to write a single translation key manually. I didn't have to migrate routes file by file. I didn't have to debug middleware edge cases one by one. Claude Code did all of that, and I reviewed and guided.
Tomorrow, we tackle a different kind of challenge: turning 13 podcast episodes into 50 blog posts. How can AI recycle your podcasts into quality SEO content? The answer might surprise you.

Toni Dias
Full-Stack Developer at AsuOs
Related articles

Freelance Developer and AI: How I Transformed My Productivity with Claude Code
Final episode of the series. What AI does well, what it doesn't, and what it concretely changes when you're an independent developer. An honest look at the future of the profession. Episode 7/7.

AI-Powered SEO Audit: How to Analyse and Fix Your Site in 2026
Broken RSS URLs, incomplete sitemap, missing structured data, tags mixed across languages. Claude Code's SEO audit uncovered a dozen issues and fixed them all in one pass. Episode 6/7.
Ready to transform your digital business?
AsuOs supports you in your digital strategy with tailored solutions.