Skip to content

Commit 73ef876

Browse files
committed
refactor(vite-vue-app): restructure content files and update localization implementation in example app
1 parent 19b6eb1 commit 73ef876

File tree

13 files changed

+323
-253
lines changed

13 files changed

+323
-253
lines changed

docs/en/intlayer_with_vite+vue.md

Lines changed: 178 additions & 133 deletions
Large diffs are not rendered by default.

examples/vite-vue-app/src/App.vue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import { useIntlayer } from 'vue-intlayer';
33
import HelloWorld from './components/HelloWorld.vue';
44
import LocaleSwitcher from './components/LocaleSwitcher.vue';
55
import { useI18nHTMLAttributes } from './composables/useI18nHTMLAttributes';
6+
import { useLocale } from 'vue-intlayer';
7+
import { ref, watch } from 'vue';
8+
9+
const { locale, availableLocales, setLocale } = useLocale();
610
711
// Use the useIntlayer composable to access translations
812
const content = useIntlayer('app');

examples/vite-vue-app/src/components/LocaleSwitcher.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
<script setup>
1212
import { ref, watch } from 'vue';
13-
import { Locales, getLocaleName } from 'intlayer';
13+
import { getLocaleName } from 'intlayer';
1414
import { useLocale } from 'vue-intlayer';
1515
1616
// Get locale information and setLocale function

examples/vite-vue-app/src/components/helloWorld.content.ts

Lines changed: 27 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,35 @@
11
import { t, type Dictionary } from 'intlayer';
22

