Configuración de múltiples idiomas en Nextjs

힘센캥거루
2025년 10월 18일(수정됨)
9
nextjs
Configuración de múltiples idiomas en Nextjs-1

Para aumentar el tráfico a mi blog, decidí probar la configuración multilingüe.

Investigué varias maneras y el primer paso es enrutar por idioma.

Decidí usar next-intl.

1. Instalación

yarn add next-intl

2. Aplicación

La aplicación es algo complicada.

Aproximadamente se sigue el siguiente orden:

  1. Colocar toda la estructura de carpetas internas de la app dentro de la carpeta [locale].

  2. Crear una carpeta i18n y generar config.ts, request.ts, ko.json, en.json en su interior.

  3. Configurar en middleware.ts y next.config.ts.

  4. Envolver niños con params y provider en el layout.

  5. Cargar mensajes en los componentes.

3. Probar

1) Carpeta [locale]

Configuración de múltiples idiomas en Nextjs-2

Esta es la estructura de carpetas interna de mi app. 

Voy a envolver todas las carpetas excepto api y uploads dentro de [locale].

Al mover carpetas con .next presente, se produce un error de permisos, así que elimínelo con sudo rm -r .next y luego mueva las carpetas.

Es importante adaptar las llamadas de rutas relativas ya que la estructura de carpetas ha cambiado.

Configuración de múltiples idiomas en Nextjs-3

2) Crear carpeta i18n

Si tiene una carpeta src, puede crearla dentro de src; de lo contrario, simplemente en la raíz si solo usa la carpeta app.

Cree config.ts, request.ts en la carpeta i18n y ko.json, en.json en la carpeta message.

Configuración de múltiples idiomas en Nextjs-4

Configura config.ts como sigue:

Configuré la ruta base "/" al coreano.

export const locales = ['ko', 'en'] as const;
export type Locale = (typeof locales)[number];

export const defaultLocale: Locale = 'ko'; // Establece la ruta base en coreano

export const pathnames = {
  '/': '/',
  '/about': {
    ko: '/about',
    en: '/about',
  },
  '/post/[slug]': {
    ko: '/post/[slug]',
    en: '/post/[slug]',
  },
} as const;

Configura request.ts de la siguiente manera:

Se llama a la información del locale y se devuelve al servidor.

import { getRequestConfig } from 'next-intl/server';
import { defaultLocale } from './config';

export default getRequestConfig(async ({ requestLocale }: { requestLocale: Promise<string | undefined> }) => {
  const locale = await requestLocale || defaultLocale;

  return {
    locale,
    messages: (await import(`./message/${locale}.json`)).default,
  };
});

3) Configuración middleware.ts, next.config.ts

Primero, configura middleware.ts de la siguiente manera:

Es fácil pensar que se añade createMiddleware al principio como export.

import createMiddleware from 'next-intl/middleware';
import { locales, defaultLocale } from './i18n/config';

export createMiddleware({
  locales,
  defaultLocale,
  localePrefix: 'as-needed', // El coreano (ko) no tiene prefijo en la ruta
});
//...configuraciones existentes...//
export default withAuth(
	  function middleware(req) {
		//...configuraciones existentes...//
	});

Luego en next.config.ts, crea createNextIntlPlugin y envuelve las configuraciones existentes:

import type { NextConfig } from "next";
import createNextIntlPlugin from 'next-intl/plugin';

const withNextIntl = createNextIntlPlugin()

const withNextIntlConfig: NextConfig = withNextIntl({
	configuraciones de next.config existentes...
});

export default withNextIntlConfig;

4) Envolviendo el Layout

Ahora, obtén el locale con getMessage en el layout, envuelve con provider para que los componentes secundarios lo usen.

import { NextIntlClientProvider } from "next-intl";
import { getMessages, getLocale } from "next-intl/server";

export default async function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  const messages = await getMessages();
  const locale = await getLocale();

  return (
    <html
      lang={locale}
    >
      <NextIntlClientProvider locale={locale} messages={messages}>
        <body>
		{children}
        </body>
      </NextIntlClientProvider>
    </html>
  );
}

5) Usar mensajes

Los nombres de las funciones son diferentes cuando se renderiza en el lado servidor y el lado cliente.

import {useTranslations, useLocale, useFormatter} from 'next-intl'; // se llama desde el componente 'use client'
import {getTranslations, getLocale, getFormatter} from 'next-intl/server'; // se llama desde el componente del servidor

Categoría

Componente Cliente

Componente Servidor / Función Servidor

Descripción

Traducciones

useTranslations(namespace?)

getTranslations(namespace?)

Trae mensajes de traducción como ko.json, en.json y se utilizan en forma t('key')

Locale

useLocale()

getLocale()

Devuelve el locale activo como cadena (/en, /ko, …)

Formatter

useFormatter()

getFormatter()

Formatea fecha, hora, números según el locale

Mensajes

getMessages()

Objeto de mensajes de traducción completa de la solicitud actual (usualmente para layout como Provider)

Establecer Locale de Solicitud

unstable_setRequestLocale(locale)

Se usa en layout para asegurar consistencia de locale en caching SSG·SSR

Decidí cambiar /about.

El componente /about estaba codificado así que era bueno para cambios.

import {
  HeroSection,
  JourneySection,
  ProjectsSection,
} from "@/components/about";


const baseUrl = process.env.NEXT_PUBLIC_URL||"";

export default function AboutPage() {
	...
  const heroData = {
	...
  };

  const journeyData = {
    title: "My Journey",
    items: [
	.....
	]
  };

  const projectsData = {
    title: "Featured Projects",
    projects: [
      {
        title: "Análisis Estadístico de Admisiones",
		...
      },
	...
    ],
  };

  return (
    <div className="min-h-screen bg-gray-900 ">
      <main className="rounded-lg container relative mx-auto scroll-my-12 overflow-auto">
        {/* Selector de Idioma */}
        <HeroSection {...heroData} />
        <JourneySection {...journeyData} />
        <ProjectsSection {...projectsData} />
      </main>
    </div>
  );
}

Configura ko.json y en.json y utiliza getTranslations para insertar texto en el componente.

Configuración de múltiples idiomas en Nextjs-5

El problema es que lo obtenido con getTranslations es solo texto.

Intenté cambiarlo así y resultó en un error.

export default async function AboutPage() {
	...
  const t = await getTranslations("about");
  const heroData = JSON.parse(JSON.stringify(t("hero")));
  const journeyData = JSON.parse(JSON.stringify(t("journey")));
  const projectsData = JSON.parse(JSON.stringify(t("projects")));
	...
}

Fue una molestia, así que pedí ayuda a Cursor.

Configuración de múltiples idiomas en Nextjs-6

De esta forma, se pasó a todos los componentes secundarios a través de props.

Luego verifiqué con en.

Configuración de múltiples idiomas en Nextjs-7

Puedo ver que se ha aplicado correctamente.

4. Conclusión

Hasta ahora pensaba que debía hacer todo el trabajo del blog en inglés manualmente, pero ahora con AI y herramientas automatizadas, será más fácil.

Lo que queda es traducir todas las entradas del blog e incorporarlas en la base de datos.

Luego agregaré el locale a la base de datos y recuperaré las publicaciones mediante búsquedas por locale.

Lo intentaré pronto.

댓글을 불러오는 중...