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>