Guide

自定义路由路径

自定义特定语言环境的路径名称。

在某些情况下,您可能希望翻译 URL,除了将其前缀化为语言环境代码之外。配置自定义路径有两种方法,通过 模块配置 或从每个 页面组件 中进行配置。

使用哪种方法可以通过设置 customRoutes 选项 来配置,默认设置为 'page'。同时使用两种方法是不可能的。

当使用 'no_prefix'策略 时,不支持自定义路径,除非与 differentDomains 结合使用。

模块配置

确保将 customRoutes 选项设置为 'config' 并在 pages 选项中添加您的自定义路径:

nuxt.config.ts
export default defineNuxtConfig({
  i18n: {
    customRoutes: 'config', // 禁用带页面组件的自定义路由
    pages: {
      about: {
        en: '/about-us', // -> 可通过 /about-us 访问(由于它是默认语言环境,因此没有前缀)
        fr: '/a-propos', // -> 可通过 /fr/a-propos 访问
        es: '/sobre' // -> 可通过 /es/sobre 访问
      }
    }
  }
})

请注意, pages 对象中的每个键应 对应要本地化的路由名称

自定义路由路径 必须以 / 开头 并且 不得包含语言环境前缀

您现在可以使用 localePath() 函数或 <NuxtLinkLocale> 组件,但请确保使用命名路由。例如,路由 '/services/advanced' 应该是 'services-advanced'

<script setup>
const { t } = useI18n()
</script>

<template>
  <NuxtLinkLocale to="about"> {{ t('about') }} </NuxtLinkLocale>
  <NuxtLinkLocale to="services-advanced"> {{ t('advanced') }} </NuxtLinkLocale>
</template>

或者:

<script setup>
const { t } = useI18n()
const localePath = useLocalePath()
</script>

<template>
  <NuxtLink :to="localePath('about')"> {{ t('about') }} </NuxtLink>
  <NuxtLink :to="localePath('services-advanced')"> {{ t('advanced') }} </NuxtLink>
</template>
目前不支持将路径传递给 localePath()

示例 1:基本 URL 本地化

您有一些路由,带有以下 pages 目录:

Directory structure
-| pages/
---| parent/
-----| child.vue
---| parent.vue
嵌套/子路由依赖于存在一个与文件夹同名的页面组件,用于渲染子路由。有关更多详细信息,请参见 嵌套路由

您需要按如下方式设置 pages 属性:

nuxt.config.ts
export default defineNuxtConfig({
   i18n: {
    customRoutes: 'config',
    pages: {
      parent: {
        en: '/parent',
        ca: '/pare'
      },
      'parent-child': {
        en: '/parent/child',
        ca: '/pare/fill'
      }
    }
  }
})
所有 URL 必须以 / 开头

示例 2:本地化 URL 的一部分

您有一些路由,其 pages 目录如下:

Directory structure
-| pages/
---| about.vue
---| services/
-----| index.vue
-----| coaching.vue
-----| development/
-------| app.vue
-------| website.vue
-----| development.vue
---| services.vue

您需要按如下方式设置 pages 属性:

nuxt.config.ts
export default defineNuxtConfig({
  i18n: {
    customRoutes: 'config',
    pages: {
      about: {
        fr: '/a-propos'
      },
      services: {
        fr: '/offres'
      },
      'services-development': {
        fr: '/offres/developement'
      },
      'services-development-app': {
        fr: '/offres/developement/app'
      },
      'services-development-website': {
        fr: '/offres/developement/site-web'
      },
      'services-coaching': {
        fr: '/offres/formation'
      }
    }
  }
})

如果缺少某个语言环境的自定义路径,则使用 defaultLocale 自定义路径(如果设置)。

示例 3:动态路由

假设您有一些动态路由,如下所示:

Directory structure
-| pages/
---| blog/
-----| [date]/
-------| [slug].vue

您可以按照以下方式在配置中设置这些特定页面:

