Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!: functions in the config to be used through hooks #1919

Merged
merged 4 commits into from Mar 12, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,25 +1,23 @@
# Callbacks
# Runtime Hooks

Nuxt i18n module exposes some callbacks that you can use to perform specific tasks that depend on the app's language.
Nuxt i18n module exposes some [runtime hooks](https://nuxt.com/docs/guide/going-further/hooks#app-hooks-runtime) as callbacks that you can use to perform specific tasks that depend on the app's language.

---

**Nuxt i18n module** exposes some callbacks that you can use to perform specific tasks that depend on the app's language.

### `onBeforeLanguageSwitch`
### `i18n:beforeLocaleSwitch`

Called before the app's locale is switched. Can be used to override the new locale by returning a new locale code.

Parameters:

- **oldLocale**: the app's locale before the switch
- **newLocale**: the app's locale after the switch
- **isInitialSetup**: set to `true` if it's the initial locale switch that triggers on app load. It's a special case since the locale is not technically set yet so we're switching from no locale to locale.
- **nuxtApp**: the Nuxt app
- **initialSetup**: set to `true` if it's the initial locale switch that triggers on app load. It's a special case since the locale is not technically set yet so we're switching from no locale to locale.
- **context**: the Nuxt app

Returns: `string` or nothing

### `onLanguageSwitched`
### `i18n:localeSwitched`

Called right after the app's locale has been switched.

Expand All @@ -34,13 +32,14 @@ A typical usage would be to define those callbacks via a plugin where you can ac

```js {}[/plugins/i18n.js]
export default defineNuxtPlugin(nuxtApp => {
// onBeforeLanguageSwitch called right before setting a new locale
nuxtApp.$i18n.onBeforeLanguageSwitch = (oldLocale, newLocale, isInitialSetup, nuxtApp) => {
console.log('onBeforeLanguageSwitch', oldLocale, newLocale, isInitialSetup)
}
// onLanguageSwitched called right after a new locale has been set
nuxtApp.$i18n.onLanguageSwitched = (oldLocale, newLocale) => {
// called right before setting a new locale
nuxtApp.hook('i18n:beforeLocaleSwitch', ({ oldLocale, newLocale, initialSetup, context }) => {
console.log('onBeforeLanguageSwitch', oldLocale, newLocale, initialSetup)
})

// called right after a new locale has been set
nuxtApp.hook('i18n:localeSwitched', ({oldLocale, newLocale}) => {
console.log('onLanguageSwitched', oldLocale, newLocale)
}
})
})
```
18 changes: 0 additions & 18 deletions docs/content/3.options/2.routing.md
Expand Up @@ -113,24 +113,6 @@ Whether [custom paths](/guide/custom-paths) are extracted from page files

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.

## `onBeforeLanguageSwitch`

- type: `function`
- default: `(oldLocale, newLocale, isInitialSetup, context) => {}`

A listener called before the app's locale is changed. Can override the locale that is about to be set.

See [callbacks](/guide/callbacks)

## `onLanguageSwitched`

- type: `function`
- default: `(oldLocale, newLocale) => {}`

A listener called after app's locale has changed.

See [callbacks](/guide/callbacks)

## `skipSettingLocaleOnNavigate`

- type: `boolean`
Expand Down
6 changes: 0 additions & 6 deletions playground/nuxt.config.ts
Expand Up @@ -78,12 +78,6 @@ export default defineNuxtConfig({
// // // cookieKey: 'my_custom_cookie_name',
// // redirectOn: 'root'
// },
onBeforeLanguageSwitch: (oldLocale: string, newLocale: string, initial: boolean, nuxt: NuxtApp) => {
console.log('onBeforeLanguageSwitch', oldLocale, newLocale, initial)
},
onLanguageSwitched: (oldLocale: string, newLocale: string) => {
console.log('onLanguageSwitched', oldLocale, newLocale)
},
// vueI18n: './vue-i18n.options.ts'
vueI18n: {
legacy: false,
Expand Down
12 changes: 6 additions & 6 deletions playground/plugins/i18n.ts
@@ -1,11 +1,11 @@
import { defineNuxtPlugin } from '#imports'

export default defineNuxtPlugin(nuxtApp => {
nuxtApp.$i18n.onBeforeLanguageSwitch = (oldLocale, newLocale, isInitialSetup, nuxtApp) => {
console.log('onBeforeLanguageSwitch', oldLocale, newLocale, isInitialSetup)
}
// onLanguageSwitched called right after a new locale has been set
nuxtApp.$i18n.onLanguageSwitched = (oldLocale, newLocale) => {
nuxtApp.hook('i18n:beforeLocaleSwitch', ({ oldLocale, newLocale, initialSetup }) => {
console.log('onBeforeLanguageSwitch', oldLocale, newLocale, initialSetup)
})

nuxtApp.hook('i18n:localeSwitched', ({ oldLocale, newLocale }) => {
console.log('onLanguageSwitched', oldLocale, newLocale)
}
})
})
15 changes: 2 additions & 13 deletions specs/callbacks.spec.ts
Expand Up @@ -8,19 +8,8 @@ await setup({
browser: true,
// overrides
nuxtConfig: {
i18n: {
defaultLocale: 'en',
// eslint-disable-next-line @typescript-eslint/no-explicit-any
onBeforeLanguageSwitch: (oldLocale: string, newLocale: string, initialSetup: boolean, context: any) => {
console.log('onBeforeLanguageSwitch', oldLocale, newLocale, initialSetup, context)
if (newLocale === 'en') {
return 'fr'
}
},
onLanguageSwitched: (oldLocale: string, newLocale: string) => {
console.log('onLanguageSwitched', oldLocale, newLocale)
}
}
plugins: [fileURLToPath(new URL(`../playground/plugins/i18n.ts`, import.meta.url))],
i18n: { defaultLocale: 'en' }
}
})

Expand Down
2 changes: 0 additions & 2 deletions src/constants.ts
Expand Up @@ -58,8 +58,6 @@ export const DEFAULT_OPTIONS = {
customRoutes: 'page',
pages: {},
skipSettingLocaleOnNavigate: false,
onBeforeLanguageSwitch: () => '',
onLanguageSwitched: () => null,
types: undefined,
debug: false
} as const
Expand Down
15 changes: 15 additions & 0 deletions src/module.ts
Expand Up @@ -277,6 +277,9 @@ function checkOptions(options: NuxtI18nOptions) {
}
}

type MaybePromise<T> = T | Promise<T>
type LocaleSwitch<T extends string = string> = { oldLocale: T; newLocale: T }

declare module '@nuxt/schema' {
interface NuxtConfig {
i18n?: NuxtI18nOptions
Expand All @@ -286,3 +289,15 @@ declare module '@nuxt/schema' {
'i18n:extend-messages': (messages: LocaleMessages<DefineLocaleMessage>[], localeCodes: string[]) => Promise<void>
}
}

declare module '#app' {
interface RuntimeNuxtHooks {
'i18n:beforeLocaleSwitch': <Context = unknown>(
params: LocaleSwitch & {
initialSetup: boolean
context: Context
}
) => MaybePromise<void>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
) => MaybePromise<void>
) => MaybePromise<string | void>

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

@ineshbose ineshbose Mar 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of return, it may need to be something like nuxtApp.$i18n.locale = 'en'

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work with callHook it seems!

'i18n:localeSwitched': (params: LocaleSwitch) => MaybePromise<void>
}
}
8 changes: 6 additions & 2 deletions src/runtime/plugins/i18n.ts
Expand Up @@ -224,8 +224,12 @@ export default defineNuxtPlugin(async nuxt => {
_getLocaleCookie(nuxt.ssrContext, { ...nuxtI18nOptions.detectBrowserLanguage, localeCodes })
composer.setLocaleCookie = (locale: string) =>
_setLocaleCookie(locale, nuxt.ssrContext, nuxtI18nOptions.detectBrowserLanguage || undefined)
composer.onBeforeLanguageSwitch = nuxtI18nOptions.onBeforeLanguageSwitch
composer.onLanguageSwitched = nuxtI18nOptions.onLanguageSwitched

composer.onBeforeLanguageSwitch = (oldLocale, newLocale, initialSetup, context) =>
nuxt.callHook('i18n:beforeLocaleSwitch', { oldLocale, newLocale, initialSetup, context })
composer.onLanguageSwitched = (oldLocale, newLocale) =>
nuxt.callHook('i18n:localeSwitched', { oldLocale, newLocale })

composer.finalizePendingLocaleChange = async () => {
if (!i18n.__pendingLocale) {
return
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/types.d.ts
Expand Up @@ -26,15 +26,15 @@ type BeforeLanguageSwitchHandler = (
newLocale: string,
initialSetup: boolean,
context: NuxtApp
) => string | void
) => Promise<unknown>
ineshbose marked this conversation as resolved.
Show resolved Hide resolved

/**
* Called after the app's locale is switched.
*
* @param oldLocale - The app's locale before the switch
* @param newLocale - The app's locale after the switch.
*/
type LanguageSwitchedHandler = (oldLocale: string, newLocale: string) => void
type LanguageSwitchedHandler = (oldLocale: string, newLocale: string) => Promise<unknown>
ineshbose marked this conversation as resolved.
Show resolved Hide resolved

export interface ComposerCustomProperties {
/**
Expand Down
6 changes: 2 additions & 4 deletions src/types.ts
Expand Up @@ -41,14 +41,12 @@ export type BeforeLanguageSwitchHandler = <Context = unknown>(
newLocale: string,
initialSetup: boolean,
context: Context
) => string | void
) => Promise<unknown>
ineshbose marked this conversation as resolved.
Show resolved Hide resolved

export type LanguageSwitchedHandler = (oldLocale: string, newLocale: string) => void
export type LanguageSwitchedHandler = (oldLocale: string, newLocale: string) => Promise<unknown>
ineshbose marked this conversation as resolved.
Show resolved Hide resolved

export type NuxtI18nOptions<Context = unknown> = {
differentDomains?: boolean
onBeforeLanguageSwitch?: BeforeLanguageSwitchHandler
onLanguageSwitched?: LanguageSwitchedHandler
detectBrowserLanguage?: DetectBrowserLanguageOptions | false
langDir?: string | null
lazy?: boolean | LazyOptions
Expand Down