content
content copied to clipboard
i18n - How I'm supposed to get the correct page linked to correct locale ?
Environment
Classic nuxt 3 project with this as nuxt.config :
modules: ["@nuxt/content", "@nuxtjs/i18n", '@nuxt/devtools'],
content: {
locales:[
'en', 'fr'
],
defaultLocale: 'fr'
},
i18n: {
strategy: 'prefix',
defaultLocale: 'fr',
baseUrl: process.env.BASE_URL || 'https://localhost:3000',
detectBrowserLanguage: {
useCookie: true,
cookieKey: 'i18n_redirected',
redirectOn: 'root', // recommended
},
locales: [
{
code: 'en',
iso: 'en-US'
},
{
code: 'fr',
iso: 'fr-FR'
}
]
}
This is the content folder :
Reproduction
Use a catchall page [...slug].vue
in the pages directory with the same structure as me & same nuxt config
Try to fetch all pages :
const data = await queryContent().where({ _locale: locale.value }).find()
console.log(data)
You'll get this :
But when you will use :
const { path } = useRoute()
const { locale } = useI18n()
const data = await queryContent().where({ _locale: locale.value, _path: path }).findOne()
console.log(data)
You will normally get this :
Describe the bug
where
query parameter is maybe broken with multi lang. It won't fetch the correct page but will fetch correctly multiples pages in the folder.
I believe it is not linked to the module i18n.
Additional context
No response
Logs
No response
What is the value of path
? Note that you should remove locale from path
before passing it to queryContent
.
Also do you ming creating a simple reproduction using Content Starter?
@Pamavoc I had some issues as well.
This works for me:
<template>
<NuxtLayout>
<h1>{{ data.title }}</h1>
<div>{{ data.description }}</div>
<ContentRenderer :key="data._id" :value="data.body">
<ContentRendererMarkdown :value="data" />
</ContentRenderer>
</NuxtLayout>
</template>
<script setup>
const { locale: { value: localCode }} = useI18n()
const { data } = await useAsyncData(`/${localCode}`, () => queryContent(`/`).where({ _locale: localCode }).findOne())
</script>
But I'm not sure is the most elegant solution.
Thanks for your insights, after a few try, I think I got it right working also with hierachy /locale/../.../page.md
<script setup lang="ts">
import type { ParsedContent } from "@nuxt/content/dist/runtime/types";
const {
params: { slug },
} = useRoute();
const { locale } = useI18n();
function redirect404() {
const router = useRouter();
router.push("/404");
}
interface ContentError extends Error {
statusCode: number;
}
const { data, pending, error, refresh } = await useAsyncData<
ParsedContent,
ContentError
>(`nuxt-content:${useRoute().fullPath}`, () =>
queryContent("/")
.where({ _locale: locale.value, _path: `/${(slug as string[]).join("/")}` })
.findOne()
);
if (error.value && error.value.statusCode === 404) {
redirect404();
}
</script>
<template>
<pre>
{{ data }}
</pre>
<main v-if="data">
<ContentRenderer v-if="data" :value="data" />
</main>
</template>