---
createdAt: 2024-12-06
updatedAt: 2026-05-31
title: "Next.js 16 i18n - Kompletny przewodnik po tłumaczeniu swojej aplikacji"
description: "Koniec z i18next. Przewodnik 2026 do budowania wielojęzycznej (i18n) aplikacji Next.js 16. Tłumacz z agentami AI i optymalizuj rozmiar bundle, SEO i wydajność."
keywords:
- Internacjonalizacja
- Dokumentacja
- Intlayer
- Next.js 16
- JavaScript
- React
slugs:
- doc
- environment
- nextjs
applicationTemplate: https://github.com/aymericzip/intlayer-next-16-template
applicationShowcase: https://intlayer-next-16-template.vercel.app
youtubeVideo: https://www.youtube.com/watch?v=e_PPG7PTqGU
history:
- version: 8.9.0
date: 2026-05-04
changes: "Aktualizacja użycia API useIntlayer w Solid do bezpośredniego dostępu do właściwości"
- version: 7.5.9
date: 2025-12-30
changes: "Dodaj polecenie init"
- version: 7.0.6
date: 2025-11-01
changes: "Dodano wzmiankę o `x-default` w obiekcie `alternates`"
- version: 7.0.0
date: 2025-06-29
changes: "Inicjalizacja historii"
---
# Przetłumacz swoją stronę Next.js 16 za pomocą Intlayer | Internacjonalizacja (i18n)
Zobacz [Szablon aplikacji](https://github.com/aymericzip/intlayer-next-16-template) na GitHubie.
## Spis treści
## Dlaczego Interlayer zamiast alternatyw?
W porównaniu do głównych rozwiązań, takich jak `next-intl` czy `i18next`, Intlayer jest rozwiązaniem wyposażonym w zintegrowane optymalizacje, takie jak:
**Pełne pokrycie Next.js**
Intlayer jest zoptymalizowany do współpracy z **Server Components** w celu wydajnego renderowania i jest w pełni kompatybilny z [**Turbopack**](https://nextjs.org/docs/architecture/turbopack). Nie blokuje renderowania statycznego i oferuje oprogramowanie pośredniczące oraz wszystkie funkcje potrzebne do skalowania internacjonalizacji (i18n).
> Intlayer jest kompatybilny z Next.js 12, 13, 14, 15 i 16. Jeśli używasz routera Next.js Pages Router, możesz zapoznać się z tym [przewodnikiem] (https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_with_nextjs_page_router.md).
> Routing lokalny jest przydatny ze względu na SEO, rozmiar bundle'a i wydajność. Jeśli go nie potrzebujesz, możesz zapoznać się z tym [przewodnikiem](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_with_nextjs_no_locale_path.md).
> W przypadku Next.js 12, 13, 14 i 15 z App Router zapoznaj się z tym [przewodnikiem] (https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_with_nextjs_14.md).
**Rozmiar bundle'a**
Zamiast ładować ogromne pliki JSON na swoje strony, ładuj tylko niezbędną treść. Intlayer pomaga **zmniejszyć rozmiary bundle'a i stron nawet o 50%**.
**Łatwość konserwacji**
Określanie zakresu zawartości aplikacji **ułatwia konserwację** aplikacji na dużą skalę. Możesz powielić lub usunąć pojedynczy folder funkcji bez obciążania psychicznego koniecznością przeglądania całej bazy kodu zawartości. Dodatkowo Inlayer jest **w pełni napisany**, aby zapewnić dokładność treści.
**Agent AI**
Wspólna lokalizacja treści **zmniejsza potrzebny kontekst** dzięki modelom dużego języka (LLM). Intlayer zawiera także zestaw narzędzi, taki jak **CLI** do sprawdzania brakujących tłumaczeń**[LSP](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/lsp.md)**, **[MCP](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/mcp_server.md)** i **[umiejętności agenta](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/agent_skills.md)**, aby praca programisty (DX) była jeszcze płynniejsza dla agentów AI.
**Automatyzacja**
Korzystaj z automatyzacji, aby tłumaczyć w swoim potoku CI/CD przy użyciu wybranego LLM na koszt dostawcy sztucznej inteligencji. Intlayer oferuje także **kompilator** do automatyzacji ekstrakcji treści, a także [platformę internetową] (https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_CMS.md), która pomaga **tłumaczyć w tle**.
**Wydajność**
Łączenie ogromnych plików JSON z komponentami może prowadzić do problemów z wydajnością i reaktywnością. Inlayer optymalizuje ładowanie treści w czasie kompilacji.
**Skalowanie bez użycia dewelopera**
Więcej niż tylko rozwiązanie i18n, Intlayer zapewnia **samodzielny [edytor wizualny](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_visual_editor.md)** i **[pełny CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/intlayer_CMS.md)**, który pomoże Ci zarządzać wielojęzyczną treścią w **w czasie rzeczywistym**, dzięki czemu współpraca z tłumaczami, copywriterami i innymi członkami zespołu będzie płynna. Treść może być przechowywana lokalnie i/lub zdalnie.
---
## Przewodnik krok po kroku, jak skonfigurować Intlayer w aplikacji Next.js
Zainstaluj niezbędne pakiety za pomocą npm:
```bash packageManager="npm"
npm install intlayer next-intlayer
npx intlayer init
```
```bash packageManager="pnpm"
pnpm add intlayer next-intlayer
pnpm intlayer init
```
```bash packageManager="yarn"
yarn add intlayer next-intlayer
yarn intlayer init
```
```bash packageManager="bun"
bun add intlayer next-intlayer
bun x intlayer init
```
- **intlayer**
Podstawowy pakiet, który dostarcza narzędzia do internacjonalizacji dla zarządzania konfiguracją, tłumaczeń, [deklaracji treści](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dictionary/content_file.md), transpilacji oraz [poleceń CLI](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/cli/index.md).
- **next-intlayer**
Pakiet integrujący Intlayer z Next.js. Dostarcza dostawców kontekstu oraz hooki do internacjonalizacji w Next.js. Dodatkowo zawiera wtyczkę Next.js do integracji Intlayer z [Webpack](https://webpack.js.org/) lub [Turbopack](https://nextjs.org/docs/app/api-reference/turbopack), a także proxy do wykrywania preferowanego języka użytkownika, zarządzania ciasteczkami oraz obsługi przekierowań URL.
Oto ostateczna struktura, którą stworzymy:
```bash
.
├── src
│ ├── app
│ │ ├── [locale]
│ │ │ ├── layout.tsx # Układ lokalizacji dla dostawcy Intlayer
│ │ │ ├── page.content.ts
│ │ │ └── page.tsx
│ │ └── layout.tsx # Główny układ dla stylów i globalnych dostawców
│ ├── components
│ │ ├── client-component-example.content.ts
│ │ ├── ClientComponentExample.tsx
│ │ ├── LocaleSwitcher
│ │ │ ├── localeSwitcher.content.ts
│ │ │ └── LocaleSwitcher.tsx
│ │ ├── server-component-example.content.ts
│ │ └── ServerComponentExample.tsx
│ └── proxy.ts
├── intlayer.config.ts
├── next.config.ts
├── package.json
└── tsconfig.json
```
> Jeśli nie chcesz routingu lokalizacji, intlayer może być używany jako prosty dostawca / hook. Zobacz [ten przewodnik](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/intlayer_with_nextjs_no_locale_path.md) po więcej szczegółów.
Utwórz plik konfiguracyjny, aby skonfigurować języki swojej aplikacji:
```typescript fileName="intlayer.config.ts" codeFormat={["typescript", "esm", "commonjs"]}
import { Locales, type IntlayerConfig } from "intlayer";
const config: IntlayerConfig = {
internationalization: {
locales: [
Locales.ENGLISH,
Locales.FRENCH,
Locales.SPANISH,
// Twoje pozostałe lokalizacje
],
defaultLocale: Locales.ENGLISH,
},
};
export default config;
```
> Dzięki temu plikowi konfiguracyjnemu możesz ustawić lokalizowane adresy URL, przekierowania proxy, nazwy ciasteczek, lokalizację i rozszerzenie deklaracji zawartości, wyłączyć logi Intlayer w konsoli i wiele więcej. Pełną listę dostępnych parametrów znajdziesz w [dokumentacji konfiguracji](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/configuration.md).
Skonfiguruj swoje środowisko Next.js, aby korzystało z Intlayer:
```typescript fileName="next.config.ts" codeFormat={["typescript", "esm", "commonjs"]}
import type { NextConfig } from "next";
import { withIntlayer } from "next-intlayer/server";
const nextConfig: NextConfig = {
/* opcje konfiguracji tutaj */
};
export default withIntlayer(nextConfig);
```
> Wtyczka Next.js `withIntlayer()` służy do integracji Intlayer z Next.js. Zapewnia budowanie plików deklaracji treści oraz monitoruje je w trybie deweloperskim. Definiuje zmienne środowiskowe Intlayer w środowiskach [Webpack](https://webpack.js.org/) lub [Turbopack](https://nextjs.org/docs/app/api-reference/turbopack). Dodatkowo dostarcza aliasy optymalizujące wydajność oraz zapewnia kompatybilność z komponentami serwerowymi.
> Funkcja `withIntlayer()` jest funkcją zwracającą obietnicę. Pozwala przygotować słowniki Intlayer przed rozpoczęciem budowania. Jeśli chcesz użyć jej z innymi wtyczkami, możesz na nią zaczekać (await). Przykład:
>
> ```ts
> const nextConfig = await withIntlayer(nextConfig);
> const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);
>
> export default nextConfigWithOtherPlugins;
> ```
>
> Jeśli chcesz używać tego synchronicznie, możesz użyć funkcji `withIntlayerSync()`. Przykład:
>
> ```ts
> const nextConfig = withIntlayerSync(nextConfig);
> const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);
>
> export default nextConfigWithOtherPlugins;
> ```
> Intlayer automatycznie wykrywa, czy Twój projekt używa **webpack** czy **Turbopack** na podstawie flag wiersza poleceń `--webpack`, `--turbo` lub `--turbopack`, a także bieżącej wersji **Next.js**.
>
> Od wersji `next>=16`, jeśli używasz **Rspack**, musisz jawnie wymusić na Intlayer korzystanie z konfiguracji webpack poprzez wyłączenie Turbopack:
>
> ```ts
> withRspack(withIntlayer(nextConfig, { enableTurbopack: false }));
> ```
Usuń wszystko z `RootLayout` i zastąp to następującym kodem:
```tsx {3} fileName="src/app/layout.tsx" codeFormat={["typescript", "esm"]}
import type { PropsWithChildren, FC } from "react";
import "./globals.css";
const RootLayout: FC = ({ children }) => (
// Nadal możesz opakować dzieci innymi dostawcami, takimi jak `next-themes`, `react-query`, `framer-motion` itp.
<>{children}>
);
export default RootLayout;
```
> Pozostawienie komponentu `RootLayout` pustym pozwala na ustawienie atrybutów [`lang`](https://developer.mozilla.org/fr/docs/Web/HTML/Global_attributes/lang) oraz [`dir`](https://developer.mozilla.org/fr/docs/Web/HTML/Global_attributes/dir) dla tagu ``.
Aby zaimplementować dynamiczne routowanie, podaj ścieżkę dla lokalizacji, dodając nowy layout w katalogu `[locale]`:
```tsx fileName="src/app/[locale]/layout.tsx" codeFormat={["typescript", "esm"]}
import { type NextLayoutIntlayer, IntlayerClientProvider } from "next-intlayer";
import { Inter } from "next/font/google";
import { getHTMLTextDir } from "intlayer";
const inter = Inter({ subsets: ["latin"] });
const LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => {
const { locale } = await params;
return (
{children}
);
};
export default LocaleLayout;
```
> Segment ścieżki `[locale]` służy do określenia lokalizacji. Przykład: `/en-US/about` odnosi się do `en-US`, a `/fr/about` do `fr`.
> Na tym etapie napotkasz błąd: `Error: Missing and tags in the root layout.`. Jest to oczekiwane, ponieważ plik `/app/page.tsx` nie jest już używany i można go usunąć. Zamiast tego segment ścieżki `[locale]` aktywuje stronę `/app/[locale]/page.tsx`. W konsekwencji strony będą dostępne pod ścieżkami takimi jak `/en`, `/fr`, `/es` w Twojej przeglądarce. Aby ustawić domyślny język jako stronę główną, odnieś się do konfiguracji `proxy` w kroku 7.
Następnie zaimplementuj funkcję `generateStaticParams` w układzie aplikacji.
```tsx {1} fileName="src/app/[locale]/layout.tsx" codeFormat={["typescript", "esm"]}
export { generateStaticParams } from "next-intlayer"; // Linia do dodania
const LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => {
/*... Reszta kodu*/
};
export default LocaleLayout;
```
> `generateStaticParams` zapewnia, że Twoja aplikacja wstępnie buduje niezbędne strony dla wszystkich lokalizacji, zmniejszając obciążenie podczas działania i poprawiając doświadczenie użytkownika. Aby uzyskać więcej informacji, zapoznaj się z [dokumentacją Next.js dotyczącą generateStaticParams](https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic-rendering#generate-static-params).
> Intlayer działa z `export const dynamic = 'force-static';`, aby zapewnić, że strony są wstępnie zbudowane dla wszystkich lokalizacji.
Utwórz i zarządzaj deklaracjami zawartości, aby przechowywać tłumaczenia:
```tsx fileName="src/app/[locale]/page.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
import { t, type Dictionary } from "intlayer";
const pageContent = {
key: "page",
content: {
getStarted: {
main: t({
en: "Get started by editing",
fr: "Commencez par éditer",
es: "Comience por editar",
}),
pageLink: "src/app/page.tsx",
},
},
} satisfies Dictionary;
export default pageContent;
```
```json fileName="src/app/[locale]/page.content.json" contentDeclarationFormat="json"
{
"$schema": "https://intlayer.org/schema.json",
"key": "page",
"content": {
"getStarted": {
"nodeType": "translation",
"translation": {
"en": "Get started by editing",
"fr": "Commencez par éditer",
"es": "Comience por editar"
}
},
"pageLink": "src/app/page.tsx"
}
}
```
> Twoje deklaracje zawartości mogą być definiowane w dowolnym miejscu w aplikacji, pod warunkiem, że zostaną umieszczone w katalogu `contentDir` (domyślnie `./src`). I będą miały rozszerzenie pliku deklaracji zawartości (domyślnie `.content.{json,ts,tsx,js,jsx,mjs,cjs,md,mdx,yaml,yml}`).
> Aby uzyskać więcej szczegółów, zapoznaj się z [dokumentacją deklaracji zawartości](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/dictionary/content_file.md).
Uzyskaj dostęp do swoich słowników zawartości w całej aplikacji:
```tsx fileName="src/app/[locale]/page.tsx" codeFormat={["typescript", "esm"]}
import type { FC } from "react";
import { ClientComponentExample } from "@components/ClientComponentExample";
import { ServerComponentExample } from "@components/ServerComponentExample";
import { type NextPageIntlayer } from "next-intlayer";
import { IntlayerServerProvider, useIntlayer } from "next-intlayer/server";
const PageContent: FC = () => {
const content = useIntlayer("page");
return (
<>
{content.getStarted.main}
{content.getStarted.pageLink}
>
);
};
const Page: NextPageIntlayer = async ({ params }) => {
const { locale } = await params;
return (
);
};
export default Page;
```
- **`IntlayerClientProvider`** służy do dostarczania lokalizacji komponentom po stronie klienta. Może być umieszczony w dowolnym komponencie nadrzędnym, w tym w layoucie. Jednak zaleca się umieszczenie go w layoucie, ponieważ Next.js współdzieli kod layoutu między stronami, co jest bardziej efektywne. Używając `IntlayerClientProvider` w layoucie, unikasz ponownej inicjalizacji dla każdej strony, poprawiając wydajność i utrzymując spójny kontekst lokalizacji w całej aplikacji.
- **`IntlayerServerProvider`** służy do dostarczania lokalizacji komponentom po stronie serwera. Nie może być ustawiony w layoucie.
> Layout i strona nie mogą dzielić wspólnego kontekstu serwera, ponieważ system kontekstu serwera opiera się na magazynie danych na żądanie (za pomocą mechanizmu [React's cache](https://react.dev/reference/react/cache)), co powoduje, że każdy "kontekst" jest tworzony na nowo dla różnych segmentów aplikacji. Umieszczenie providera w wspólnym layoucie złamałoby tę izolację, uniemożliwiając prawidłowe propagowanie wartości kontekstu serwera do komponentów serwerowych.
```tsx {4,7} fileName="src/components/ClientComponentExample.tsx" codeFormat={["typescript", "esm"]}
"use client";
import type { FC } from "react";
import { useIntlayer } from "next-intlayer";
export const ClientComponentExample: FC = () => {
const content = useIntlayer("client-component-example"); // Utwórz powiązaną deklarację zawartości
return (
{content.title}
{content.content}
);
};
```
```tsx {2} fileName="src/components/ServerComponentExample.tsx" codeFormat={["typescript", "esm"]}
import type { FC } from "react";
import { useIntlayer } from "next-intlayer/server";
export const ServerComponentExample: FC = () => {
const content = useIntlayer("server-component-example"); // Utwórz powiązaną deklarację zawartości
return (
{content.title}
{content.content}
);
};
```
> Jeśli chcesz użyć swojej zawartości w atrybucie `string`, takim jak `alt`, `title`, `href`, `aria-label` itp., musisz wywołać wartość funkcji, na przykład:
> ```html
>
>
>
> ```
> Aby dowiedzieć się więcej o hooku `useIntlayer`, zapoznaj się z [dokumentacją](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/packages/next-intlayer/useIntlayer.md).
> Jeśli Twoja aplikacja już istnieje, możesz użyć [Intlayer Compiler](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/compiler.md) w połączeniu z [poleceniem extract](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/cli/extract.md), aby przekonwertować tysiące komponentów w jedną sekundę.
Skonfiguruj proxy, aby wykrywać preferowaną lokalizację użytkownika:
```typescript fileName="src/proxy.ts" codeFormat={["typescript", "esm", "commonjs"]}
export { intlayerProxy as proxy } from "next-intlayer/proxy";
export const config = {
matcher:
"/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",
};
```
> `intlayerProxy` służy do wykrywania preferowanego języka użytkownika i przekierowywania go na odpowiedni adres URL, zgodnie z [konfiguracją](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/configuration.md). Dodatkowo umożliwia zapisywanie preferowanego języka użytkownika w ciasteczku.
> Jeśli potrzebujesz łączyć kilka proxy razem (na przykład `intlayerProxy` z uwierzytelnianiem lub niestandardowymi proxy), Intlayer udostępnia teraz pomocnika o nazwie `multipleProxies`.
```ts
import { multipleProxies, intlayerProxy } from "next-intlayer/proxy";
import { customProxy } from "@utils/customProxy";
export const proxy = multipleProxies([intlayerProxy, customProxy]);
```
W przypadku, gdy chcesz internacjonalizować swoje metadane, takie jak tytuł Twojej strony, możesz użyć funkcji `generateMetadata` dostarczanej przez Next.js. Wewnątrz możesz pobrać zawartość z funkcji `getIntlayer`, aby przetłumaczyć swoje metadane.
```typescript fileName="src/app/[locale]/metadata.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
import { type Dictionary, t } from "intlayer";
import { Metadata } from "next";
const metadataContent = {
key: "page-metadata",
content: {
title: t({
en: "Create Next App",
fr: "Créer une application Next.js",
es: "Crear una application Next.js",
}),
description: t({
en: "Generated by create next app",
fr: "Généré par create next app",
es: "Generado por create next app",
}),
},
} satisfies Dictionary;
export default metadataContent;
```
```json fileName="src/app/[locale]/metadata.content.json" contentDeclarationFormat="json"
{
"key": "page-metadata",
"content": {
"title": {
"nodeType": "translation",
"translation": {
"en": "Preact logo",
"fr": "Logo Preact",
"es": "Logo Preact"
}
},
"description": {
"nodeType": "translation",
"translation": {
"en": "Generated by create next app",
"fr": "Généré par create next app",
"es": "Generado por create next app"
}
}
}
}
```
````typescript fileName="src/app/[locale]/layout.tsx or src/app/[locale]/page.tsx" codeFormat={["typescript", "esm"]}
import { getIntlayer, getMultilingualUrls } from "intlayer";
import type { Metadata } from "next";
import type { LocalPromiseParams } from "next-intlayer";
export const generateMetadata = async ({
params,
}: LocalPromiseParams): Promise => {
const { locale } = await params;
const metadata = getIntlayer("page-metadata", locale);
/**
* Generuje obiekt zawierający wszystkie url dla każdego języka.
*
* Przykład:
* ```ts
* getMultilingualUrls('/about');
*
* // Zwraca
* // {
* // en: '/about',
* // fr: '/fr/about',
* // es: '/es/about',
* // }
* ```
*/
const multilingualUrls = getMultilingualUrls("/");
const localizedUrl =
multilingualUrls[locale as keyof typeof multilingualUrls];
return {
...metadata,
alternates: {
canonical: localizedUrl,
languages: { ...multilingualUrls, "x-default": "/" },
},
openGraph: {
url: localizedUrl,
},
};
};
// ... Reszta kodu
````
> Zauważ, że funkcja `getIntlayer` zaimportowana z `next-intlayer` zwraca Twoją zawartość opakowaną w `IntlayerNode`, co pozwala na integrację z edytorem wizualnym. Natomiast funkcja `getIntlayer` zaimportowana z `intlayer` zwraca Twoją zawartość bezpośrednio bez dodatkowych właściwości.
Alternatywnie możesz użyć funkcji `getTranslation` do zadeklarowania swoich metadanych. Jednak używanie plików deklaracji treści jest zalecane, aby zautomatyzować tłumaczenie metadanych i w pewnym momencie wyodrębnić zawartość.
```typescript fileName="src/app/[locale]/layout.tsx or src/app/[locale]/page.tsx" codeFormat={["typescript", "esm"]}
import {
type IConfigLocales,
getTranslation,
getMultilingualUrls,
} from "intlayer";
import type { Metadata } from "next";
import type { LocalPromiseParams } from "next-intlayer";
export const generateMetadata = async ({
params,
}: LocalPromiseParams): Promise => {
const { locale } = await params;
const t = (content: IConfigLocales) => getTranslation(content, locale);
return {
title: t({
en: "My title",
fr: "Mon titre",
es: "Mi título",
}),
description: t({
en: "My description",
fr: "Ma description",
es: "Mi descripción",
}),
};
};
// ... Reszta kodu
```
> Dowiedz się więcej o optymalizacji metadanych [w oficjalnej dokumentacji Next.js](https://nextjs.org/docs/app/building-your-application/optimizing/metadata).
Aby zinternacjonalizować swoje pliki `sitemap.xml` i `robots.txt`, możesz użyć funkcji `getMultilingualUrls` dostarczonej przez Intlayer. Ta funkcja pozwala na generowanie wielojęzycznych adresów URL dla Twojej mapy witryny.
```tsx fileName="src/app/sitemap.ts" codeFormat={["typescript", "esm", "commonjs"]}
import { getMultilingualUrls } from "intlayer";
import type { MetadataRoute } from "next";
const sitemap = (): MetadataRoute.Sitemap => [
{
url: "https://example.com",
alternates: {
languages: {
...getMultilingualUrls("https://example.com"),
"x-default": "https://example.com",
},
},
},
{
url: "https://example.com/login",
alternates: {
languages: {
...getMultilingualUrls("https://example.com/login"),
"x-default": "https://example.com/login",
},
},
},
{
url: "https://example.com/register",
alternates: {
languages: {
...getMultilingualUrls("https://example.com/register"),
"x-default": "https://example.com/register",
},
},
},
];
export default sitemap;
```
```tsx fileName="src/app/robots.ts" codeFormat={["typescript", "esm", "commonjs"]}
import type { MetadataRoute } from "next";
import { getMultilingualUrls } from "intlayer";
const getAllMultilingualUrls = (urls: string[]) =>
urls.flatMap((url) => Object.values(getMultilingualUrls(url)) as string[]);
const robots = (): MetadataRoute.Robots => ({
rules: {
userAgent: "*",
allow: ["/"],
disallow: getAllMultilingualUrls(["/login", "/register"]),
},
host: "https://example.com",
sitemap: `https://example.com/sitemap.xml`,
});
export default robots;
```
> Dowiedz się więcej o optymalizacji mapy witryny [w oficjalnej dokumentacji Next.js](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/sitemap). Dowiedz się więcej o optymalizacji pliku robots.txt [w oficjalnej dokumentacji Next.js](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/robots).
Aby zmienić język swojej zawartości w Next.js, zalecanym sposobem jest użycie komponentu `Link` do przekierowania użytkowników na odpowiednią zlokalizowaną stronę. Komponent `Link` umożliwia wstępne pobieranie strony, co pomaga uniknąć pełnego przeładowania strony.
```tsx fileName="src/components/LocaleSwitcher.tsx" codeFormat={["typescript", "esm"]}
"use client";
import type { FC } from "react";
import {
Locales,
getHTMLTextDir,
getLocaleName,
getLocalizedUrl,
} from "intlayer";
import { useLocale } from "next-intlayer";
import Link from "next/link";
export const LocaleSwitcher: FC = () => {
const { locale, pathWithoutLocale, availableLocales, setLocale } =
useLocale();
return (
{availableLocales.map((localeItem) => (
setLocale(localeItem)}
replace // Zapewni, że przycisk "wstecz" w przeglądarce przekieruje do poprzedniej strony
>
{/* Lokalizacja - np. FR */}
{localeItem}
{/* Język w swojej własnej lokalizacji - np. Français */}
{getLocaleName(localeItem, locale)}
{/* Język w bieżącej lokalizacji - np. Francés przy ustawionej lokalizacji Locales.SPANISH */}
{getLocaleName(localeItem)}
{/* Język po angielsku - np. French */}
{getLocaleName(localeItem, Locales.ENGLISH)}
))}
);
};
```
> Alternatywnym sposobem jest użycie funkcji `setLocale` dostarczonej przez hook `useLocale`. Ta funkcja nie pozwala na wstępne pobieranie strony. Zobacz [dokumentację hooka `useLocale`](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/packages/next-intlayer/useLocale.md) po więcej szczegółów.
> Możesz również ustawić funkcję w opcji `onLocaleChange`, aby wywołać niestandardową funkcję, gdy zmieni się lokalizacja.
```tsx fileName="src/components/LocaleSwitcher.tsx"
"use client";
import { useRouter } from "next/navigation";
import { useLocale } from "next-intlayer";
import { getLocalizedUrl } from "intlayer";
// ... Reszta kodu
const router = useRouter();
const { setLocale } = useLocale({
onLocaleChange: (locale) => {
router.push(getLocalizedUrl(pathWithoutLocale, locale));
},
});
return (
);
```
> Referencje dokumentacji:
>
> - [`useLocale` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/packages/next-intlayer/useLocale.md)
> - [`getLocaleName` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/packages/intlayer/getLocaleName.md)
> - [`getLocalizedUrl` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/packages/intlayer/getLocalizedUrl.md)
> - [`getHTMLTextDir` hook](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/packages/intlayer/getHTMLTextDir.md)
> - [atrybut `hrefLang`](https://developers.google.com/search/docs/specialty/international/localized-versions?hl=fr)
> - [atrybut `lang`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang)
> - [atrybut `dir`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir)
> - [atrybut `aria-current`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current)
Aby upewnić się, że nawigacja w Twojej aplikacji szanuje bieżącą lokalizację, możesz stworzyć niestandardowy komponent `Link`. Ten komponent automatycznie poprzedza wewnętrzne adresy URL bieżącym językiem. Na przykład, gdy użytkownik francuskojęzyczny kliknie w link do strony "O nas", zostanie przekierowany do `/fr/about` zamiast do `/about`.
To zachowanie jest przydatne z kilku powodów:
- **SEO i doświadczenie użytkownika**: Zlokalizowane adresy URL pomagają wyszukiwarkom poprawnie indeksować strony specyficzne dla danego języka i dostarczają użytkownikom treści w ich preferowanym języku.
- **Spójność**: Korzystając ze zlokalizowanego linku w całej aplikacji, gwarantujesz, że nawigacja pozostaje w obrębie bieżącej lokalizacji, zapobiegając nieoczekiwanym zmianom języka.
- **Utrzymywalność**: Centralizacja logiki lokalizacji w jednym komponencie upraszcza zarządzanie adresami URL, czyniąc Twoją bazę kodu łatwiejszą w utrzymaniu i rozbudowie w miarę rozwoju aplikacji.
Poniżej znajduje się implementacja zlokalizowanego komponentu `Link` w TypeScript:
```tsx fileName="src/components/Link.tsx" codeFormat={["typescript", "esm"]}
"use client";
import { getLocalizedUrl } from "intlayer";
import NextLink, { type LinkProps as NextLinkProps } from "next/link";
import { useLocale } from "next-intlayer";
import type { PropsWithChildren, FC } from "react";
/**
* Funkcja pomocnicza sprawdzająca, czy dany adres URL jest zewnętrzny.
* Jeśli adres URL zaczyna się od http:// lub https://, jest uważany za zewnętrzny.
*/
export const checkIsExternalLink = (href?: string): boolean =>
/^https?:\/\//.test(href ?? "");
/**
* Niestandardowy komponent Link, który dostosowuje atrybut href w oparciu o bieżącą lokalizację.
* Dla linków wewnętrznych używa `getLocalizedUrl`, aby poprzedzić adres URL lokalizacją (np. /fr/about).
* Zapewnia to, że nawigacja pozostaje w tym samym kontekście lokalizacji.
*/
export const Link: FC> = ({
href,
children,
...props
}) => {
const { locale } = useLocale();
const isExternalLink = checkIsExternalLink(href.toString());
// Jeśli link jest wewnętrzny i podano prawidłowy href, pobierz zlokalizowany adres URL.
const hrefI18n: NextLinkProps["href"] =
href && !isExternalLink ? getLocalizedUrl(href.toString(), locale) : href;
return (
{children}
);
};
```
#### Jak to działa
- **Wykrywanie linków zewnętrznych**:
Funkcja pomocnicza `checkIsExternalLink` określa, czy adres URL jest zewnętrzny. Linki zewnętrzne pozostają niezmienione, ponieważ nie wymagają lokalizacji.
- **Pobieranie bieżącej lokalizacji**:
Hook `useLocale` dostarcza bieżącą lokalizację (np. `fr` dla francuskiego).
- **Lokalizowanie adresu URL**:
Dla linków wewnętrznych (tj. niezewnętrznych), używa się `getLocalizedUrl`, aby automatycznie poprzedzić adres URL bieżącą lokalizacją. Oznacza to, że jeśli Twój użytkownik jest we francuskiej wersji językowej, przekazanie `/about` jako `href` zmieni je na `/fr/about`.
- **Zwracanie linku**:
Komponent zwraca element `` ze zlokalizowanym adresem URL, zapewniając spójność nawigacji z lokalizacją.
Dzięki zintegrowaniu tego komponentu `Link` w całej aplikacji zachowujesz spójne i świadome językowo doświadczenie użytkownika, jednocześnie korzystając z lepszego SEO i użyteczności.
Jeśli potrzebujesz aktywnej lokalizacji wewnątrz Server Action (np. do lokalizacji e-maili lub uruchomienia logiki zależnej od języka), wywołaj `getLocale` z `next-intlayer/server`:
```tsx fileName="src/app/actions/getLocale.ts" codeFormat="typescript"
"use server";
import { getLocale } from "next-intlayer/server";
export const myServerAction = async () => {
const locale = await getLocale();
// Zrób coś z lokalizacją
};
```
> Funkcja `getLocale` stosuje strategię kaskadową, aby określić lokalizację użytkownika:
>
> 1. Najpierw sprawdza nagłówki żądania pod kątem wartości lokalizacji, która mogła zostać ustawiona przez proxy.
> 2. Jeśli nie znaleziono lokalizacji w nagłówkach, szuka lokalizacji zapisanej w ciasteczkach.
> 3. Jeśli nie znaleziono ciasteczka, próbuje wykryć preferowany język użytkownika z ustawień przeglądarki.
> 4. W ostateczności powraca do skonfigurowanej domyślnej lokalizacji aplikacji.
>
> Zapewnia to wybranie najbardziej odpowiedniej lokalizacji na podstawie dostępnego kontekstu.
Podczas korzystania z `next-intlayer`, słowniki są domyślnie dołączane do pakietu dla każdej strony. Aby zoptymalizować rozmiar bundle'a, Intlayer dostarcza opcjonalną wtyczkę SWC, która inteligentnie zastępuje wywołania `useIntlayer` za pomocą makr. Gwarantuje to, że słowniki są dołączane tylko do pakietów stron, które faktycznie ich używają.
Aby włączyć tę optymalizację, zainstaluj pakiet `@intlayer/swc`. Po zainstalowaniu, `next-intlayer` automatycznie wykryje i użyje wtyczki:
```bash packageManager="npm"
npm install @intlayer/swc --save-dev
```
```bash packageManager="pnpm"
pnpm add @intlayer/swc --save-dev
```
```bash packageManager="yarn"
yarn add @intlayer/swc --save-dev
```
```bash packageManager="bun"
bun add @intlayer/swc --dev
```
> Uwaga: Ta optymalizacja jest dostępna tylko dla Next.js 13 i nowszych.
> Uwaga: Ten pakiet nie jest instalowany domyślnie, ponieważ wtyczki SWC są nadal eksperymentalne w Next.js. Może się to zmienić w przyszłości.
> Uwaga: Jeśli ustawisz opcję `importMode: 'dynamic'` lub `importMode: 'fetch'` (w konfiguracji `dictionary`), będzie ona polegać na Suspense, więc będziesz musiał opakować wywołania `useIntlayer` w granicę `Suspense`. Oznacza to, że nie będziesz mógł używać `useIntlayer` bezpośrednio na najwyższym poziomie komponentu Page / Layout.
>
Jeśli masz istniejącą bazę kodu, transformacja tysięcy plików może być czasochłonna.
Aby ułatwić ten proces, Intlayer proponuje [kompilator](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/compiler.md) / [ekstraktor](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/cli/extract.md), aby przetransformować komponenty i wyodrębnić zawartość.
Aby go skonfigurować, możesz dodać sekcję `compiler` w pliku `intlayer.config.ts`:
```typescript fileName="intlayer.config.ts" codeFormat={["typescript", "esm", "commonjs"]}
import { type IntlayerConfig } from "intlayer";
const config: IntlayerConfig = {
// ... Reszta Twojej konfiguracji
compiler: {
/**
* Wskazuje, czy kompilator powinien być włączony.
*/
enabled: true,
/**
* Definiuje ścieżkę plików wyjściowych
*/
output: ({ fileName, extension }) => `./${fileName}${extension}`,
/**
* Wskazuje, czy komponenty powinny zostać zapisane po transformacji. W ten sposób kompilator można uruchomić tylko raz, aby przetransformować aplikację, a następnie go usunąć.
*/
saveComponents: false,
/**
* Prefiks klucza słownika
*/
dictionaryKeyPrefix: "",
},
};
export default config;
```
Uruchom ekstraktor, aby przetransformować komponenty i wyodrębnić zawartość
```bash packageManager="npm"
npx intlayer extract
```
```bash packageManager="pnpm"
pnpm intlayer extract
```
```bash packageManager="yarn"
yarn intlayer extract
```
```bash packageManager="bun"
bun x intlayer extract
```
```bash packageManager="npm"
npm install @intlayer/babel --save-dev
```
```bash packageManager="pnpm"
pnpm add @intlayer/babel --save-dev
```
```bash packageManager="yarn"
yarn add @intlayer/babel --save-dev
```
```bash packageManager="bun"
bun add @intlayer/babel --dev
```
```js fileName="babel.config.js"
const {
intlayerExtractBabelPlugin,
getExtractPluginOptions,
} = require("@intlayer/babel");
module.exports = {
presets: ["next/babel"],
plugins: [
// Wyodrębnij zawartość z komponentów do słowników
[intlayerExtractBabelPlugin, getExtractPluginOptions()],
],
};
```
```bash packageManager="npm"
npm run build # Lub npm run dev
```
```bash packageManager="pnpm"
pnpm run build # Or pnpm run dev
```
```bash packageManager="yarn"
yarn build # Or yarn dev
```
```bash packageManager="bun"
bun run build # Or bun run dev
```
### Obserwuj zmiany słowników w Turbopack
Podczas korzystania z Turbopack jako serwera deweloperskiego za pomocą polecenia `next dev`, zmiany w słownikach nie będą automatycznie wykrywane domyślnie.
To ograniczenie występuje, ponieważ Turbopack nie może uruchamiać wtyczek webpack równolegle, aby monitorować zmiany w plikach zawartości. Aby to obejść, będziesz musiał użyć polecenia `intlayer watch`, aby uruchomić jednocześnie serwer deweloperski i obserwatora budowania Intlayer.
```json5 fileName="package.json"
{
// ... Twoje istniejące konfiguracje package.json
"scripts": {
// ... Twoje istniejące konfiguracje skryptów
"dev": "intlayer watch --with 'next dev'",
},
}
```
> Jeśli używasz next-intlayer@<=6.x.x, musisz zachować flagę `--turbopack`, aby aplikacja Next.js 16 działała poprawnie z Turbopack. Zalecamy używanie next-intlayer@>=7.x.x, aby uniknąć tego ograniczenia.
### Skonfiguruj TypeScript
Intlayer wykorzystuje augmentację modułów, aby czerpać korzyści z TypeScript i wzmacniać Twoją bazę kodu.


Upewnij się, że Twoja konfiguracja TypeScript zawiera automatycznie generowane typy.
```json5 fileName="tsconfig.json"
{
// ... Twoje istniejące konfiguracje TypeScript
"include": [
// ... Twoje istniejące konfiguracje TypeScript
".intlayer/**/*.ts", // Uwzględnij automatycznie generowane typy
],
}
```
### Konfiguracja Git
Zaleca się ignorowanie plików generowanych przez Intlayer. Pozwala to uniknąć ich zatwierdzania w repozytorium Git.
Aby to zrobić, możesz dodać następujące instrukcje do pliku `.gitignore`:
```plaintext fileName=".gitignore"
# Ignoruj pliki generowane przez Intlayer
.intlayer
```
### Rozszerzenie VS Code
Aby poprawić wrażenia z programowania z Intlayer, możesz zainstalować oficjalne **rozszerzenie Intlayer VS Code**.
[Zainstaluj z VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)
To rozszerzenie zapewnia:
- **Autouzupełnianie** kluczy tłumaczeń.
- **Wykrywanie błędów w czasie rzeczywistym** dla brakujących tłumaczeń.
- **Podgląd wierszowy** przetłumaczonej zawartości.
- **Szybkie akcje** do łatwego tworzenia i aktualizowania tłumaczeń.
Aby uzyskać więcej informacji na temat korzystania z rozszerzenia, zapoznaj się z [dokumentacją rozszerzenia Intlayer VS Code](https://intlayer.org/doc/vs-code-extension).
### Idź dalej
Aby pójść dalej, możesz zaimplementować [edytor wizualny](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/intlayer_visual_editor.md) lub wyeksportować swoją zawartość za pomocą [CMS](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pl/intlayer_CMS.md).