Skip to content

Commit

Permalink
feat: add customRoutes named-config (nuxt-modules#2407)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitry Istomin committed Sep 13, 2023
1 parent fbe195e commit 95b915f
Show file tree
Hide file tree
Showing 8 changed files with 569 additions and 10 deletions.
153 changes: 152 additions & 1 deletion docs/content/2.guide/4.custom-paths.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ Customize the names of the paths for specific locale.

---

In some cases, you might want to translate URLs in addition to having them prefixed with the locale code. There are 2 ways of configuring custom paths for your [Module configuration](#nodule-configuration) or your pages [Page component](#page-component).
In some cases, you might want to translate URLs in addition to having them prefixed with the locale code. There are 3 ways of configuring custom paths:

[Module configuration](#module-configuration) (`customRoutes: 'config'`)

[Module named configuration](#module-named-configuration) (`customRoutes: 'named-config'`)

[Page component](#page-component) (`customRoutes: 'page'`)

::alert{type="warning"}
Custom paths are not supported when using the `no-prefix` [strategy](/guide/routing-strategies).
Expand Down Expand Up @@ -187,6 +193,151 @@ export default defineNuxtConfig({
})
```

### Module named configuration

Make sure you set the `customRoutes` option to `named-config` and add your custom paths in the `pages` option:

```ts {}[nuxt.config.ts]
export default defineNuxtConfig({
// ...

i18n: {
customRoutes: 'config', // disable custom route with page components
pages: {
about: {
en: '/about-us', // -> accessible at /about-us (no prefix since it's the default locale)
fr: '/a-propos', // -> accessible at /fr/a-propos
es: '/sobre' // -> accessible at /es/sobre
}
}
},

// ...
})
```

Note that each key within the `pages` object should **correspond to the route name**.

Customized route paths **must start with a `/`** and **not include the locale prefix**.

#### Example 1: Basic URL localization

You have some routes with the following `pages` directory:

```asciidoc
pages/
├── about.vue
├── me.vue
├── services/
├──── index.vue
├──── advanced.vue
|---- [param].vue

```
You would need to set up your `pages` property as follows:

```ts {}[nuxt.config.ts]
export default defineNuxtConfig({
// ...

i18n: {
customRoutes: 'named-config',
pages: {
about: {
fr: '/a-propos',
},
me: {
fr: '/je',
},
'services': {
fr: '/offres',
}
'services-advanced': {
fr: '/offres/avancee',
}
'services-param': {
fr: '/offres/:param()',
}
}
},

// ...
})
```

Nuxt generates routes names based on you files structure
Basically it just removes special characters and join all segments with '-'

if you not sure about routes names just add that simple module before `'@nuxtjs/i18n'`:

```ts{}[nuxt.config.ts]
export default defineNuxtConfig({
modules: [
(_, nuxt) => {
nuxt.hook('pages:extend', pages => {
let pagesCopy = JSON.parse(JSON.stringify(pages))
function processRoutes(routes) {
return routes.map(r => {
if (r.children) {
r.children = processRoutes(r.children)
}
return {
name: r.name,
path: r.path,
children: r.children
}
})
}
console.log('PAGES:')
console.log(JSON.stringify(processRoutes(pagesCopy), null, 4))
})
},
'@nuxtjs/i18n',
],
})
```

::alert{type="warning"}
All the URL should start with `/`
::

#### Example 3: Dynamic Routes

Say you have some dynamic routes like:

```asciidoc
pages/
├── blog/
├──── [date]/
├────── [slug].vue
├── news/
├──── [[slug]].vue
```

Here's how you would configure these particular pages in the configuration:

```ts {}[nuxt.config.ts]
export default defineNuxtConfig({
// ...

i18n: {
customRoutes: 'named-config',
pages: {
'blog-date-slug': {
// params need to be put back here as you would declare with Vue Router
// https://router.vuejs.org/guide/essentials/dynamic-matching.html
ja: '/blog/tech/:date()/:slug()'
},
'news-slug':{
ja: '/news-ja/:slug?'
}
}
},

// ...
})
```

### Page component

You can use the `defineI18nRoute` compiler macro to set some custom paths for each page component.
Expand Down
24 changes: 23 additions & 1 deletion docs/content/2.guide/5.ignoring-localized-routes.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,19 @@ If you'd like some pages to be available in some languages only, you can configu
::code-block{label="Module configuration"}
```js {}[nuxt.config.js]
i18n: {
customRoutes: false,
customRoutes: 'config',
pages: {
about: {
en: false,
}
}
}
```
::
::code-block{label="Module named configuration"}
```js {}[nuxt.config.js]
i18n: {
customRoutes: 'named-config',
pages: {
about: {
en: false,
Expand Down Expand Up @@ -56,4 +68,14 @@ If you'd like some pages to be available in some languages only, you can configu
}
```
::
::code-block{label="Module named configuration"}
```js {}[nuxt.config.js]
i18n: {
customRoutes: 'named-config',
pages: {
about: false
}
}
```
::
::
4 changes: 2 additions & 2 deletions docs/content/3.options/2.routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Routes generation strategy. Can be set to one of the following:

## `customRoutes`

- type: `string` (`page` or `config`) | `undefined`
- type: `string` (`page`, `config` or `named-config`) | `undefined`
- default: `page`

Whether [custom paths](/guide/custom-paths) are extracted from page files
Expand All @@ -89,7 +89,7 @@ Whether [custom paths](/guide/custom-paths) are extracted from page files
- type: `object`
- default: `{}`

If `customRoutes` option is disabled with `config`, the module will look for custom routes in the `pages` option. Refer to the [Routing](/guide/routing-strategies) for usage.
If `customRoutes` option is disabled with `config` or `named-config`, the module will look for custom routes in the `pages` option. Refer to the [Routing](/guide/routing-strategies) for usage.

## `skipSettingLocaleOnNavigate`

Expand Down
36 changes: 36 additions & 0 deletions playground/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default defineNuxtConfig({
(_, nuxt) => {
console.log(nuxt.options._installedModules)
},

Module1,
ModuleExperimental,
LayerModule,
Expand Down Expand Up @@ -88,6 +89,25 @@ export default defineNuxtConfig({
}
],
*/
(_, nuxt) => {
nuxt.hook('pages:extend', pages => {
let pagesCopy = JSON.parse(JSON.stringify(pages))
function processRoutes(routes) {
return routes.map(r => {
if (r.children) {
r.children = processRoutes(r.children)
}
return {
name: r.name,
path: r.path,
children: r.children
}
})
}
console.log('PAGES:')
console.log(JSON.stringify(processRoutes(pagesCopy), null, 4))
})
},
'@nuxtjs/i18n',
'@nuxt/devtools'
],
Expand Down Expand Up @@ -171,6 +191,22 @@ export default defineNuxtConfig({
ja: '/about-ja'
}
},

// // NAMED-CONFIG
// customRoutes: 'named-config',
// pages: {
// history: {
// ja: '/history-ja'
// },
// about: {
// ja: '/about-ja'
// },
// 'category-id': {
// ja: '/category-ja/:id()'
// }
// },
// // END OF NAMED-CONFIG

// differentDomains: true,
skipSettingLocaleOnNavigate: true,
detectBrowserLanguage: false,
Expand Down
69 changes: 64 additions & 5 deletions src/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,27 @@ export function getRouteOptionsResolver(
): RouteOptionsResolver {
const { pages, defaultLocale, customRoutes } = options

const useConfig = customRoutes === 'config'
debug('getRouteOptionsResolver useConfig', useConfig)
let customRoutesProvider = 'page'
if (customRoutes && ['config', 'named-config', 'page'].includes(customRoutes)) {
customRoutesProvider = customRoutes
} else if (customRoutes) {
console.warn(
formatMessage(
`Unknown customRoutes property (${JSON.stringify(customRoutes)}), will be reset to default ("page")`
)
)
}

debug('getRouteOptionsResolver customRoutes:', customRoutes)

return (route, localeCodes): ComputedRouteOptions | null => {
const ret = useConfig
? getRouteOptionsFromPages(ctx, route, localeCodes, pages, defaultLocale)
: getRouteOptionsFromComponent(route, localeCodes)
const routesGetters = {
config: () => getRouteOptionsFromPages(ctx, route, localeCodes, pages, defaultLocale),
'named-config': () => getRouteOptionsFromRoutesNames(ctx, route, localeCodes, pages, defaultLocale),
page: () => getRouteOptionsFromComponent(route, localeCodes)
}

const ret = routesGetters[customRoutesProvider]()
debug('getRouteOptionsResolver resolved', route.path, route.name, ret)
return ret
}
Expand Down Expand Up @@ -198,6 +212,51 @@ function getRouteOptionsFromPages(
return options
}

function getRouteOptionsFromRoutesNames(
ctx: NuxtPageAnalyzeContext,
route: I18nRoute,
localeCodes: string[],
pages: CustomRoutePages,
defaultLocale: string
) {
const options: ComputedRouteOptions = {
locales: localeCodes,
paths: {}
}
const pageOptions = pages[route.name]

// routing disabled
if (pageOptions === false) {
return null
}

// skip if no page options defined
if (!pageOptions) {
return options
}

// remove disabled locales from page options
options.locales = options.locales.filter(locale => pageOptions[locale] !== false)

// construct paths object
for (const locale of options.locales) {
const customLocalePath = pageOptions[locale]
if (isString(customLocalePath)) {
// set custom path if any
options.paths[locale] = customLocalePath
continue
}

const customDefaultLocalePath = pageOptions[defaultLocale]
if (isString(customDefaultLocalePath)) {
// set default locale's custom path if any
options.paths[locale] = customDefaultLocalePath
}
}

return options
}

function getRouteOptionsFromComponent(route: I18nRoute, localeCodes: string[]) {
debug('getRouteOptionsFromComponent', route)
const file = route.component || route.file
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export type NuxtI18nOptions<Context = unknown> = {
langDir?: string | null
lazy?: boolean
pages?: CustomRoutePages
customRoutes?: 'page' | 'config'
customRoutes?: 'page' | 'config' | 'named-config'
/**
* @internal
*/
Expand Down
Loading

0 comments on commit 95b915f

Please sign in to comment.