N
Nuxt8mo ago
Henrik

useRoute() causing hydration mismatches

I am using useRoute() to conditionally render classes and elements. All works well on dev but when deployed as SSG I get very strange results and "Hydration completed but contains mismatches" in the console. In a child component a prop which value is determined by useRoute().query is used for both v-f and conditional styles and classes. The v-if is working as expected but the class and style bindings are not. https://stackblitz.com/edit/nuxt-starter-umaxer Note that you have to run npx nuxt generate and npx nuxt start or deploy as SSG. Adding ?box=second to the url renders the second box with "inactive" styles and classes but the v-if is rendered as active. "Hydration completed but contains mismatches" is logged in the console. I am really at a loss here, any input would be really helpful! app.vue
<template>
<div style="display: flex; gap: 16px">
<Box :active="box === 'first'"> First </Box>
<Box :active="box === 'second'"> Second </Box>
</div>
</template>
<script setup lang="ts">
const routeQuery = useRoute().query;

const box = ref(routeQuery.box || "first");
</script>
<template>
<div style="display: flex; gap: 16px">
<Box :active="box === 'first'"> First </Box>
<Box :active="box === 'second'"> Second </Box>
</div>
</template>
<script setup lang="ts">
const routeQuery = useRoute().query;

const box = ref(routeQuery.box || "first");
</script>
` box.vue
<template>
<button
style="padding: 16px"
:class="[active ? 'active' : 'inactive']"
:style="[active ? 'color:red' : 'color:black']"
>
<slot />
<span v-if="active">Active</span>
<span v-else>Inactive</span>
</button>
</template>
<script setup lang="ts">
defineProps({
active: {
type: Boolean,
default: false,
},
});
</script>
<template>
<button
style="padding: 16px"
:class="[active ? 'active' : 'inactive']"
:style="[active ? 'color:red' : 'color:black']"
>
<slot />
<span v-if="active">Active</span>
<span v-else>Inactive</span>
</button>
</template>
<script setup lang="ts">
defineProps({
active: {
type: Boolean,
default: false,
},
});
</script>
Henrik Hansson
StackBlitz
useRoute.query reactivity - StackBlitz
Create a new Nuxt project, module, layer or start from a theme with our collection of starters.
2 Replies
Henrik
HenrikOP8mo ago
I have looked further into this and it seems like useRoute is causing the hydration mismatches. The problem occurs even in this very minimal example when deployed as SSG or npx nuxt generate & npx nuxt start. Is useRoutebroken? Edit: solved! Wrapping in client-only solved the problem, needed when using query parameters in SSG. app.vue
<template>
<client-only>
...
</client-only>
</template>
<script setup lang="ts">
const route = useRoute();
const active = ref(route.query.box || false);
</script>
<template>
<client-only>
...
</client-only>
</template>
<script setup lang="ts">
const route = useRoute();
const active = ref(route.query.box || false);
</script>
manniL
manniL8mo ago
because SSG can't generate "the site version with the query params" for you
Want results from more Discord servers?
Add your server