Skip to content

Commit

Permalink
fix!: nuxt context injected function types (#3098)
Browse files Browse the repository at this point in the history
  • Loading branch information
BobbieGoede committed Sep 13, 2024
1 parent a3fb89f commit 97528e9
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 82 deletions.
14 changes: 14 additions & 0 deletions docs/content/docs/5.v9/2.guide/19.breaking-changes-in-v9.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,17 @@ Some properties have changed or swapped names to better fit their functionality,
## SEO - `useLocaleHead`

We have added a `addLangAttribute` property to the options parameter of `useLocaleHead` and `$localeHead`, originally this was not configurable on its own. If you want to keep the same behavior, if you were passing `addSeoAttributes`, you will also have to pass `addLangAttribute: true`. See [`useLocaleHead`](/docs/v9/api#useLocaleHead)

## Nuxt context functions

In v8 both the types and name of the injected context functions (such as `$localePath`, `$switchLocalePath` and [more](/docs/v9/api/nuxt)) did not work as intended. You may have found that these functions worked when using them without prefix (`$`) even when not assigning these functions from a composable.

The types and names have been fixed in v9, if you have been using the unprefixed functions globally (without composable) in your project you will have to prefix these functions as they were originally intended.

- `getRouteBaseName` -> `$getRouteBaseName`
- `resolveRoute` -> `$resolveRoute`
- `localePath` -> `$localePath`
- `localeRoute` -> `$localeRoute`
- `localeLocation` -> `$localeLocation`
- `switchLocalePath` -> `$switchLocalePath`
- `localeHead` -> `$localeHead`
2 changes: 1 addition & 1 deletion playground/pages/[...catch].vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ definePageMeta({
<p>This page is catch all: '{{ route.params }}'</p>
<nav>
<span v-for="locale in availableLocales" :key="locale.code">
<NuxtLink :to="switchLocalePath(locale.code) || ''">{{ locale.name }}</NuxtLink> |
<NuxtLink :to="$switchLocalePath(locale.code) || ''">{{ locale.name }}</NuxtLink> |
</span>
</nav>
</div>
Expand Down
6 changes: 3 additions & 3 deletions playground/pages/about/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ export default defineComponent({
<template>
<div>
<nav>
<NuxtLink :to="localePath('/')">Back to Home</NuxtLink>
<NuxtLink :to="$localePath('/')">Back to Home</NuxtLink>
</nav>
<nav>
<span v-for="locale in availableLocales" :key="locale.code">
<NuxtLink :to="switchLocalePath(locale.code) || ''">{{ locale.name }}</NuxtLink> |
<NuxtLink :to="$switchLocalePath(locale.code) || ''">{{ locale.name }}</NuxtLink> |
</span>
</nav>
<p>hello</p>
Expand All @@ -54,6 +54,6 @@ export default defineComponent({
</span>
</nav>
<p>{{ switchableLocale }}</p>
<p>{{ localeHead({ addSeoAttributes: true }) }}</p>
<p>{{ $localeHead({ addSeoAttributes: true }) }}</p>
</div>
</template>
2 changes: 1 addition & 1 deletion playground/pages/category/[id].vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ definePageMeta({
<p>This is cateory page on '{{ route.params.id }}'</p>
<nav>
<span v-for="locale in availableLocales" :key="locale.code">
<NuxtLink :to="switchLocalePath(locale.code) || ''">{{ locale.name }}</NuxtLink> |
<NuxtLink :to="$switchLocalePath(locale.code) || ''">{{ locale.name }}</NuxtLink> |
</span>
<i18n-t keypath="hello">
<template #name>nuxtjs/i18n</template>
Expand Down
2 changes: 1 addition & 1 deletion specs/fixtures/basic/pages/blog/index.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div>
<p>This is blog index page</p>
<NuxtLink id="link-blog-article" exact :to="localePath('blog-article')">article</NuxtLink>
<NuxtLink id="link-blog-article" exact :to="$localePath('blog-article')">article</NuxtLink>
</div>
</template>
2 changes: 1 addition & 1 deletion specs/fixtures/basic/pages/define-i18n-route-false.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div>
<h1 id="disable-route-text">Page with disabled localized route</h1>
<nuxt-link id="goto-home" :to="localePath('/')"> Goto Home </nuxt-link>
<nuxt-link id="goto-home" :to="$localePath('/')"> Goto Home </nuxt-link>
</div>
</template>

Expand Down
2 changes: 1 addition & 1 deletion specs/fixtures/different_domains/pages/blog/index.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div>
<p>This is blog index page</p>
<NuxtLink id="link-blog-article" exact :to="localePath('blog-article')">article</NuxtLink>
<NuxtLink id="link-blog-article" exact :to="$localePath('blog-article')">article</NuxtLink>
</div>
</template>
2 changes: 1 addition & 1 deletion specs/fixtures/multi_domains_locales/pages/blog/index.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div>
<p>This is blog index page</p>
<NuxtLink id="link-blog-article" exact :to="localePath('blog-article')">article</NuxtLink>
<NuxtLink id="link-blog-article" exact :to="$localePath('blog-article')">article</NuxtLink>
</div>
</template>
68 changes: 68 additions & 0 deletions src/runtime/injections.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import type {
LocaleHeadFunction,
LocalePathFunction,
LocaleRouteFunction,
RouteBaseNameFunction,
SwitchLocalePathFunction
} from '#i18n'
import type {
getRouteBaseName,
localeHead,
localePath,
localeRoute,
switchLocalePath
} from './routing/compatibles/index'

export type NuxtI18nPluginInjections = {
/**
* Returns base name of current (if argument not provided) or passed in route.
*
* @remarks
* Base name is name of the route without locale suffix and other metadata added by nuxt i18n module
*
* @param givenRoute - A route.
*
* @returns The route base name. if cannot get, `undefined` is returned.
*/
getRouteBaseName: (...args: Parameters<RouteBaseNameFunction>) => ReturnType<typeof getRouteBaseName>
/**
* Returns localized path for passed in route.
*
* @remarks
* If locale is not specified, uses current locale.
*
* @param route - A route.
* @param locale - A locale, optional.
*
* @returns A path of the current route.
*/
localePath: (...args: Parameters<LocalePathFunction>) => ReturnType<typeof localePath>
/**
* Returns localized route for passed in `route` parameters.
*
* @remarks
* If `locale` is not specified, uses current locale.
*
* @param route - A route.
* @param locale - A {@link Locale | locale}, optional.
*
* @returns A route. if cannot resolve, `undefined` is returned.
*/
localeRoute: (...args: Parameters<LocaleRouteFunction>) => ReturnType<typeof localeRoute>
/**
* Returns localized head properties for locale-related aspects.
*
* @param options - An options object, see `I18nHeadOptions`.
*
* @returns The localized head properties.
*/
localeHead: (...args: Parameters<LocaleHeadFunction>) => ReturnType<typeof localeHead>
/**
* Returns path of the current route for specified locale
*
* @param locale - A {@link Locale}
*
* @returns A path of the current route
*/
switchLocalePath: (...args: Parameters<SwitchLocalePathFunction>) => ReturnType<typeof switchLocalePath>
}
82 changes: 16 additions & 66 deletions src/runtime/plugins/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,24 @@ import { extendI18n, createLocaleFromRouteGetter } from '../routing/extends'
import { setLocale, getLocale, mergeLocaleMessage, setLocaleProperty } from '../compatibility'
import { createLogger } from 'virtual:nuxt-i18n-logger'

import type { NuxtI18nPluginInjections } from '../injections'
import type { Locale, I18nOptions } from 'vue-i18n'
import type { NuxtApp } from '#app'
import type { getRouteBaseName, localePath, localeRoute, switchLocalePath, localeHead } from '../routing/compatibles'
import type {
LocaleHeadFunction,
LocalePathFunction,
LocaleRouteFunction,
RouteBaseNameFunction,
SwitchLocalePathFunction
} from '../composables'

export default defineNuxtPlugin({

// from https://github.com/nuxt/nuxt/blob/2466af53b0331cdb8b17c2c3b08675c5985deaf3/packages/nuxt/src/core/templates.ts#L152
type Decorate<T extends Record<string, unknown>> = { [K in keyof T as K extends string ? `$${K}` : never]: T[K] }

// TODO: use @nuxt/module-builder to stub/prepare types
declare module '#app' {
interface NuxtApp extends Decorate<NuxtI18nPluginInjections> {}
}

// declare module 'vue' {
// interface ComponentCustomProperties extends Decorate<NuxtI18nPluginInjections> {}
// }

// `NuxtI18nPluginInjections` should not have properties prefixed with `$`
export default defineNuxtPlugin<NuxtI18nPluginInjections>({
name: 'i18n:plugin',
parallel: parallelPlugin,
async setup(nuxt) {
Expand Down Expand Up @@ -383,59 +389,3 @@ export default defineNuxtPlugin({
)
}
})

declare module '#app' {
interface NuxtApp {
/**
* Returns base name of current (if argument not provided) or passed in route.
*
* @remarks
* Base name is name of the route without locale suffix and other metadata added by nuxt i18n module
*
* @param givenRoute - A route.
*
* @returns The route base name. if cannot get, `undefined` is returned.
*/
$getRouteBaseName: (...args: Parameters<RouteBaseNameFunction>) => ReturnType<typeof getRouteBaseName>
/**
* Returns localized path for passed in route.
*
* @remarks
* If locale is not specified, uses current locale.
*
* @param route - A route.
* @param locale - A locale, optional.
*
* @returns A path of the current route.
*/
$localePath: (...args: Parameters<LocalePathFunction>) => ReturnType<typeof localePath>
/**
* Returns localized route for passed in `route` parameters.
*
* @remarks
* If `locale` is not specified, uses current locale.
*
* @param route - A route.
* @param locale - A {@link Locale | locale}, optional.
*
* @returns A route. if cannot resolve, `undefined` is returned.
*/
$localeRoute: (...args: Parameters<LocaleRouteFunction>) => ReturnType<typeof localeRoute>
/**
* Returns localized head properties for locale-related aspects.
*
* @param options - An options object, see `I18nHeadOptions`.
*
* @returns The localized head properties.
*/
$localeHead: (...args: Parameters<LocaleHeadFunction>) => ReturnType<typeof localeHead>
/**
* Returns path of the current route for specified locale
*
* @param locale - A {@link Locale}
*
* @returns A path of the current route
*/
$switchLocalePath: (...args: Parameters<SwitchLocalePathFunction>) => ReturnType<typeof switchLocalePath>
}
}
14 changes: 7 additions & 7 deletions src/runtime/routing/extends/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ export function extendI18n(i18n: I18n, { extendComposer, extendComposerInstance
const common = initCommonComposableOptions(i18n)
app.mixin({
methods: {
getRouteBaseName: wrapComposable(getRouteBaseName, common),
resolveRoute: wrapComposable(resolveRoute, common),
localePath: wrapComposable(localePath, common),
localeRoute: wrapComposable(localeRoute, common),
localeLocation: wrapComposable(localeLocation, common),
switchLocalePath: wrapComposable(switchLocalePath, common),
localeHead: wrapComposable(localeHead, common)
$getRouteBaseName: wrapComposable(getRouteBaseName, common),
$resolveRoute: wrapComposable(resolveRoute, common),
$localePath: wrapComposable(localePath, common),
$localeRoute: wrapComposable(localeRoute, common),
$localeLocation: wrapComposable(localeLocation, common),
$switchLocalePath: wrapComposable(switchLocalePath, common),
$localeHead: wrapComposable(localeHead, common)
}
})
}
Expand Down

0 comments on commit 97528e9

Please sign in to comment.