Автор:
    Дата створення:2024-08-13Останнє оновлення:2026-06-23

    Реалізація користувацьких правил переписування URL

    Intlayer підтримує користувацькі правила переписування URL, що дозволяють визначати локалезовані шляхи, які відрізняються від стандартної структури /locale/path. Це дає змогу використовувати такі URL, як /about для англійської та /a-propos для французької, водночас зберігаючи канонічну внутрішню логіку застосунку.

    Конфігурація

    Користувацькі перенаписування налаштовуються в розділі routing файлу intlayer.config.ts з використанням форматерів, специфічних для фреймворку. Ці форматери забезпечують правильний синтаксис для вашого обраного роутера.

    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    import { nextjsRewrite } from "intlayer/routing";
    
    const config: IntlayerConfig = {
    // ... (інші налаштування)
    routing: {
      mode: "prefix-no-default",
      rewrite: nextjsRewrite({
        "/[locale]/about": {
          fr: "/[locale]/a-propos",
          es: "/[locale]/acerca-de",
        },
        "/[locale]/products/[id]": {
          fr: "/[locale]/produits/[id]",
          es: "/[locale]/productos/[id]",
        },
      }),
    },
    };
    
    export default config;
    
    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    import { reactRouterRewrite } from "intlayer/routing";
    
    const config: IntlayerConfig = {
    // ...
    routing: {
      mode: "prefix-all",
      rewrite: reactRouterRewrite({
        "/:locale/about": {
          fr: "/:locale/a-propos",
          es: "/:locale/acerca-de",
        },
        "/:locale/products/:id": {
          fr: "/:locale/produits/:id",
          es: "/:locale/productos/:id",
        },
      }),
    },
    };
    
    export default config;
    
    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    import { tanstackRouterRewrite } from "intlayer/routing";
    
    const config: IntlayerConfig = {
    // ...
    routing: {
      mode: "prefix-all",
      rewrite: tanstackRouterRewrite({
        "/$locale/about": {
          fr: "/$locale/a-propos",
          es: "/$locale/acerca-de",
        },
        "/$locale/products/$id": {
          fr: "/$locale/produits/$id",
          es: "/$locale/productos/$id",
        },
      }),
    },
    };
    
    export default config;
    
    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    import { vueRouterRewrite } from "intlayer/routing";
    
    const config: IntlayerConfig = {
    // ...
    routing: {
      mode: "prefix-all",
      rewrite: vueRouterRewrite({
        "/:locale/about": {
          fr: "/:locale/a-propos",
          es: "/:locale/acerca-de",
        },
        "/:locale/products/:id": {
          fr: "/:locale/produits/:id",
          es: "/:locale/productos/:id",
        },
      }),
    },
    };
    
    export default config;
    
    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    import { svelteKitRewrite } from "intlayer/routing";
    
    const config: IntlayerConfig = {
    // ...
    routing: {
      mode: "prefix-all",
      rewrite: svelteKitRewrite({
        "/[locale]/about": {
          fr: "/[locale]/a-propos",
          es: "/[locale]/acerca-de",
        },
        "/[locale]/products/[id]": {
          fr: "/[locale]/produits/[id]",
          es: "/[locale]/productos/[id]",
        },
      }),
    },
    };
    
    export default config;
    
    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    import { solidRouterRewrite } from "intlayer/routing";
    
    const config: IntlayerConfig = {
    // ...
    routing: {
      mode: "prefix-all",
      rewrite: solidRouterRewrite({
        "/:locale/about": {
          fr: "/:locale/a-propos",
          es: "/:locale/acerca-de",
        },
        "/:locale/products/:id": {
          fr: "/:locale/produits/:id",
          es: "/:locale/productos/:id",
        },
      }),
    },
    };
    
    export default config;
    
    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";
    import { nuxtRewrite } from "intlayer/routing";
    
    const config: IntlayerConfig = {
    // ...
    routing: {
      mode: "prefix-all",
      rewrite: nuxtRewrite({
        "/[locale]/about": {
          fr: "/[locale]/a-propos",
          es: "/[locale]/acerca-de",
        },
        "/[locale]/products/[id]": {
          fr: "/[locale]/produits/[id]",
          es: "/[locale]/productos/[id]",
        },
      }),
    },
    };
    
    export default config;
    

    Доступні форматери

    Intlayer надає форматери для всіх популярних фреймворків:

    • nextjsRewrite: Для Next.js App Router. Підтримує [slug], [...slug] (1+), та [[...slug]] (0+).
    • svelteKitRewrite: Для SvelteKit. Підтримує [slug], [...path] (0+), та [[optional]] (0-1).
    • reactRouterRewrite: Для React Router. Підтримує :slug та * (0+).
    • vueRouterRewrite: Для Vue Router 4. Підтримує :slug, :slug? (0-1), :slug* (0+), та :slug+ (1+).
    • solidRouterRewrite: Для Solid Router. Підтримує :slug та *slug (0+).
    • tanstackRouterRewrite: Для TanStack Router. Підтримує $slug та * (0+).
    • nuxtRewrite: Для Nuxt 3. Підтримує [slug] та [...slug] (0+).
    • viteRewrite: Універсальний форматер для будь-якого проєкту на базі Vite. Нормалізує синтаксис для Vite proxy.

    Розширені шаблони

    Intlayer внутрішньо нормалізує ці шаблони до уніфікованого синтаксису, що дозволяє здійснювати складне зіставлення й генерацію шляхів:

    • Необов'язкові сегменти: [[optional]] (SvelteKit) або :slug? (Vue/React) підтримуються.
    • Catch-all (нуль або більше): [[...slug]] (Next.js), [...path] (SvelteKit/Nuxt), або * (React/TanStack) дозволяють відповідати кільком сегментам.
    • Обов'язковий catch-all (один або більше): [...slug] (Next.js) або :slug+ (Vue) забезпечують наявність принаймні одного сегмента.

    Корекція URL на стороні клієнта: useRewriteURL

    Щоб адресний рядок браузера завжди відображав "pretty" локалізований URL, Intlayer надає хук useRewriteURL. Цей хук непомітно оновлює URL за допомогою window.history.replaceState, коли користувач потрапляє на канонічний шлях.

    Використання у фреймворках

    tsx
    'use client';
    
    import { useRewriteURL } from "next-intlayer";
    
    const MyLayout = ({ children }) => {
    useRewriteURL(); // Автоматично виправляє /fr/about на /fr/a-propos
    return <>{children}</>;
    };
    
    tsx
    'use client';
    
    import { useRewriteURL } from "react-intlayer";
    
    const MyLayout = ({ children }) => {
    useRewriteURL(); // Автоматично виправляє /fr/about на /fr/a-propos
    
    return <>{children}</>;
    };
    
    vue
    <script setup>
    import { useRewriteURL } from "vue-intlayer";
    
    useRewriteURL();
    </script>
    
    
    tsx
    import { useRewriteURL } from "solid-intlayer";
    
    const Layout = (props) => {
    useRewriteURL();
    return <>{props.children}</>;
    };
    
    svelte
    <script>
    import { useRewriteURL } from "svelte-intlayer";
    
    useRewriteURL();
    </script>
    
    

    Інтеграція маршрутизатора та проксі

    Серверні проксі Intlayer (Vite і Next.js) автоматично обробляють кастомні переписування, щоб забезпечити узгодженість для SEO.

    1. Внутрішні переписування: Коли користувач заходить на /fr/a-propos, проксі внутрішньо відображає це на /fr/about, щоб ваш фреймворк відповідав правильному маршруту.
    2. Авторитетні редиректи: Якщо користувач вручну вводить /fr/about, проксі відправляє 301/302 редирект на /fr/a-propos, гарантуючи, що пошукові системи індексують лише одну версію сторінки.

    Інтеграція з Next.js

    Інтеграція з Next.js повністю здійснюється через middleware intlayerProxy.

    middleware.ts
    import { intlayerProxy } from "next-intlayer/middleware";
    import { NextRequest } from "next/server";
    
    export function middleware(request: NextRequest) {
      return intlayerProxy(request);
    }
    

    Інтеграція з Vite

    Для SolidJS, Vue та Svelte Vite-плагін intlayerProxy керує перезаписами під час розробки.

    Починаючи з Intlayer v9, intlayerProxy() включено безпосередньо у плагін intlayer() і ввімкнено за замовчуванням через параметр routing.enableProxy (true за замовчуванням). Реєстрація його окремо, як показано нижче, тепер є необов'язковою — вона зберігається для зворотної сумісності та для налаштувань, які потребують контролю порядку плагінів. Встановіть routing.enableProxy: false, щоб відмовитися. Дивіться примітки до випуску v9.
    vite.config.ts
    import { defineConfig } from "vite";
    import { intlayer } from "vite-intlayer";
    
    export default defineConfig({
      plugins: [
        intlayer({
          proxy: {
            ignore: (req) => req.url?.startsWith("/api"),
          },
        }),
      ],
    });
    

    Ключові можливості

    1. Багатоконтекстні перезаписи

    Кожен форматер генерує RewriteObject, що містить спеціалізовані правила для різних споживачів:

    • url: Оптимізовано для генерації URL на боці клієнта (видаляє сегменти локалі).
    • nextjs: Зберігає [locale] для middleware Next.js.
    • vite: Зберігає :locale для проксі Vite.

    2. Автоматична нормалізація шаблонів

    Intlayer внутрішньо нормалізує всі синтаксиси шаблонів (наприклад, перетворює [param] на :param), щоб зіставлення залишалося послідовним незалежно від вихідного фреймворку.

    3. SEO авторитетні URL-адреси

    Забезпечуючи перенаправлення з канонічних шляхів на більш привабливі аліаси, Intlayer запобігає проблемам дубльованого контенту та покращує знаходжуваність сайту.

    Основні утиліти

    • getLocalizedUrl(url, locale): Генерує локалізований URL з урахуванням правил перезапису.
    • getCanonicalPath(path, locale): Відновлює локалізований URL до його внутрішнього канонічного шляху.
    • getRewritePath(pathname, locale): Визначає, чи потрібно виправити шлях (pathname) до його більш привабливого локалізованого аліаса.