diff --git a/docs/content/2.guide/19.migrating.md b/docs/content/2.guide/19.migrating.md
index 696e2f2a2..600546012 100644
--- a/docs/content/2.guide/19.migrating.md
+++ b/docs/content/2.guide/19.migrating.md
@@ -134,7 +134,7 @@ Use the `customRoutes` option. because the option name `parsePages` is not intui
### Deprecated `vuex` option
-Use `dynamicRouteParams` option. Because Vuex is no longer required by the Nuxt i18n module.
+Vuex is no longer required by the Nuxt i18n module, use the `useSetI18nParams` composable to set dynamic route parameters instead.
```diff {}[nuxt.config.js]
export default defineNuxtConfig({
@@ -145,7 +145,6 @@ Use `dynamicRouteParams` option. Because Vuex is no longer required by the Nuxt
i18n: {
// ...
- vuex: true,
-+ dynamicRouteParams: true,
// ...
}
})
diff --git a/docs/content/2.guide/9.lang-switcher.md b/docs/content/2.guide/9.lang-switcher.md
index cd976db2c..1c0ac2371 100644
--- a/docs/content/2.guide/9.lang-switcher.md
+++ b/docs/content/2.guide/9.lang-switcher.md
@@ -80,57 +80,57 @@ const availableLocales = computed(() => {
## Dynamic route parameters
-Dealing with dynamic route parameters requires a bit more work because you need to provide parameters translations to **Nuxt i18n module**. For this purpose, **Nuxt i18n module** uses params which are configured by `definePageMeta`. These will be merged with route params when generating lang switch routes with `switchLocalePath()`.
+Dealing with dynamic route parameters requires a bit more work because you need to provide parameters translations to **Nuxt i18n module**. The composable `useSetI18nParams` can be used to set translations for route parameters, this is used to set SEO tags as well as changing the routes returned by `switchLocalePath`.
::alert{type="warning"}
+During SSR it matters when and where you set i18n parameters, since there is no reactivity during SSR.
-You have to set the `dynamicRouteParams` option to `true` in **Nuxt i18n module**'s options to enable dynamic route parameters.
+:br :br
+Components which have already been rendered do not update by changes introduced by pages and components further down the tree. Instead, these links are updated on the client side, so this should not cause any issues.
+:br :br
+This is not the case for SEO tags, these are updated correctly during SSR regardless of when and where i18n parameters are set.
::
-An example (replace `id` with the applicable route parameter):
-
+An example (replace `slug` with the applicable route parameter):
```vue
-
+
-
```
Note that for the special case of a catch-all route named like `[...pathMatch.vue]`, the key of the object needs to say `pathMatch`. For example:
```vue
-
```
Note that a catch all route is defined **as an array**. In this case, there is only one element, but if you want to use a sub-path, for example `/not-found/post`, define multiple elements as in `['not-found', 'post']`. You will need to define more than one, e.g. `['not-found', 'post']`.
-
::alert{type="info"}
**Nuxt i18n module** won't reset parameters translations for you, this means that if you use identical parameters for different routes, navigating between those routes might result in conflicting parameters. Make sure you always set params translations in such cases.
::
@@ -240,3 +240,52 @@ route.meta.pageTransition.onBeforeEnter = async () => {
}
```
+
+
+## Dynamic route parameters using `definePageMeta` (Deprecated)
+::alert{type="warning"}
+Dynamic route params using `nuxtI18n` on `definePageMeta` has been deprecated and will be removed in `v8.1`, use the composable [`useSetI18nParams`](/api/composables#useseti18nparams) instead.
+::
+
+
+Dynamic params can be configured uding `definePageMeta`. These will be merged with route params when generating lang switch routes with `switchLocalePath()`.
+
+::alert{type="warning"}
+You have to set the `dynamicRouteParams` option to `true` in **Nuxt i18n module**'s options to enable dynamic route parameters.
+::
+
+An example (replace `id` with the applicable route parameter):
+
+```vue
+
+
+
+
+```
+
+Note that for the special case of a catch-all route named like `[...pathMatch.vue]`, the key of the object needs to say `pathMatch`. For example:
+
+```vue
+
+
+
+
+```
\ No newline at end of file
diff --git a/docs/content/3.options/2.routing.md b/docs/content/3.options/2.routing.md
index 8c6b66afd..5fdfe1402 100644
--- a/docs/content/3.options/2.routing.md
+++ b/docs/content/3.options/2.routing.md
@@ -132,6 +132,10 @@ Set to a path to which you want to redirect users accessing the root URL (`/`).
- type: `boolean`
- default: `false`
+::alert{type=warning}
+The `dynamicRouteParams` is deprecated and will be removed in `v8.1`, use the [`useSetI18nParams`](/api/composables#useseti18nparams) composable instead.
+::
+
Whether to localize dynamic route parameters.
If `true`, you can set the dynamic route parameter to `nuxtI18n` field of `definePageMeta` for each locale:
diff --git a/docs/content/4.API/1.composables.md b/docs/content/4.API/1.composables.md
index 12f85d3c0..509299262 100644
--- a/docs/content/4.API/1.composables.md
+++ b/docs/content/4.API/1.composables.md
@@ -124,6 +124,50 @@ An object accepting the following optional fields:
Identifier attribute of `` tag, default `'hid'`.
+
+## `useSetI18nParams`
+
+The `useSetI18nParams` returns a function to set translated parameters for the current route. For more details on its usage see the [Lang Switcher guide](/guide/lang-switcher#dynamic-route-parameters).
+
+Example:
+```vue
+
+
+
+
+
+```
+
+### Type
+
+```ts
+declare function useSetI18nParams(options?: SeoAttributesOptions): (locale: Record) => void;
+```
+
+### Parameters
+
+#### `options`
+
+ **Type**: `SeoAttributesOptions | undefined`
+
+ An `SeoAttributesOptions` object, default `undefined`. See the [SEO guide](/guide/seo#feature-details) for more details.
+
+
+
## `useRouteBaseName`
The `useRouteBaseName` composable returns a function that gets the route's base name. `useRouteBaseName` is powered by [vue-i18n-routing](https://github.com/intlify/routing/tree/main/packages/vue-i18n-routing).
diff --git a/package.json b/package.json
index 0a5c5a0a5..f569f6719 100644
--- a/package.json
+++ b/package.json
@@ -106,6 +106,7 @@
"@types/debug": "^4.1.9",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
+ "@unhead/vue": "^1.8.8",
"bumpp": "^9.2.0",
"changelogithub": "^0.13.0",
"consola": "^3",
@@ -130,6 +131,7 @@
"unbuild": "^2.0.0",
"undici": "^6.0.1",
"vitest": "^1.0.0",
+ "unhead": "^1.8.8",
"vue": "^3.3.4",
"vue-router": "^4.2.5"
},
@@ -152,4 +154,4 @@
"engines": {
"node": "^14.16.0 || >=16.11.0"
}
-}
+}
\ No newline at end of file
diff --git a/playground/layouts/default.vue b/playground/layouts/default.vue
index 42194425f..aa9d56eca 100644
--- a/playground/layouts/default.vue
+++ b/playground/layouts/default.vue
@@ -1,7 +1,10 @@
@@ -21,7 +24,7 @@ const title = computed(() => t('layouts.title', { title: t(route.meta.title ?? '
I18n Head
-
{{ head }}
+
{{ head }}