33
const helloWorldContent = {
4-
key: 'app',
4+
key: 'helloworld',
55
content: {
6-
countIs: t({
7-
en: 'count is ',
8-
fr: 'le compte est ',
9-
es: 'el recuento es ',
6+
count: t({ en: 'count is ', fr: 'le compte est ', es: 'el recuento es ' }),
7+
edit: t({
8+
en: 'Edit <code>components/HelloWorld.vue</code> and save to test HMR',
9+
fr: 'Éditez <code>components/HelloWorld.vue</code> et enregistrez pour tester HMR',
10+
es: 'Edita <code>components/HelloWorld.vue</code> y guarda para probar HMR',
11+
}),
12+
checkOut: t({ en: 'Check out ', fr: 'Vérifiez ', es: 'Compruebe ' }),
13+
officialStarter: t({
14+
en: ', the official Vue + Vite starter',
15+
fr: ', le starter officiel Vue + Vite',
16+
es: ', el starter oficial Vue + Vite',
17+
}),
18+
learnMore: t({
19+
en: 'Learn more about IDE Support for Vue in the ',
20+
fr: 'En savoir plus sur le support IDE pour Vue dans le ',
21+
es: 'Aprenda más sobre el soporte IDE para Vue en el ',
22+
}),
23+
vueDocs: t({
24+
en: 'Vue Docs Scaling up Guide',
25+
fr: 'Vue Docs Scaling up Guide',
26+
es: 'Vue Docs Scaling up Guide',
27+
}),
28+
readTheDocs: t({
29+
en: 'Click on the Vite and Vue logos to learn more',
30+
fr: 'Cliquez sur les logos Vite et Vue pour en savoir plus',
31+
es: 'Haga clic en los logotipos de Vite y Vue para obtener más información',
1032
}),
11-
edit: [
12-
t({
13-
en: 'Edit ',
14-
fr: 'Éditez ',
15-
es: 'Edita ',
16-
}),
17-
t({
18-
en: 'components/HelloWorld.vue',
19-
fr: 'components/HelloWorld.vue',
20-
es: 'components/HelloWorld.vue',
21-
}),
22-
t({
23-
en: ' to test HMR',
24-
fr: ' pour tester HMR',
25-
es: ' para probar HMR',
26-
}),
27-
],
28-
checkOutStarter: [
29-
t({
30-
en: 'Check out ',
31-
fr: 'Vérifiez ',
32-
es: 'Compruebe ',
33-
}),
34-
t({
35-
en: 'create-vue',
36-
fr: 'create-vue',
37-
es: 'create-vue',
38-
}),
39-
t({
40-
en: ', the official Vue + Vite starter',
41-
fr: ', le starter officiel Vue + Vite',
42-
es: ', el starter oficial Vue + Vite',
43-
}),
44-
],
45-
learnMore: [
46-
t({
47-
en: 'Learn more about IDE Support for Vue in the ',
48-
fr: 'En savoir plus sur le support IDE pour Vue dans le ',
49-
es: 'Aprenda más sobre el soporte IDE para Vue en el ',
50-
}),
51-
t({
52-
en: 'Vue Docs Scaling up Guide',
53-
fr: 'Vue Docs Scaling up Guide',
54-
es: 'Vue Docs Scaling up Guide',
55-
}),
56-
t({
57-
en: ',',
58-
fr: ',',
59-
es: ',',
60-
}),
61-
],
62-
clickOnLogos: [
63-
t({
64-
en: 'Click on the Vite and Vue logos to learn more',
65-
fr: 'Cliquez sur les logos Vite et Vue pour en savoir plus',
66-
es: 'Haga clic en los logotipos de Vite y Vue para obtener más información',
67-
}),
68-
],
6933
},
7034
} satisfies Dictionary;
7135

examples/vite-vue-app/src/helloworld.content.ts

Lines changed: 0 additions & 44 deletions
This file was deleted.

examples/vite-vue-app/src/main.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { createApp } from 'vue';
2+
import { installIntlayer } from 'vue-intlayer';
23
import App from './App.vue';
34
import './style.css';
45

56
const app = createApp(App);
67

8+
// Inject the provider at the top level
9+
installIntlayer(app); // provide the singleton instance
10+
711
// Mount the app
812
app.mount('#app');

examples/vite-vue-app/tsconfig.json

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"$schema": "https://json.schemastore.org/tsconfig",
3+
"compilerOptions": {
4+
"target": "ES2020",
5+
"useDefineForClassFields": true,
6+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
7+
"module": "ESNext",
8+
"skipLibCheck": false,
9+
10+
/* Bundler mode */
11+
"moduleResolution": "bundler",
12+
"allowImportingTsExtensions": true,
13+
"resolveJsonModule": true,
14+
"isolatedModules": true,
15+
"noEmit": true,
16+
17+
/* Linting */
18+
"strict": true,
19+
"noUnusedLocals": true,
20+
"noUnusedParameters": true,
21+
"noFallthroughCasesInSwitch": true
22+
},
23+
"include": ["**/*", ".intlayer/**/*.ts"],
24+
"exclude": ["node_modules", "dist"]
25+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import configuration from '@intlayer/config/built';
2+
import type { LocalesValues } from '@intlayer/config/client';
3+
import { ref } from 'vue';
4+
import { INTLAYER_SYMBOL } from '../constants';
5+
import type { IntlayerProvider } from '../types/intlayer';
6+
7+
/**
8+
* Singleton instance
9+
*/
10+
let instance: IntlayerProvider | null = null;
11+
12+
/**
13+
* Create and return a single IntlayerProvider instance
14+
*/
15+
export const createIntlayerClient = (): IntlayerProvider => {
16+
if (instance) return instance;
17+
18+
const { defaultLocale } = configuration.internationalization ?? {};
19+
20+
const locale = ref<LocalesValues>(defaultLocale);
21+
22+
const setLocale = (newLocale: LocalesValues) => {
23+
locale.value = newLocale;
24+
};
25+
26+
instance = {
27+
locale,
28+
setLocale,
29+
};
30+
31+
return instance;
32+
};
33+
34+
/**
35+
* Helper to install the Intlayer provider into the app
36+
*/
37+
export const installIntlayer = (app: any) => {
38+
const client = createIntlayerClient();
39+
app.provide(INTLAYER_SYMBOL, client);
40+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export * from './createIntlayerClient';
12
export * from './useDictionary';
23
export * from './useIntlayer';
34
export * from './useLocale';
Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import type { LocalesValues } from '@intlayer/config/client';
22
import type { Dictionary } from '@intlayer/core';
3-
import { computed, ref } from 'vue';
3+
import { computed, inject } from 'vue';
4+
import { INTLAYER_SYMBOL } from '../constants';
45
import { getDictionary } from '../getDictionary';
6+
import { IntlayerProvider } from '../types/intlayer';
57

68
export const useDictionary = <T extends Dictionary>(
79
dictionary: T,
810
locale?: LocalesValues
911
) => {
10-
const currentLocale = ref<LocalesValues>();
11-
const localeTarget = computed(() => locale ?? currentLocale.value);
12+
const intlayer = inject<IntlayerProvider>(INTLAYER_SYMBOL);
1213

13-
return getDictionary<T, LocalesValues>(dictionary, localeTarget.value);
14+
const localeTarget = computed(() => locale ?? intlayer?.locale.value);
15+
16+
return computed(() =>
17+
getDictionary<T, LocalesValues>(dictionary, localeTarget.value)
18+
);
1419
};
Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import type { LocalesValues } from '@intlayer/config/client';
22
import { DeepTransformContent, DictionaryKeys } from '@intlayer/core';
3-
import { computed, ref } from 'vue';
3+
import { computed, type ComputedRef, inject } from 'vue';
44
// @ts-ignore intlayer declared for module augmentation
55
import type { IntlayerDictionaryTypesConnector } from 'intlayer';
6+
import { INTLAYER_SYMBOL } from '../constants';
67
import { getIntlayer } from '../getIntlayer';
8+
import { IntlayerProvider } from '../types/intlayer';
79

810
/**
911
* On the client side, Hook that picking one dictionary by its key and return the content
@@ -13,9 +15,12 @@ import { getIntlayer } from '../getIntlayer';
1315
export const useIntlayer = <T extends DictionaryKeys>(
1416
key: T,
1517
locale?: LocalesValues
16-
): DeepTransformContent<IntlayerDictionaryTypesConnector[T]['content']> => {
17-
const currentLocale = ref<LocalesValues>();
18-
const localeTarget = computed(() => locale ?? currentLocale.value);
18+
): ComputedRef<
19+
DeepTransformContent<IntlayerDictionaryTypesConnector[T]['content']>
20+
> => {
21+
const intlayer = inject<IntlayerProvider>(INTLAYER_SYMBOL);
1922

20-
return getIntlayer(key, localeTarget.value);
23+
const localeTarget = computed(() => locale ?? intlayer?.locale?.value);
24+
25+
return computed(() => getIntlayer(key, localeTarget.value));
2126
};

packages/vue-intlayer/src/client/useLocale.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import configuration from '@intlayer/config/built';
22
import type { LocalesValues } from '@intlayer/config/client';
33
import { localeList } from '@intlayer/core';
4-
import { computed, inject } from 'vue';
4+
import { computed, inject, ref, watch } from 'vue';
55
import { INTLAYER_SYMBOL } from '../constants';
66
import type { IntlayerProvider } from '../types/intlayer';
77
import { useLocaleCookie } from './useLocaleCookie';
@@ -19,15 +19,36 @@ export const useLocale = ({ onLocaleChange }: useLocaleProps = {}) => {
1919
const intlayer = inject<IntlayerProvider>(INTLAYER_SYMBOL);
2020
const { setLocaleCookie } = useLocaleCookie();
2121

22-
const locale = computed(() => intlayer?.locale.value ?? defaultLocale);
22+
// Create a reactive reference for the locale
23+
const currentLocale = ref(intlayer?.locale?.value ?? defaultLocale);
24+
25+
// Watch for changes in the intlayer locale and update our local state
26+
if (intlayer?.locale) {
27+
watch(
28+
() => intlayer.locale.value,
29+
(newLocale) => {
30+
if (newLocale) {
31+
currentLocale.value = newLocale;
32+
}
33+
},
34+
{ immediate: true }
35+
);
36+
}
37+
38+
// Exported computed value based on our local reactive reference
39+
const locale = computed(() => currentLocale.value);
2340

2441
const setLocale = (newLocale: LocalesValues) => {
2542
if (!availableLocales?.map(String).includes(newLocale)) {
2643
console.error(`Locale ${newLocale} is not available`);
2744
return;
2845
}
2946

30-
intlayer?.setLocale(newLocale);
47+
// Update both the local ref and intlayer
48+
currentLocale.value = newLocale;
49+
if (intlayer) {
50+
intlayer.setLocale(newLocale);
51+
}
3152
setLocaleCookie(newLocale);
3253
onLocaleChange?.(newLocale);
3354
};

0 commit comments

Comments
 (0)