Strona głównaPiaskownicaPrezentacjaAplikacjaDokumentacjaBlog
    • Englishangielski
      EN
    • русскийrosyjski
      RU
    • 日本語japoński
      JA
    • françaisfrancuski
      FR
    • 한국어koreański
      KO
    • 中文chiński
      ZH
    • españolhiszpański
      ES
    • Deutschniemiecki
      DE
    • العربيةarabski
      AR
    • italianowłoski
      IT
    • British Englishangielski brytyjski
      EN-GB
    • portuguêsportugalski
      PT
    • हिन्दीhindi
      HI
    • Türkçeturecki
      TR
    • polskipolski
      PL
    • Indonesiaindonezyjski
      ID
    • Tiếng Việtwietnamski
      VI
    • українськаukraiński
      UK
    /
    Filtruj dokumenty według frameworka
    Alt+←
    Dlaczego Intlayer?
    Zacząć
    Koncepcja
    • Jak działa Intlayer
    • Konfiguracja
    • TestFillBuildWatchExtractLoginPushPullConfigurationListVersionEditorLiveDebugDoc ReviewDoc TranslateSDK
    • Edytor wizualny
    • CMS
    • Integracja CI/CD
    • TłumaczenieLiczba mnogaWyliczenieWarunekPłećWstawieniePlikZagnieżdżanieMarkdownHTMLPobieranie funkcji
    • Plik dla każdej lokalizacji
    • Kompilator
    • Automatyczne wypełnianie
    • Testowanie
    • Optymalizacja pakietu
    Środowisko
    • Next.js 14 i App Router
      Next.js 15
      Next.js bez locale URL
      Next.js dan Page Router
      Kompilator
    • Tanstack Start Solid
    • Astro dan React
      Astro dan Svelte
      Astro dan Vue
      Astro dan Solid
      Astro dan Preact
      Astro dan Lit
      Astro dan Vanilla JS
    • React Router v7
      React Router v7 (fs-routes)
      Compiler
    • Nuxt dan Vue
    • Vite dan Solid
    • SvelteKit
    • Vite dan Preact
    • Vite dan Vanilla JS
    • Vite dan Lit
    • Angular 19 (Webpack)
      Analog
    • React CRA
    • React Native dan Expo
    • Express.js
      NestJS
      Fastify
      Hono
      Adonis
    • Lynx dan React
    Plugins
    • JSON
    • gettext (.po)
    Rozszerzenie VS Code
    Agent
    • Serwer MCP
    • Umiejętności agenta
    Wersje
    • v8
    • v7
    • v6
    Benchmark
    • Next.js
    • TanStack
    • Vue
    • Solid
    • Svelte
    Blog
    Zadaj pytanie
    1. Documentation
    2. Środowisko
    3. Astro
    4. Lit
    \n```\n\n> Jeśli chcesz użyć swojej treści w atrybucie `string`, takim jak `alt`, `title`, `href`, `aria-label` itp., możesz użyć wartości funkcji, np.:\n\n> ```html\n> \"{content.image.value}\"\n> \"{content.image.toString()}\"\n> \"{String(content.image)}\"\n> ```\n\n> **Uwaga na temat konfiguracji routingu:**\n> Używana przez Ciebie struktura katalogów zależy od ustawienia `middleware.routing` w `intlayer.config.ts`:\n>\n> - **`prefix-no-default` (domyślnie):** Zachowuje domyślny język w katalogu głównym (bez prefiksu) i dodaje prefiksy do pozostałych. Użyj `[...locale]`, aby obsłużyć wszystkie przypadki.\n> - **`prefix-all`:** Wszystkie adresy URL otrzymują prefiks języka. Możesz użyć standardowego `[locale]`, jeśli nie musisz traktować katalogu głównego oddzielnie.\n> - **`search-param` lub `no-prefix`:** Katalogi językowe nie są wymagane. Język jest zarządzany za pomocą parametrów zapytania lub plików cookie.\n\n### Krok 6: Utworzenie elementu niestandardowego Lit (Custom Element)\n\nUtwórz element niestandardowy Lit. Wywołaj `installIntlayer` w `connectedCallback`, używając atrybutu `locale` opartego na serwerze, aby zainicjować singleton tłumaczeń po stronie klienta.\n\n```typescript fileName=\"src/components/lit/LitDemo.ts\"\nimport { LitElement, html } from \"lit\";\nimport { installIntlayer, useIntlayer, useLocale } from \"lit-intlayer\";\nimport { getLocalizedUrl, getLocaleName, type LocalesValues } from \"intlayer\";\n\nclass LitDemo extends LitElement {\n static properties = {\n locale: { type: String },\n };\n\n locale: LocalesValues = \"en\" as LocalesValues;\n\n private _content = useIntlayer(this, \"lit-demo\");\n private _localeCtrl = useLocale(this, {\n onLocaleChange: (newLocale: LocalesValues) => {\n window.location.href = getLocalizedUrl(\n window.location.pathname,\n newLocale\n );\n },\n });\n\n override connectedCallback() {\n super.connectedCallback();\n // Zainicjuj językiem wykrytym przez serwer\n installIntlayer({ locale: this.locale as any });\n }\n\n override render() {\n const { greeting, description } = this._content;\n const {\n locale: currentLocale,\n availableLocales,\n setLocale,\n } = this._localeCtrl;\n\n return html`\n
    \n

    ${greeting}

    \n

    ${description}

    \n \n
    \n Zmień język:\n
    \n ${availableLocales.map(\n (localeItem) => html`\n setLocale(localeItem)}\n >\n ${getLocaleName(localeItem)}\n ${getLocaleName(localeItem, currentLocale)}\n ${localeItem.toUpperCase()}\n \n `\n )}\n
    \n
    \n
    \n `;\n }\n}\n\ncustomElements.define(\"lit-demo\", LitDemo);\n```\n\n> Atrybut `locale` jest przekazywany ze strony Astro (wykrywanie po stronie serwera) i używany do zainicjowania `installIntlayer` w `connectedCallback`, ustawiając początkowy język dla wszystkich hooków `ReactiveController` wewnątrz elementu.\n\n> `useIntlayer` jest zarejestrowany jako `ReactiveController`. Automatycznie instruuje on komponent o konieczności ponownego renderowania (re-render) przy zmianie języka, więc nie jest wymagana żadna dodatkowa logika subskrypcji.\n\n### Krok 7: Dodanie przełącznika języków\n\nFunkcjonalność przełączania języków jest zintegrowana bezpośrednio z metodą `render()` elementu niestandardowego Lit (patrz krok 6 powyżej). Wykorzystuje ona `useLocale` z `lit-intlayer` i przechodzi do zlokalizowanego adresu URL, gdy użytkownik wybierze nowy język:\n\n```typescript fileName=\"src/components/lit/LitDemo.ts\"\n// Wewnątrz klasy LitElement, po konfiguracji useLocale z kroku 6:\n\nprivate _localeCtrl = useLocale(this, {\n onLocaleChange: (newLocale: LocalesValues) => {\n // Przekieruj do zlokalizowanego adresu URL przy zmianie języka\n window.location.href = getLocalizedUrl(window.location.pathname, newLocale);\n },\n});\n\noverride render() {\n const { locale: currentLocale, availableLocales, setLocale } = this._localeCtrl;\n\n return html`\n
    \n Zmień język:\n
    \n ${availableLocales.map(\n (localeItem) => html`\n setLocale(localeItem)}\n >\n ${getLocaleName(localeItem)}\n ${getLocaleName(localeItem, currentLocale)}\n ${localeItem.toUpperCase()}\n \n `\n )}\n
    \n
    \n `;\n}\n```\n\n> **Uwaga na temat reaktywności Lit:**\n> `useLocale` zwraca `ReactiveController`. Gdy wywoływane jest `setLocale`, kontroler automatycznie żąda ponownego renderowania, aktualizując stan przycisków bez potrzeby ręcznej manipulacji DOM.\n\n> **Uwaga na temat trwałości:**\n> Użycie `onLocaleChange` do przekierowania przez `window.location.href` zapewnia, że nowy adres URL z prefiksem językowym zostanie odwiedzony. Pozwala to oprogramowaniu pośredniczącemu Intlayer ustawić plik cookie języka i zapamiętać preferencje użytkownika przy przyszłych wizytach.\n\n### Krok 8: Sitemap i Robots.txt\n\nIntlayer oferuje narzędzia do dynamicznego generowania zlokalizowanej mapy witryny oraz pliku robots.txt.\n\n#### Sitemap\n\nIntlayer comes with a built-in sitemap generator to help you create a sitemap for your application easily. It handles localized routes and adds the necessary metadata for search engines.\n\n> The Intlayer generated sitemap supports the `xhtml:link` namespace (Hreflang XML Extensions). Unlike the default sitemap generators that only list raw URLs, Intlayer automatically creates the required bidirectional links between all language versions of a page (e.g., `/about`, `/about?lang=fr`, and `/about?lang=es`). This ensures search engines correctly index and serve the right language version to the right audience.\n\nUtwórz plik `src/pages/sitemap.xml.ts`, aby wygenerować mapę witryny obejmującą wszystkie Twoje zlokalizowane trasy.\n\n```typescript fileName=\"src/pages/sitemap.xml.ts\"\nimport type { APIRoute } from \"astro\";\nimport { generateSitemap, type SitemapUrlEntry } from \"intlayer\";\n\nconst pathList: SitemapUrlEntry[] = [\n { path: \"/\", changefreq: \"daily\", priority: 1.0 },\n { path: \"/about\", changefreq: \"monthly\", priority: 0.7 },\n];\n\nconst SITE_URL = import.meta.env.SITE ?? \"http://localhost:4321\";\n\nexport const GET: APIRoute = async ({ site }) => {\n const xmlOutput = generateSitemap(pathList, { siteUrl: SITE_URL });\n\n return new Response(xmlOutput, {\n headers: { \"Content-Type\": \"application/xml\" },\n });\n};\n```\n\n#### Robots.txt\n\nUtwórz plik `src/pages/robots.txt.ts`, aby kontrolować indeksowanie przez wyszukiwarki.\n\n```typescript fileName=\"src/pages/robots.txt.ts\"\nimport type { APIRoute } from \"astro\";\nimport { getMultilingualUrls } from \"intlayer\";\n\nconst getAllMultilingualUrls = (urls: string[]) =>\n urls.flatMap((url) => Object.values(getMultilingualUrls(url)) as string[]);\n\nconst disallowedPaths = getAllMultilingualUrls([\"/admin\", \"/private\"]);\n\nexport const GET: APIRoute = ({ site }) => {\n const robotsTxt = [\n \"User-agent: *\",\n \"Allow: /\",\n ...disallowedPaths.map((path) => `Disallow: ${path}`),\n \"\",\n `Sitemap: ${new URL(\"/sitemap.xml\", site).href}`,\n ].join(\"\\n\");\n\n return new Response(robotsTxt, {\n headers: { \"Content-Type\": \"text/plain\" },\n });\n};\n```\n\n### Konfiguracja TypeScript\n\nIntlayer wykorzystuje rozszerzenie modułów (module augmentation), aby skorzystać z TypeScript, czyniąc bazę kodu bardziej solidną. Jeśli używasz składni dekoratorów, upewnij się, że w opcjach kompilatora włączono `experimentalDecorators`.\n\n![Autocompletion](https://github.com/aymericzip/intlayer/blob/main/docs/assets/autocompletion.png?raw=true)\n\n![Translation Error](https://github.com/aymericzip/intlayer/blob/main/docs/assets/translation_error.png?raw=true)\n\nUpewnij się, że Twoja konfiguracja TypeScript zawiera automatycznie generowane typy.\n\n```json5 fileName=\"tsconfig.json\"\n{\n compilerOptions: {\n // ...\n experimentalDecorators: true,\n useDefineForClassFields: false, // Wymagane dla obsługi dekoratorów w Lit\n },\n \"include\": [\n // ... Twoja istniejąca konfiguracja TypeScript\n \".intlayer/**/*.ts\", // Uwzględnij automatycznie generowane typy\n ],\n}\n```\n\n### Konfiguracja Git\n\nZaleca się ignorowanie plików generowanych przez Intlayer. Zapobiega to ich przesyłaniu do repozytorium Git.\n\nAby to zrobić, dodaj następujące instrukcje do pliku `.gitignore`:\n\n```bash\n# Ignoruj pliki generowane przez Intlayer\n.intlayer\n```\n\n### Rozszerzenie VS Code\n\nAby poprawić wrażenia z programowania z Intlayer, możesz zainstalować **oficjalne rozszerzenie Intlayer dla VS Code**.\n\n[Instalacja z VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=intlayer.intlayer-vs-code-extension)\n\nTo rozszerzenie zapewnia:\n\n- **Autouzupełnianie** kluczy tłumaczeń.\n- **Wykrywanie błędów w czasie rzeczywistym** dla brakujących tłumaczeń.\n- **Podgląd inline** przetłumaczonej treści.\n- **Szybkie akcje** do łatwego tworzenia i aktualizowania tłumaczeń.\n\nWięcej informacji na temat korzystania z rozszerzenia znajdziesz w [dokumentacji rozszerzenia VS Code](https://intlayer.org/doc/vs-code-extension).\n\n---\n\n### (Opcjonalnie) Krok 17 : Wyodrębnij zawartość swoich komponentów\n\nJeśli masz istniejącą bazę kodu, transformacja tysięcy plików może być czasochłonna.\n\nAby ułatwić ten proces, Intlayer proponuje [kompilator](/pl/doc/compiler) / [ekstraktor](/pl/doc/concept/cli/extract), aby przetransformować komponenty i wyodrębnić zawartość.\n\nAby go skonfigurować, możesz dodać sekcję `compiler` w pliku `intlayer.config.ts`:\n\n```typescript fileName=\"intlayer.config.ts\" codeFormat={[\"typescript\", \"esm\", \"commonjs\"]}\nimport { type IntlayerConfig } from \"intlayer\";\n\nconst config: IntlayerConfig = {\n // ... Reszta Twojej konfiguracji\n compiler: {\n /**\n * Wskazuje, czy kompilator powinien być włączony.\n */\n enabled: true,\n\n /**\n * Definiuje ścieżkę plików wyjściowych\n */\n output: ({ fileName, extension }) => `./${fileName}${extension}`,\n\n /**\n * 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ąć.\n */\n saveComponents: false,\n\n /**\n * Prefiks klucza słownika\n */\n dictionaryKeyPrefix: \"\",\n },\n};\n\nexport default config;\n```\n\n\n \n\nUruchom ekstraktor, aby przetransformować komponenty i wyodrębnić zawartość\n\n```bash packageManager=\"npm\"\nnpx intlayer extract\n```\n\n```bash packageManager=\"pnpm\"\npnpm intlayer extract\n```\n\n```bash packageManager=\"yarn\"\nyarn intlayer extract\n```\n\n```bash packageManager=\"bun\"\nbun x intlayer extract\n```\n\n \n \n\nZaktualizuj `vite.config.ts`, aby dołączyć wtyczkę `intlayerCompiler`:\n\n```ts fileName=\"vite.config.ts\"\nimport { defineConfig } from \"vite\";\nimport { intlayer, intlayerCompiler } from \"vite-intlayer\";\n\nexport default defineConfig({\n plugins: [\n intlayer(),\n intlayerCompiler(), // Dodaje wtyczkę kompilatora\n ],\n});\n```\n\n```bash packageManager=\"npm\"\nnpm run build # Lub npm run dev\n```\n\n```bash packageManager=\"pnpm\"\npnpm run build # Or pnpm run dev\n```\n\n```bash packageManager=\"yarn\"\nyarn build # Or yarn dev\n```\n\n```bash packageManager=\"bun\"\nbun run build # Or bun run dev\n```\n\n \n\n\n---\n\n### Pogłębiaj swoją wiedzę\n\nJeśli chcesz dowiedzieć się więcej, możesz również wdrożyć [Edytor Wizualny](/pl/doc/concept/editor) lub użyć [CMS](/pl/doc/concept/cms), aby wyeksternalizować swoją treść.\n","about":"Dowiedz się, jak dodać międzynarodowość (i18n) do swojej witryny Astro + Lit za pomocą Intlayer. Postępuj zgodnie z tym przewodnikiem, aby uczynić swoją witrynę wielojęzyczną.","url":"https://intlayer.org/pl/doc/environment/astro/lit","datePublished":"24-04-2026","dateModified":"06-05-2026","keywords":"międzynarodowość, dokumentacja, Intlayer, Astro, Lit, Web Components, i18n, JavaScript","license":"https://raw.githubusercontent.com/aymericzip/intlayer/refs/heads/main/LICENSE","audience":{"@type":"Audience","audienceType":"Programiści, Menedżerowie treści"}}
    Data utworzenia:2026-04-24Ostatnia aktualizacja:2026-05-06
    Zobacz szablon aplikacji na GitHubie

    Na tej stronie dostępny jest szablon aplikacji.

    Zobacz aplikację pokazową

    Ta strona prowadzi do działającej demonstracji szablonu.

    Prześlij ten dokument do swojego ulubionego asystenta AI
    ChatGPT
    Claude
    DeepSeek
    Google AI mode
    Gemini
    Perplexity
    Mistral
    Grok

    Zadaj pytanie i otrzymaj streszczenie dokumentu, odwołując się do tej strony i wybranego dostawcy AI

    Historia wersji

    1. "Aktualizacja użycia API useIntlayer w Solid do bezpośredniego dostępu do właściwości"
      v8.9.04.05.2026
    2. "Początkowa dokumentacja dla Astro + Lit"
      v8.7.724.04.2026

    Treść tej strony została przetłumaczona przy użyciu sztucznej inteligencji.

    Zobacz ostatnią wersję oryginalnej treści w języku angielskim
    Edytuj tę dokumentację

    Jeśli masz pomysł na ulepszenie tej dokumentacji, zachęcamy do przesłania pull requesta na GitHubie.

    Link do dokumentacji na GitHubie
    Kopiuj

    Kopiuj dokument Markdown do schowka

    Przetłumacz swoją witrynę Astro + Lit za pomocą Intlayer | Międzynarodowość (i18n)

    ide.intlayer.org
    intlayer-astro-template.vercel.app

    Spis treści

    Czym jest Intlayer?

    Intlayer to innowacyjna biblioteka międzynarodowości (i18n) o otwartym kodzie źródłowym, zaprojektowana w celu uproszczenia obsługi wielojęzyczności w nowoczesnych aplikacjach internetowych.

    Dzięki Intlayer możesz:

    • Łatwo zarządzać tłumaczeniami: Korzystając z deklaratywnych słowników na poziomie komponentów.
    • Dynamicznie lokalizować metadane, trasy i treści.
    • Zapewnić obsługę TypeScript: Dzięki automatycznie generowanym typom dla lepszego autouzupełniania i wykrywania błędów.
    • Korzystać z zaawansowanych funkcji: Takich jak dynamiczne wykrywanie języka i przełączanie języków.

    Przewodnik krok po kroku po konfiguracji Intlayer w Astro + Lit

    Sprawdź szablon aplikacji na GitHubie.

    Krok 1: Zainstaluj zależności

    Zainstaluj niezbędne pakiety za pomocą preferowanego menedżera pakietów:

    bash
    Kopiuj kod

    Skopiuj kod do schowka

    npm install intlayer astro-intlayer lit lit-intlayer @astrojs/litnpx intlayer init
    • intlayer Główny pakiet zapewniający narzędzia i18n do zarządzania konfiguracją, tłumaczeniami, deklaracją treści, transpilacją i poleceniami CLI.

    • astro-intlayer Wtyczka integracyjna Astro służąca do połączenia Intlayer z bundlerem Vite; zawiera również oprogramowanie pośredniczące (middleware) do wykrywania preferowanego języka użytkownika, zarządzania plikami cookie i obsługi przekierowań URL.

    • lit Podstawowe pakiety Lit do budowania szybkich, lekkich komponentów Web Components.

    • lit-intlayer Pakiet do integracji Intlayer z aplikacjami Lit. Zapewnia hooki oparte na ReactiveController (useIntlayer, useLocale itp.), które automatycznie instruują LitElement o konieczności ponownego renderowania przy zmianie języka.

    • @astrojs/lit Oficjalna integracja Astro pozwalająca na używanie elementów niestandardowych (custom elements) Lit wewnątrz stron Astro.

    Krok 2: Skonfiguruj swój projekt

    Utwórz plik konfiguracyjny, aby zdefiniować języki swojej aplikacji:

    intlayer.config.ts
    Kopiuj kod

    Skopiuj kod do schowka

    import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [      Locales.ENGLISH,      Locales.FRENCH,      Locales.SPANISH,      Locales.POLISH,      // Twoje inne języki    ],    defaultLocale: Locales.ENGLISH,  },};export default config;
    Za pośrednictwem tego pliku konfiguracyjnego możesz ustawić zlokalizowane adresy URL, przekierowania oprogramowania pośredniczącego, nazwy plików cookie, lokalizację i rozszerzenia deklaracji treści, wyłączyć dzienniki Intlayer w konsoli i wiele więcej. Pełną listę dostępnych parametrów znajdziesz w dokumentacji konfiguracji.

    Krok 3: Zintegruj Intlayer ze swoją konfiguracją Astro

    Dodaj wtyczkę intlayer do konfiguracji Astro oraz integrację Lit.

    astro.config.ts
    Kopiuj kod

    Skopiuj kod do schowka

    // @ts-checkimport { intlayer } from "astro-intlayer";import lit from "@astrojs/lit";import { defineConfig } from "astro/config";// https://astro.build/configexport default defineConfig({  integrations: [intlayer(), lit()],});
    Wtyczka integracyjna intlayer() służy do integracji Intlayer z Astro. Zapewnia ona generowanie plików deklaracji treści i monitoruje je w trybie deweloperskim. Definiuje zmienne środowiskowe Intlayer w aplikacji Astro i udostępnia aliasy w celu optymalizacji wydajności.
    Integracja lit() pozwala na używanie elementów niestandardowych Lit wewnątrz stron Astro.

    Krok 4: Zadeklaruj swoją treść

    Twórz i zarządzaj swoimi deklaracjami treści, aby przechowywać tłumaczenia:

    src/components/lit/app.content.ts
    Kopiuj kod

    Skopiuj kod do schowka

    import { t, type Dictionary } from "intlayer";const litDemoContent = {  key: "lit-demo",  content: {    greeting: t({      en: "Hello World",      fr: "Bonjour le monde",      es: "Hola mundo",      pl: "Witaj świecie",    }),    description: t({      en: "Welcome to my multilingual Astro + Lit site.",      fr: "Bienvenue sur mon site Astro + Lit multilingue.",      es: "Bienvenido a mi sitio Astro + Lit multilingüe.",      pl: "Witaj na mojej wielojęzycznej stronie Astro + Lit.",    }),  },} satisfies Dictionary;export default litDemoContent;
    Deklaracje treści mogą być definiowane w dowolnym miejscu aplikacji, pod warunkiem, że są zawarte w contentDir (domyślnie ./src) i pasują do rozszerzenia pliku deklaracji treści (domyślnie .content.{json,ts,tsx,js,jsx,mjs,cjs}).
    Więcej informacji znajdziesz w dokumentacji deklaracji treści.

    Krok 5: Korzystanie z treści w Astro

    Możesz konsumować słowniki bezpośrednio w swoich plikach .astro, używając podstawowych pomocników wyeksportowanych z intlayer. Powinieneś również dodać metadane SEO (takie jak linki hreflang i kanoniczne) na każdej stronie. Elementy niestandardowe Lit są importowane za pomocą bloku <script> po stronie klienta i umieszczane w body.

    src/pages/[...locale]/index.astro
    Kopiuj kod

    Skopiuj kod do schowka

    ---import {  getIntlayer,  getLocaleFromPath,  getLocalizedUrl,  getHTMLTextDir,  getPrefix,  localeMap,  defaultLocale,  type LocalesValues,} from "intlayer";export const getStaticPaths = () => {  return localeMap(({ locale }) => ({    params: { locale: getPrefix(locale).localePrefix },  }));};const locale = getLocaleFromPath(Astro.url.pathname) as LocalesValues;const { greeting } = getIntlayer("lit-demo", locale);---<!doctype html><html lang={locale} dir={getHTMLTextDir(locale)}>  <head>    <meta charset="utf-8" />    <meta name="viewport" content="width=device-width" />    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />    <title>{greeting}</title>    <!-- Link kanoniczny -->    <link      rel="canonical"      href={new URL(getLocalizedUrl(Astro.url.pathname, locale), Astro.site)}    />    <!-- Linki hreflang -->    {      localeMap(({ locale: mapLocale }) => (        <link          rel="alternate"          hreflang={mapLocale}          href={new URL(            getLocalizedUrl(Astro.url.pathname, mapLocale),            Astro.site          )}        />      ))    }    <link      rel="alternate"      hreflang="x-default"      href={new URL(        getLocalizedUrl(Astro.url.pathname, defaultLocale),        Astro.site      )}    />  </head>  <body>    <!-- Element niestandardowy Lit - otrzymuje język wykryty przez serwer jako atrybut -->    <lit-demo locale={locale}></lit-demo>  </body></html><script>  import "../../components/lit/LitDemo";</script>
    Jeśli chcesz użyć swojej treści w atrybucie string, takim jak alt, title, href, aria-label itp., możesz użyć wartości funkcji, np.:
    html
    Kopiuj kod

    Skopiuj kod do schowka

    <img src="{content.image.src.value}" alt="{content.image.value}" /><img src="{content.image.src.toString()}" alt="{content.image.toString()}" /><img src="{String(content.image.src)}" alt="{String(content.image)}" />

    Uwaga na temat konfiguracji routingu: Używana przez Ciebie struktura katalogów zależy od ustawienia middleware.routing w intlayer.config.ts:

    • prefix-no-default (domyślnie): Zachowuje domyślny język w katalogu głównym (bez prefiksu) i dodaje prefiksy do pozostałych. Użyj [...locale], aby obsłużyć wszystkie przypadki.
    • prefix-all: Wszystkie adresy URL otrzymują prefiks języka. Możesz użyć standardowego [locale], jeśli nie musisz traktować katalogu głównego oddzielnie.
    • search-param lub no-prefix: Katalogi językowe nie są wymagane. Język jest zarządzany za pomocą parametrów zapytania lub plików cookie.

    Krok 6: Utworzenie elementu niestandardowego Lit (Custom Element)

    Utwórz element niestandardowy Lit. Wywołaj installIntlayer w connectedCallback, używając atrybutu locale opartego na serwerze, aby zainicjować singleton tłumaczeń po stronie klienta.

    src/components/lit/LitDemo.ts
    Kopiuj kod

    Skopiuj kod do schowka

    import { LitElement, html } from "lit";import { installIntlayer, useIntlayer, useLocale } from "lit-intlayer";import { getLocalizedUrl, getLocaleName, type LocalesValues } from "intlayer";class LitDemo extends LitElement {  static properties = {    locale: { type: String },  };  locale: LocalesValues = "en" as LocalesValues;  private _content = useIntlayer(this, "lit-demo");  private _localeCtrl = useLocale(this, {    onLocaleChange: (newLocale: LocalesValues) => {      window.location.href = getLocalizedUrl(        window.location.pathname,        newLocale      );    },  });  override connectedCallback() {    super.connectedCallback();    // Zainicjuj językiem wykrytym przez serwer    installIntlayer({ locale: this.locale as any });  }  override render() {    const { greeting, description } = this._content;    const {      locale: currentLocale,      availableLocales,      setLocale,    } = this._localeCtrl;    return html`      <div>        <h1>${greeting}</h1>        <p>${description}</p>        <!-- Przełącznik języków renderowany wewnątrz LitElement -->        <div class="locale-switcher">          <span class="switcher-label">Zmień język:</span>          <div class="locale-buttons">            ${availableLocales.map(              (localeItem) => html`                <button                  class="locale-btn ${localeItem === currentLocale                    ? "active"                    : ""}"                  ?disabled=${localeItem === currentLocale}                  @click=${() => setLocale(localeItem)}                >                  <span class="ls-own-name">${getLocaleName(localeItem)}</span>                  <span class="ls-current-name"                    >${getLocaleName(localeItem, currentLocale)}</span                  >                  <span class="ls-code">${localeItem.toUpperCase()}</span>                </button>              `            )}          </div>        </div>      </div>    `;  }}customElements.define("lit-demo", LitDemo);
    Atrybut locale jest przekazywany ze strony Astro (wykrywanie po stronie serwera) i używany do zainicjowania installIntlayer w connectedCallback, ustawiając początkowy język dla wszystkich hooków ReactiveController wewnątrz elementu.
    useIntlayer jest zarejestrowany jako ReactiveController. Automatycznie instruuje on komponent o konieczności ponownego renderowania (re-render) przy zmianie języka, więc nie jest wymagana żadna dodatkowa logika subskrypcji.

    Krok 7: Dodanie przełącznika języków

    Funkcjonalność przełączania języków jest zintegrowana bezpośrednio z metodą render() elementu niestandardowego Lit (patrz krok 6 powyżej). Wykorzystuje ona useLocale z lit-intlayer i przechodzi do zlokalizowanego adresu URL, gdy użytkownik wybierze nowy język:

    src/components/lit/LitDemo.ts
    Kopiuj kod

    Skopiuj kod do schowka

    // Wewnątrz klasy LitElement, po konfiguracji useLocale z kroku 6:private _localeCtrl = useLocale(this, {  onLocaleChange: (newLocale: LocalesValues) => {    // Przekieruj do zlokalizowanego adresu URL przy zmianie języka    window.location.href = getLocalizedUrl(window.location.pathname, newLocale);  },});override render() {  const { locale: currentLocale, availableLocales, setLocale } = this._localeCtrl;  return html`    <div class="locale-switcher">      <span class="switcher-label">Zmień język:</span>      <div class="locale-buttons">        ${availableLocales.map(          (localeItem) => html`            <button              class="locale-btn ${localeItem === currentLocale ? "active" : ""}"              ?disabled=${localeItem === currentLocale}              @click=${() => setLocale(localeItem)}            >              <span class="ls-own-name">${getLocaleName(localeItem)}</span>              <span class="ls-current-name">${getLocaleName(localeItem, currentLocale)}</span>              <span class="ls-code">${localeItem.toUpperCase()}</span>            </button>          `        )}      </div>    </div>  `;}

    Uwaga na temat reaktywności Lit: useLocale zwraca ReactiveController. Gdy wywoływane jest setLocale, kontroler automatycznie żąda ponownego renderowania, aktualizując stan przycisków bez potrzeby ręcznej manipulacji DOM.

    Uwaga na temat trwałości: Użycie onLocaleChange do przekierowania przez window.location.href zapewnia, że nowy adres URL z prefiksem językowym zostanie odwiedzony. Pozwala to oprogramowaniu pośredniczącemu Intlayer ustawić plik cookie języka i zapamiętać preferencje użytkownika przy przyszłych wizytach.

    Krok 8: Sitemap i Robots.txt

    Intlayer oferuje narzędzia do dynamicznego generowania zlokalizowanej mapy witryny oraz pliku robots.txt.

    Sitemap

    Intlayer comes with a built-in sitemap generator to help you create a sitemap for your application easily. It handles localized routes and adds the necessary metadata for search engines.

    The Intlayer generated sitemap supports the xhtml:link namespace (Hreflang XML Extensions). Unlike the default sitemap generators that only list raw URLs, Intlayer automatically creates the required bidirectional links between all language versions of a page (e.g., /about, /about?lang=fr, and /about?lang=es). This ensures search engines correctly index and serve the right language version to the right audience.

    Utwórz plik src/pages/sitemap.xml.ts, aby wygenerować mapę witryny obejmującą wszystkie Twoje zlokalizowane trasy.

    src/pages/sitemap.xml.ts
    Kopiuj kod

    Skopiuj kod do schowka

    import type { APIRoute } from "astro";import { generateSitemap, type SitemapUrlEntry } from "intlayer";const pathList: SitemapUrlEntry[] = [  { path: "/", changefreq: "daily", priority: 1.0 },  { path: "/about", changefreq: "monthly", priority: 0.7 },];const SITE_URL = import.meta.env.SITE ?? "http://localhost:4321";export const GET: APIRoute = async ({ site }) => {  const xmlOutput = generateSitemap(pathList, { siteUrl: SITE_URL });  return new Response(xmlOutput, {    headers: { "Content-Type": "application/xml" },  });};

    Robots.txt

    Utwórz plik src/pages/robots.txt.ts, aby kontrolować indeksowanie przez wyszukiwarki.

    src/pages/robots.txt.ts
    Kopiuj kod

    Skopiuj kod do schowka

    import type { APIRoute } from "astro";import { getMultilingualUrls } from "intlayer";const getAllMultilingualUrls = (urls: string[]) =>  urls.flatMap((url) => Object.values(getMultilingualUrls(url)) as string[]);const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);export const GET: APIRoute = ({ site }) => {  const robotsTxt = [    "User-agent: *",    "Allow: /",    ...disallowedPaths.map((path) => `Disallow: ${path}`),    "",    `Sitemap: ${new URL("/sitemap.xml", site).href}`,  ].join("\n");  return new Response(robotsTxt, {    headers: { "Content-Type": "text/plain" },  });};

    Konfiguracja TypeScript

    Intlayer wykorzystuje rozszerzenie modułów (module augmentation), aby skorzystać z TypeScript, czyniąc bazę kodu bardziej solidną. Jeśli używasz składni dekoratorów, upewnij się, że w opcjach kompilatora włączono experimentalDecorators.

    Autocompletion

    Translation Error

    Upewnij się, że Twoja konfiguracja TypeScript zawiera automatycznie generowane typy.

    tsconfig.json
    Kopiuj kod

    Skopiuj kod do schowka

    {  compilerOptions: {    // ...    experimentalDecorators: true,    useDefineForClassFields: false, // Wymagane dla obsługi dekoratorów w Lit  },  "include": [    // ... Twoja istniejąca konfiguracja TypeScript    ".intlayer/**/*.ts", // Uwzględnij automatycznie generowane typy  ],}

    Konfiguracja Git

    Zaleca się ignorowanie plików generowanych przez Intlayer. Zapobiega to ich przesyłaniu do repozytorium Git.

    Aby to zrobić, dodaj następujące instrukcje do pliku .gitignore:

    bash
    Kopiuj kod

    Skopiuj kod do schowka

    # Ignoruj pliki generowane przez Intlayer.intlayer

    Rozszerzenie VS Code

    Aby poprawić wrażenia z programowania z Intlayer, możesz zainstalować oficjalne rozszerzenie Intlayer dla VS Code.

    Instalacja z VS Code Marketplace

    To rozszerzenie zapewnia:

    • Autouzupełnianie kluczy tłumaczeń.
    • Wykrywanie błędów w czasie rzeczywistym dla brakujących tłumaczeń.
    • Podgląd inline przetłumaczonej treści.
    • Szybkie akcje do łatwego tworzenia i aktualizowania tłumaczeń.

    Więcej informacji na temat korzystania z rozszerzenia znajdziesz w dokumentacji rozszerzenia VS Code.


    (Opcjonalnie) Krok 17 : Wyodrębnij zawartość swoich komponentów

    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 / ekstraktor, aby przetransformować komponenty i wyodrębnić zawartość.

    Aby go skonfigurować, możesz dodać sekcję compiler w pliku intlayer.config.ts:

    intlayer.config.ts
    Kopiuj kod

    Skopiuj kod do schowka

    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
    Kopiuj kod

    Skopiuj kod do schowka

    npx intlayer extract

    Zaktualizuj vite.config.ts, aby dołączyć wtyczkę intlayerCompiler:

    vite.config.ts
    Kopiuj kod

    Skopiuj kod do schowka

    import { defineConfig } from "vite";import { intlayer, intlayerCompiler } from "vite-intlayer";export default defineConfig({ plugins: [   intlayer(),   intlayerCompiler(), // Dodaje wtyczkę kompilatora ],});
    bash
    Kopiuj kod

    Skopiuj kod do schowka

    npm run build # Lub npm run dev

    Pogłębiaj swoją wiedzę

    Jeśli chcesz dowiedzieć się więcej, możesz również wdrożyć Edytor Wizualny lub użyć CMS, aby wyeksternalizować swoją treść.

    Astro dan Preact
    Astro dan Vanilla JS
    Alt+→

    Na tej stronie

      Dyskusje są anonimowe i regularnie przeglądane w celu rozwiązania typowych problemów. Podziel się pomysłami na funkcje, opinią o dokumentacji lub czymkolwiek związanym z Intlayer, wykorzystujemy te informacje do kształtowania naszej mapy drogowej i ulepszania produktu.

      npm install intlayer astro-intlayer lit lit-intlayer @astrojs/litnpx intlayer init
      import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [      Locales.ENGLISH,      Locales.FRENCH,      Locales.SPANISH,      Locales.POLISH,      // Twoje inne języki    ],    defaultLocale: Locales.ENGLISH,  },};export default config;
      // @ts-checkimport { intlayer } from "astro-intlayer";import lit from "@astrojs/lit";import { defineConfig } from "astro/config";// https://astro.build/configexport default defineConfig({  integrations: [intlayer(), lit()],});
      import { t, type Dictionary } from "intlayer";const litDemoContent = {  key: "lit-demo",  content: {    greeting: t({      en: "Hello World",      fr: "Bonjour le monde",      es: "Hola mundo",      pl: "Witaj świecie",    }),    description: t({      en: "Welcome to my multilingual Astro + Lit site.",      fr: "Bienvenue sur mon site Astro + Lit multilingue.",      es: "Bienvenido a mi sitio Astro + Lit multilingüe.",      pl: "Witaj na mojej wielojęzycznej stronie Astro + Lit.",    }),  },} satisfies Dictionary;export default litDemoContent;
      ---import {  getIntlayer,  getLocaleFromPath,  getLocalizedUrl,  getHTMLTextDir,  getPrefix,  localeMap,  defaultLocale,  type LocalesValues,} from "intlayer";export const getStaticPaths = () => {  return localeMap(({ locale }) => ({    params: { locale: getPrefix(locale).localePrefix },  }));};const locale = getLocaleFromPath(Astro.url.pathname) as LocalesValues;const { greeting } = getIntlayer("lit-demo", locale);---<!doctype html><html lang={locale} dir={getHTMLTextDir(locale)}>  <head>    <meta charset="utf-8" />    <meta name="viewport" content="width=device-width" />    <link rel="icon" type="image/svg+xml" href="/favicon.svg" />    <title>{greeting}</title>    <!-- Link kanoniczny -->    <link      rel="canonical"      href={new URL(getLocalizedUrl(Astro.url.pathname, locale), Astro.site)}    />    <!-- Linki hreflang -->    {      localeMap(({ locale: mapLocale }) => (        <link          rel="alternate"          hreflang={mapLocale}          href={new URL(            getLocalizedUrl(Astro.url.pathname, mapLocale),            Astro.site          )}        />      ))    }    <link      rel="alternate"      hreflang="x-default"      href={new URL(        getLocalizedUrl(Astro.url.pathname, defaultLocale),        Astro.site      )}    />  </head>  <body>    <!-- Element niestandardowy Lit - otrzymuje język wykryty przez serwer jako atrybut -->    <lit-demo locale={locale}></lit-demo>  </body></html><script>  import "../../components/lit/LitDemo";</script>
      <img src="{content.image.src.value}" alt="{content.image.value}" /><img src="{content.image.src.toString()}" alt="{content.image.toString()}" /><img src="{String(content.image.src)}" alt="{String(content.image)}" />
      import { LitElement, html } from "lit";import { installIntlayer, useIntlayer, useLocale } from "lit-intlayer";import { getLocalizedUrl, getLocaleName, type LocalesValues } from "intlayer";class LitDemo extends LitElement {  static properties = {    locale: { type: String },  };  locale: LocalesValues = "en" as LocalesValues;  private _content = useIntlayer(this, "lit-demo");  private _localeCtrl = useLocale(this, {    onLocaleChange: (newLocale: LocalesValues) => {      window.location.href = getLocalizedUrl(        window.location.pathname,        newLocale      );    },  });  override connectedCallback() {    super.connectedCallback();    // Zainicjuj językiem wykrytym przez serwer    installIntlayer({ locale: this.locale as any });  }  override render() {    const { greeting, description } = this._content;    const {      locale: currentLocale,      availableLocales,      setLocale,    } = this._localeCtrl;    return html`      <div>        <h1>${greeting}</h1>        <p>${description}</p>        <!-- Przełącznik języków renderowany wewnątrz LitElement -->        <div class="locale-switcher">          <span class="switcher-label">Zmień język:</span>          <div class="locale-buttons">            ${availableLocales.map(              (localeItem) => html`                <button                  class="locale-btn ${localeItem === currentLocale                    ? "active"                    : ""}"                  ?disabled=${localeItem === currentLocale}                  @click=${() => setLocale(localeItem)}                >                  <span class="ls-own-name">${getLocaleName(localeItem)}</span>                  <span class="ls-current-name"                    >${getLocaleName(localeItem, currentLocale)}</span                  >                  <span class="ls-code">${localeItem.toUpperCase()}</span>                </button>              `            )}          </div>        </div>      </div>    `;  }}customElements.define("lit-demo", LitDemo);
      // Wewnątrz klasy LitElement, po konfiguracji useLocale z kroku 6:private _localeCtrl = useLocale(this, {  onLocaleChange: (newLocale: LocalesValues) => {    // Przekieruj do zlokalizowanego adresu URL przy zmianie języka    window.location.href = getLocalizedUrl(window.location.pathname, newLocale);  },});override render() {  const { locale: currentLocale, availableLocales, setLocale } = this._localeCtrl;  return html`    <div class="locale-switcher">      <span class="switcher-label">Zmień język:</span>      <div class="locale-buttons">        ${availableLocales.map(          (localeItem) => html`            <button              class="locale-btn ${localeItem === currentLocale ? "active" : ""}"              ?disabled=${localeItem === currentLocale}              @click=${() => setLocale(localeItem)}            >              <span class="ls-own-name">${getLocaleName(localeItem)}</span>              <span class="ls-current-name">${getLocaleName(localeItem, currentLocale)}</span>              <span class="ls-code">${localeItem.toUpperCase()}</span>            </button>          `        )}      </div>    </div>  `;}
      import type { APIRoute } from "astro";import { generateSitemap, type SitemapUrlEntry } from "intlayer";const pathList: SitemapUrlEntry[] = [  { path: "/", changefreq: "daily", priority: 1.0 },  { path: "/about", changefreq: "monthly", priority: 0.7 },];const SITE_URL = import.meta.env.SITE ?? "http://localhost:4321";export const GET: APIRoute = async ({ site }) => {  const xmlOutput = generateSitemap(pathList, { siteUrl: SITE_URL });  return new Response(xmlOutput, {    headers: { "Content-Type": "application/xml" },  });};
      import type { APIRoute } from "astro";import { getMultilingualUrls } from "intlayer";const getAllMultilingualUrls = (urls: string[]) =>  urls.flatMap((url) => Object.values(getMultilingualUrls(url)) as string[]);const disallowedPaths = getAllMultilingualUrls(["/admin", "/private"]);export const GET: APIRoute = ({ site }) => {  const robotsTxt = [    "User-agent: *",    "Allow: /",    ...disallowedPaths.map((path) => `Disallow: ${path}`),    "",    `Sitemap: ${new URL("/sitemap.xml", site).href}`,  ].join("\n");  return new Response(robotsTxt, {    headers: { "Content-Type": "text/plain" },  });};
      {  compilerOptions: {    // ...    experimentalDecorators: true,    useDefineForClassFields: false, // Wymagane dla obsługi dekoratorów w Lit  },  "include": [    // ... Twoja istniejąca konfiguracja TypeScript    ".intlayer/**/*.ts", // Uwzględnij automatycznie generowane typy  ],}
      # Ignoruj pliki generowane przez Intlayer.intlayer
      npx intlayer extract
      import { defineConfig } from "vite";import { intlayer, intlayerCompiler } from "vite-intlayer";export default defineConfig({ plugins: [   intlayer(),   intlayerCompiler(), // Dodaje wtyczkę kompilatora ],});
      npm run build # Lub npm run dev