Skip to content

Instantly share code, notes, and snippets.

@romainavalle
Last active March 13, 2024 17:51
Show Gist options
  • Save romainavalle/638dcffb657fe49857a00a45aa3ecf48 to your computer and use it in GitHub Desktop.
Save romainavalle/638dcffb657fe49857a00a45aa3ecf48 to your computer and use it in GitHub Desktop.
Dynamic slugs with nuxt/I18n SSR
<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>
<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>
@romainavalle
Copy link
Author

romainavalle commented Mar 13, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment