typesafe-i18n
typesafe-i18n copied to clipboard
Vue: namespace not being loaded
Version
5.26.2
Describe the bug
When loadNamespaceAsync
has resolved, the namespace is still undefined in LL
.
Reproduction
// main.ts
import { createApp } from "vue";
import { i18nPlugin } from "@/Assets/i18n/i18n-vue";
import { detectLocale } from "@/Assets/i18n/i18n-util";
import { loadLocaleAsync } from "@/Assets/i18n/i18n-util.async";
import { navigatorDetector } from "typesafe-i18n/detectors";
import App from "./App.vue";
const app = createApp(App);
const detectedLocale = detectLocale(navigatorDetector);
loadLocaleAsync(detectedLocale).then(() => {
app.use(i18nPlugin, detectedLocale);
app.mount("#app-root");
});
// Locale.ts
import { typesafeI18n } from "@/Assets/i18n/i18n-vue";
import { loadNamespaceAsync } from "@/Assets/i18n/i18n-util.async";
import {
type Locales,
type Namespaces,
type TranslationFunctions,
} from "@/Assets/i18n/i18n-types";
import { computed, ref, type Ref } from "vue";
const loadedNamespaces = ref<Set<Namespaces>>(new Set());
export function useLocaleNameSpace<T extends Namespaces>(
nameSpace: T,
): Ref<TranslationFunctions[T] | null> {
const { LL, locale } = typesafeI18n();
const ready = computed(() => loadedNamespaces.value.has(nameSpace));
if (!ready.value)
loadNamespaceAsync(locale.value, nameSpace).then(() => {
loadedNamespaces.value.add(nameSpace);
});
return computed(() => {
return ready.value ? LL.value[nameSpace] : null;
});
}
export function useLocaleCommon() {
const { LL } = typesafeI18n();
return LL as Omit<typeof LL, Namespaces>;
}
export function useSetLocale() {
const { setLocale: _setLocale } = typesafeI18n();
return (locale: Locales) => {
_setLocale(locale);
loadedNamespaces.value.clear();
};
}
// src/Assets/i18n/en/reports/index.ts
import type { BaseTranslation } from "../../i18n-types";
export default {
adminReports: "Administration",
eac: "Estimate At Completion",
eacManual: "EAC Manual",
eac_min: "Estimate",
header1: "Code",
header2: "Task",
header3: "Header3",
header4: "Header4",
header5: "Header5",
hoursReports: "Hours",
invalidSourceCurve: "Invalid source curve '{0}'",
invalidTargetCurve: "Invalid target curve '{0}'",
noFilters: "No filters",
noSourceScurveData:
"No scurve data for source component 'sourceComponentId: {0}|sourceCurve: {1}'",
noTargetAssignmentHourDistribution:
"No AssignmentHourDistribution data for target component: '{0}|type: {1}'",
noTargetComponentActivities:
"No activities for target component 'targetComponentId: {0}'",
planningReports: "Planning",
reportData: "Report Data",
showHideMarkers: "Show/hide Markers",
showReportData: "Show Report Data",
text1FilterPlaceholder: "Example: 1230,1240,1250",
text2FilterPlaceholder: "Example: 1230,1240,1250",
text3FilterPlaceholder: "Example: 1230,1240,1250",
text4FilterPlaceholder: "Example: 1230,1240,1250",
text5FilterPlaceholder: "Example: 1230,1240,1250",
worklistPerProject: "Worklist per project",
worklistPerProjectFileName: "worklist-per-project",
worklistPerProjectQr: "Worklist per project (QR)",
} satisfies BaseTranslation;
<!-- ReportPage.vue -->
<script setup lang="ts">
import { useLocaleNameSpace } from "@/Composables/Locale";
const LL = useLocaleNameSpace("reports");
</script>
<template>
<div v-if="LL">
Ready
{{ LL.invalidSourceCurve("test") }}
</div>
<div v-if="!LL">Loading</div>
</template>
Renders: Ready
Logs
No response
Config
// .typesafe-i18n.json
{
"adapter": "vue",
"esmImports": true,
"outputPath": "./src/Assets/i18n",
"$schema": "https://unpkg.com/[email protected]/schema/typesafe-i18n.json"
}
Additional information
No response