nuxt.config.ts
export default defineNuxtConfig({
  i18n: {
    customRoutes: 'config',
    pages: {
      'blog-date-slug': {
        // 参数需要放回这里,正如您在 Nuxt 动态路由中所做的
        // https://nuxt.com/docs/guide/directory-structure/pages#dynamic-routes
        ja: '/blog/tech/[date]/[slug]'
        // ...
      }
    }
  }
})

页面组件

属于更新至 v8.0.1 或更高版本的用户

路径参数解析已更改,以匹配 Nuxt 3 的解析,您需要更新自定义路径(例如 '/example/:param' 现在应该为 '/example/[param]')。

您可以使用 defineI18nRoute() 编译器宏为每个页面组件设置自定义路径。

pages/about.vue
<script setup>
  defineI18nRoute({
    paths: {
      en: '/about-us', // -> 可通过 /about-us 访问(由于它是默认语言环境,因此没有前缀)
      fr: '/a-propos', // -> 可通过 /fr/a-propos 访问
      es: '/sobre' // -> 可通过 /es/sobre 访问
    }
  })
</script>

要为动态路由配置自定义路径,您需要在路径中使用双中括号,类似于您在 Nuxt 动态路由 中所做的那样:

pages/articles/[name].vue
<script setup>
  defineI18nRoute({
    paths: {
      en: '/articles/[name]',
      es: '/artículo/[name]'
    }
  })
</script>
defineI18nRoute() 编译器宏在构建时被树摇出,并不包含在分发文件中。

动态路由参数

处理动态路由参数需要更多的工作,因为您需要为 Nuxt i18n 模块 提供参数翻译。可组合的 useSetI18nParams 可用于设置路由参数的翻译,它用于设置 SEO 标签以及更改 switchLocalePath 返回的路由。

在 SSR 期间,您设置 i18n 参数的时间和位置非常重要,因为在 SSR 期间没有反应性。

已经渲染的组件不会因页面和组件在树下方更改而更新。这些链接通常在客户端的水合期间更新,在大多数情况下这不会造成问题。

但是,SEO 标签并不会受到这个影响,无论何时何地设置 i18n 参数,它们在 SSR 中都会正确更新。

请查看实验性的 switchLocalePathLinkSSR 特性,它与 <SwitchLocalePathLink> 组件相结合,能够在 SSR 期间正确呈现链接,无论何时何地使用。

这是一个示例(将 slug 替换为适用的路由参数):

<script setup>
// 从 API 获取产品...(红色咖啡杯)

const setI18nParams = useSetI18nParams()
setI18nParams({
  en: { slug: data.slugs.en }, // slug: 'red-mug'
  nl: { slug: data.slugs.nl } // slug: 'rode-mok'
})

const switchLocalePath = useSwitchLocalePath()
switchLocalePath('en') // /products/red-mug
switchLocalePath('nl') // /nl/products/rode-mok
</script>

<template>
  <!-- pages/products/[slug].vue -->
</template>

请注意,对于命名为 [...pathMatch].vue 的通配符路由情况,该对象的键需要标记为 pathMatch。例如:

<script>
const setI18nParams = useSetI18nParams()
setI18nParams({
  en: { pathMatch: ['not-found-my-post'] },
  fr: { pathMatch: ['not-found-mon-article'] }
})
</script>

<template>
  <!-- pages/[...pathMatch].vue -->
</template>

请注意,通配符路由定义为 数组。在这种情况下,它只有一个元素,但是如果您想使用子路径,例如 '/not-found/post',则定义多个元素,如 ['not-found', 'post']。您需要定义多个,例如 ['not-found', 'post']

Nuxt i18n 模块 不会为您重置参数翻译,这意味着如果您对不同的路由使用相同的参数,则在这些路由之间导航可能会导致参数冲突。在这种情况下,请确保始终设置参数翻译。

definePageMeta({ name: '...' }) 注意事项

默认情况下,Nuxt 会在构建时覆盖生成的路由值,这会破坏自定义命名路由(使用 definePageMeta() 设置 name)在解析本地化路径时的功能。

Nuxt v3.10 引入了实验性特性 scanPageMeta,这需要启用,以便在使用 Nuxt I18n 时自定义命名路由正常工作。

可以如下启用此实验性特性:

nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    scanPageMeta: true,
  }
})