The Challenge of Framework-Level Localization
When building a Single Page Application (SPA) with Vite, internationalization (i18n) is typically handled entirely on the client side. Libraries like react-i18next or react-intl initialize a singleton instance that fetches translation JSON files and swaps strings dynamically.
However, moving that logic to Next.js introduces a paradigm shift. In Next.js, i18n isn't just about translating text; it's about routing, SEO-friendly URLs (like /en/about or /es/acerca), and Server-Side Rendering (SSR). If you simply copy-paste your Vite setup, you'll lose the benefits of pre-rendered localized content. Here is how to migrate without breaking your architecture.
1. Understanding the Routing Shift
In a Vite app, your i18n logic likely lives in an i18n.ts file and changes state internally without changing the URL path. Next.js expects the locale to be part of the URL.
Before you start moving components, decide between the two main patterns:
-
Sub-path routing:
example.com/en/dashboardvsexample.com/fr/dashboard. -
Domain routing:
example.comvsexample.fr.
For most migrations, sub-path routing is the standard. If you are using the App Router (Next.js 13+), you will need to wrap your routes in a dynamic segment: app/[lng]/layout.tsx.
2. Setting Up the Middleware
Unlike Vite, where you might handle language detection in a useEffect, Next.js uses Middleware to intercept requests. This allows you to detect the user's preferred language via the Accept-Language header and redirect them before the page even loads.
import { NextResponse } from 'next/server'
import acceptLanguage from 'accept-language'
import { fallbackLng, languages } from './app/i18n/settings'
export function middleware(req) {
let lng
if (req.cookies.has('i18next')) lng = req.cookies.get('i18next').value
if (!lng) lng = acceptLanguage.get(req.headers.get('Accept-Language'))
if (!lng) lng = fallbackLng
// Redirect if lng in path is not supported
if (
!languages.some(loc => req.nextUrl.pathname.startsWith(`/${loc}`)) &&
!req.nextUrl.pathname.startsWith('/_next')
) {
return NextResponse.redirect(new URL(`/${lng}${req.nextUrl.pathname}`, req.url))
}
return NextResponse.next()
}
3. Handling Client vs. Server Components
In Vite, every component is a client component. In Next.js, you must distinguish between them.
Server Components
You cannot use hooks like useTranslation() in Server Components. Instead, you'll need to initialize an i18next instance on the server for every request. This ensures that the HTML sent to the browser is already translated, which is vital for SEO.
Client Components
For components that require interactivity (forms, buttons), you can use the familiar hook pattern, but ensure you include the 'use client' directive at the top of the file.
If you find the manual restructuring of these component types and routing logic overwhelming, you can use ViteToNext.AI to automate the heavy lifting of converting your Vite structure into a Next.js-ready architecture.
4. Structuring Translation Files
In Vite, you might have imported JSON files directly:
import en from './locales/en.json';
In Next.js, it is better to load these files dynamically based on the current locale to keep your client-side bundle small. Use the i18next-resources-to-backend plugin to fetch only the necessary namespace for the current page.
5. SEO and Metadata
One of the primary reasons to migrate is SEO. In your layout.tsx, make sure to use the generateMetadata function to set the correct lang attribute and localized titles:
export async function generateMetadata({ params: { lng } }) {
return {
title: lng === 'en' ? 'Welcome' : 'Bienvenue',
description: '...'
}
}
Conclusion
Migrating i18n from Vite to Next.js requires moving away from global client-side state toward URL-driven, server-aware localization. By leveraging Middleware for language detection and properly splitting your logic between Server and Client components, you gain significant performance and SEO advantages.
Start by mapping your routes, move your JSON resources to a shared directory, and implement a robust Middleware to handle the redirects. Your users (and search engines) will thank you.
Further reading: Explore automated migration strategies at vitetonext.codebypaki.online.
Top comments (0)