feat: remove nuxt i18n for in house i18n for web (#5131)

* feat: remove nuxt i18n for in house

* cleanup: remove old nuxt/i18n patch

* prepr

---------

Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
This commit is contained in:
Calum H.
2026-01-15 23:49:38 +00:00
committed by GitHub
parent 4497131206
commit a903e46be9
16 changed files with 275 additions and 787 deletions

View File

@@ -2,7 +2,8 @@
import IntlMessageFormat, { type FormatXMLElementFn, type PrimitiveType } from 'intl-messageformat'
import { computed, useSlots, type VNode } from 'vue'
import { getSafeI18n, type MessageDescriptor } from '../../composables/i18n'
import type { MessageDescriptor } from '../../composables/i18n'
import { injectI18n } from '../../providers/i18n'
const props = defineProps<{
messageId: MessageDescriptor
@@ -10,7 +11,7 @@ const props = defineProps<{
}>()
const slots = useSlots()
const { t, locale } = getSafeI18n()
const { t, locale } = injectI18n()
const formattedParts = computed(() => {
const key = props.messageId.id

View File

@@ -1,6 +1,6 @@
import { computed, type ComputedRef } from 'vue'
import { getSafeI18n } from './i18n'
import { injectI18n } from '../providers/i18n'
export type Formatter = (value: Date | number, options?: FormatOptions) => string
@@ -11,7 +11,7 @@ export interface FormatOptions {
const formatters = new Map<string, ComputedRef<Intl.RelativeTimeFormat>>()
export function useRelativeTime(): Formatter {
const { locale } = getSafeI18n()
const { locale } = injectI18n()
const formatterRef = computed(
() =>

View File

@@ -1,35 +1,8 @@
import IntlMessageFormat from 'intl-messageformat'
import type { Ref } from 'vue'
import type { CompileError, Composer, MessageCompiler, MessageContext } from 'vue-i18n'
import { useI18n } from 'vue-i18n'
import type { CompileError, MessageCompiler, MessageContext } from 'vue-i18n'
declare const useNuxtApp: (() => { $i18n?: Pick<Composer, 't' | 'locale'> }) | undefined
/**
* Get i18n instance, preferring Nuxt's $i18n to avoid vue-i18n's
* getCurrentInstance() issues on edge runtimes with concurrent SSR requests.
*/
export function getSafeI18n(): Pick<Composer, 't' | 'locale'> {
// Try Nuxt's $i18n first (avoids Error 27 on Cloudflare Workers)
if (typeof useNuxtApp === 'function') {
try {
const nuxtApp = useNuxtApp()
const $i18n = nuxtApp.$i18n
if ($i18n) {
return { t: $i18n.t, locale: $i18n.locale }
}
console.warn('[getSafeI18n] useNuxtApp() succeeded but $i18n is falsy:', $i18n)
} catch (e) {
console.warn('[getSafeI18n] useNuxtApp() threw:', e)
}
} else {
console.debug('[getSafeI18n] useNuxtApp not available, using vue-i18n fallback')
}
console.log('FALLBACK TO useI18n!!!')
// Fallback to vue-i18n's useI18n (used in Tauri app or if Nuxt context unavailable)
return useI18n()
}
import { injectI18n } from '../providers/i18n'
export interface MessageDescriptor {
id: string
@@ -55,7 +28,6 @@ export interface LocaleDefinition {
code: string
name: string
dir?: 'ltr' | 'rtl'
// For @nuxtjs/i18n v9 compatibility
iso?: string
file?: string
}
@@ -199,10 +171,10 @@ export interface VIntlFormatters {
/**
* Composable that provides formatMessage() with the same API as @vintl/vintl.
* Uses vue-i18n's useI18n() under the hood.
* Uses the injected I18nContext from the provider.
*/
export function useVIntl(): VIntlFormatters & { locale: Ref<string> } {
const { t, locale } = getSafeI18n()
const { t, locale } = injectI18n()
function formatMessage(descriptor: MessageDescriptor, values?: Record<string, unknown>): string {
const key = descriptor.id

View File

@@ -0,0 +1,24 @@
import type { InjectionKey, Ref } from 'vue'
import { inject, provide } from 'vue'
// This doesn't use the architecture outlined in index.ts as it needs some custom checks + use the symbol
export interface I18nContext {
locale: Ref<string>
t: (key: string, values?: Record<string, unknown>) => string
setLocale: (locale: string) => Promise<void> | void
}
export const I18N_INJECTION_KEY: InjectionKey<I18nContext> = Symbol('i18n')
export function injectI18n(): I18nContext {
const context = inject(I18N_INJECTION_KEY)
if (!context) {
throw new Error('Injection `Symbol(i18n)` not found. Ensure the i18n plugin is installed.')
}
return context
}
export function provideI18n(context: I18nContext): I18nContext {
provide(I18N_INJECTION_KEY, context)
return context
}

View File

@@ -79,6 +79,7 @@ export function createContext<ContextValue>(
}
export * from './api-client'
export * from './i18n'
export * from './page-context'
export * from './project-page'
export * from './server-context'