Last active
March 13, 2024 17:51
-
-
Save romainavalle/638dcffb657fe49857a00a45aa3ecf48 to your computer and use it in GitHub Desktop.
Dynamic slugs with nuxt/I18n SSR
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script setup> | |
import query from '~/assets/graphql/query.graphql' | |
const { $bus, $query, $i18n } = useNuxtApp() | |
const route = useRoute() | |
const { | |
params: { slug }, | |
} = route | |
const lang = $i18n.locale.value | |
const uri = `legal_${slug}_${lang}` | |
try { | |
const { data } = await useAsyncData( | |
uri, //Key used for the request | |
() => $query(query, { uri, slug, locale: lang }) | |
) | |
if (data.value) { | |
page.value = data.value.page | |
// i18n | |
const slugLocales = {} | |
const setI18nParams = useSetI18nParams() | |
for (const key of page.value._allSlugLocales) { | |
slugLocales[key.locale] = { slug: key.value } | |
} | |
setI18nParams(slugLocales) | |
$bus.$emit(route.fullPath.replaceAll('/', '-')) | |
} | |
} catch (error) { | |
throw showError({ | |
statusCode: 404, | |
statusMessage: 'Page Not Found', | |
fatal: true, | |
}) | |
} | |
</script> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script setup> | |
const waitForEventOrTimeout = async ( | |
eventEmitter, | |
eventName, | |
maxTime = 500, | |
) => { | |
return new Promise((resolve, reject) => { | |
let timer | |
const eventHandler = (...args) => { | |
console.log('waited eventHandler') | |
clearTimeout(timer) | |
resolve(args) | |
} | |
eventEmitter.$on(eventName, eventHandler) | |
timer = setTimeout(() => { | |
console.log('waited timeout') | |
eventEmitter.$off(eventName, eventHandler) | |
resolve() | |
}, maxTime) | |
}) | |
} | |
const { $bus } = useNuxtApp() | |
const route = useRoute() | |
const { locale, locales } = useI18n() | |
const page = ref({}) | |
const switchLocalePath = useSwitchLocalePath() | |
await waitForEventOrTimeout($bus, route.fullPath.replaceAll('/', '-')) | |
const availableLocales = computed(() => { | |
return locales.value.filter((i) => i.code !== locale.value) | |
}) | |
</script> | |
<template> | |
<div class="common-lang-switcher"> | |
<nuxt-link | |
v-for="lang in availableLocales" | |
:key="lang.code" | |
:to="switchLocalePath(lang.code)" | |
> | |
{{ lang.code }} | |
</nuxt-link> | |
</div> | |
</template> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
From i18n docs :
During SSR it matters when and where you set i18n parameters, since there is no reactivity during SSR.
Components which have already been rendered do not update by changes introduced by pages and components further down the tree. Instead, these links are updated on the client side, so this should not cause any issues.
My solution here is to wait the data to render the LangSwitcher component