@fy-/fws-vue 2.4.2 → 2.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.ts +30 -3
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import type { TFunction } from 'i18next'
|
|
1
2
|
import type { Emitter } from 'mitt'
|
|
2
3
|
import type { App, Plugin } from 'vue'
|
|
3
4
|
import type { Events } from './composables/event-bus'
|
|
4
5
|
import i18next from 'i18next'
|
|
5
6
|
import mitt from 'mitt'
|
|
7
|
+
import { shallowRef } from 'vue'
|
|
6
8
|
import CmsArticleBoxed from './components/fws/CmsArticleBoxed.vue'
|
|
7
9
|
import CmsArticleSingle from './components/fws/CmsArticleSingle.vue'
|
|
8
10
|
import DataTable from './components/fws/DataTable.vue'
|
|
@@ -70,15 +72,40 @@ function createFWS(): Plugin {
|
|
|
70
72
|
// @ts-expect-error: Emitter<Events> is not assignable to Emitter<Events>
|
|
71
73
|
const eventBus: Emitter<Events> = mitt<Events>()
|
|
72
74
|
|
|
75
|
+
// i18next's `t` is NOT reactive. If a component renders a key during a window
|
|
76
|
+
// where the resource isn't loaded yet (cold deep-link, client-nav before a late
|
|
77
|
+
// locale fetch, hydration race) it paints the RAW token and Vue never re-renders
|
|
78
|
+
// — nothing reactive changed, so the miss sticks. Wrap `t` so it depends on a
|
|
79
|
+
// tick bumped by i18next's own events: any raw key then self-heals the instant
|
|
80
|
+
// resources land, and `changeLanguage` live-updates every string. Client-only:
|
|
81
|
+
// on the server strings are already resolved by the `await i18nextPromise` before
|
|
82
|
+
// render, and `install()` runs per-request there — adding listeners to the global
|
|
83
|
+
// i18next singleton each request would leak. So SSR keeps the plain `t`.
|
|
84
|
+
let translate: TFunction = i18next.t
|
|
85
|
+
if (typeof window !== 'undefined') {
|
|
86
|
+
const tick = shallowRef(0)
|
|
87
|
+
const bump = (): void => {
|
|
88
|
+
tick.value++
|
|
89
|
+
}
|
|
90
|
+
i18next.on('loaded', bump)
|
|
91
|
+
i18next.on('added', bump)
|
|
92
|
+
i18next.on('languageChanged', bump)
|
|
93
|
+
const rawT = i18next.t as unknown as (...a: unknown[]) => unknown
|
|
94
|
+
translate = ((...args: Parameters<typeof i18next.t>) => {
|
|
95
|
+
void tick.value
|
|
96
|
+
return rawT(...args)
|
|
97
|
+
}) as unknown as TFunction
|
|
98
|
+
}
|
|
99
|
+
|
|
73
100
|
return {
|
|
74
101
|
install(app: App) {
|
|
75
102
|
if (app.config.globalProperties) {
|
|
76
103
|
app.config.globalProperties.$eventBus = eventBus
|
|
77
104
|
app.provide('fwsVueEventBus', eventBus)
|
|
78
105
|
|
|
79
|
-
// i18next
|
|
80
|
-
app.config.globalProperties.$t =
|
|
81
|
-
app.provide('fwsVueTranslate',
|
|
106
|
+
// i18next (reactive wrapper — see note above)
|
|
107
|
+
app.config.globalProperties.$t = translate
|
|
108
|
+
app.provide('fwsVueTranslate', translate)
|
|
82
109
|
|
|
83
110
|
// Templating
|
|
84
111
|
app.config.globalProperties.$cropText = cropText
|