useAsyncData(..., { server: false }) in combination with .client.vue not working correctly
I have a couple pages that I don't want Nuxt to render server-side, but I do want navigations to be blocking when navigating to one of these pages. Here's an example page:
This works great, until I change the page suffix from
.vue
to .client.vue
to disable SSR:11 Replies
Hi @Rowin. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
Based on the information provided in the knowledge sources, I can explain why your approach with
.client.vue
and useAsyncData
with server: false
is not working as expected.
When you use the .client.vue
suffix for a page, you're explicitly telling Nuxt to render this component only on the client side. This conflicts with the behavior of useAsyncData
, even when server: false
is set.
According to the Nuxt documentation on data fetching (https://nuxt.com/docs/getting-started/data-fetching#client-only-fetching):
"If you have not fetched data on the server (for example, with server: false
), then the data will not be fetched until hydration completes. This means even if you await useAsyncData
on client-side, data
will remain null within <script setup>
."
This behavior explains why your approach isn't working as expected. When you use .client.vue
, the component is only rendered on the client side, and the useAsyncData
call won't block navigation or fetch data before the component is mounted.
To achieve what you're looking for - client-side rendering with blocking navigation - you have a couple of options:
1. Use a regular .vue
file and disable SSR for specific routes using route rules (https://nuxt.com/docs/guide/concepts/rendering#hybrid-rendering). This allows you to keep using useAsyncData
with server: false
while still blocking navigation.
2. If you want to stick with .client.vue
files, you'll need to handle the loading state manually, as the data fetching won't block navigation. You can use useLazyFetch
or useLazyAsyncData
for this purpose.
Here's an example of how you could modify your code to work with a .client.vue
file:
This approach doesn't block navigation, but it allows you to handle the loading state within the component.
Remember, if you want to disable SSR for specific routes while still using useAsyncData
with blocking navigation, the recommended approach is to use route rules (https://nuxt.com/docs/guide/concepts/rendering#hybrid-rendering) instead of .client.vue
files.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@874982799973699624> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Using
works... but I'd really prefer
.client.vue
instead of having to put a bunch of paths in my Nuxt config.
@kapa.aiLet me check the knowledge base for you again. One moment! :books:
Sorry @Rowin, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?
@kapa.ai
Let me check the knowledge base for you again. One moment! :books:
Sorry @Rowin, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?
😔
defineRouteRules
seems like a good solution here. Experimental though.
Works though!I'd raise that. this should work
Does it work w/o awaiting though?
Without await the navigation is instant and the data is rendered after a second (unless it's been fetched before, then it's doing stale-while-revalidate).
correct
but you can handle loading state
I'm aware, but I want blocking navigations