-
-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
useAsyncData and useFetch run twice if page uses layout #13369
Comments
Same problem here |
Hello! We experience the same issue in @nuxt/content docs theme, to lighten the investigation I also built reproduction on StackBlitz. You can see there that on first page load, the random integer will be refetched on client side and the data fetched server side won't be preserved. https://stackblitz.com/edit/nuxt3-repro-utzcxx?file=pages%2F[...id].vue |
This seems to be an upstream issue: see vuejs/router#626 (comment) |
@danielroe - I noticed this as well, So i removed layout and the issue was resolved. Although, once i introduced a second API call using
|
I did the same thing with the backend written in golang, using useFetch or useAsyncData to request api, both triggered twice.This problem needs to be solved urgently |
@Baiyuetribe From what you've said, it's possible your browser is requesting a favicon along with the HTML request. If you don't have a pages directory or a favicon, Nuxt will respond to both requests with a full HTML page, which means you will get two asyncData requests to your API. The specific bug here seems to be upstream in Vue, triggered by having nested |
@danielroe I'm not talking about the icon problem, I use golang to develop the back-end api interface and then use nuxt3 to call the api to achieve server-side rendering. Even in the minimal demo, the request is triggered twice.In the default <template>
<div>
<h3>{{ data }}</h3>
</div>
</template>
<script setup>
const { data } = await useFetch('http://192.168.1.3:363/api/home', { server: true })
</script> I think the first time the usefetch may have worked, the second time it may have been triggered by |
@Baiyuetribe Would you provide a reproduction? I'm still thinking the issue in your case is the extra favicon request. |
@danielroe I provide a reproduction here: |
@danielroe sandbox https://stackblitz.com/edit/github-5qtamp?file=app.vue You can see that after one server-side request, the client will request it again. So it causes second requests. |
@Baiyuetribe Your issue is unrelated to this particular thread. The cause is your browser requesting As a consequence, you will receive two requests to your API. That can easily make you think that it's running twice, even though it is only running once per render. It is easily solved by adding a |
@danielroe Thank you very much. It works fine after adding favicon.ico. Highly recommend adding it to the template, I almost gave up because of this problem. |
After fixing the icon issue,When there are layouts, it does lead to a second request from the client, and the problem can lead to repeated rendering of the page |
@Baiyuetribe Please see #13369. |
@danielroe When useFetch parameter server: true, can the client block the request? |
Temporarily, I found that after deleting the |
@danielroe sandbox https://stackblitz.com/edit/github-5qtamp-82ca6q?file=app.vue |
@Baiyuetribe The problem does not seem to be with Nuxt but with This issue exists, at the moment, to track the resolution of the issue within vuejs/core or vue-router. If you spot an issue with the way layouts or pages are implemented in Nuxt, of course I would be very glad to hear that. |
@codelegant I've tried the fetching with |
@danielroe thanks for the info, I am not on the latest version. I might as well wait until the RC is released (7th of this month? 🙏🏻 ) to upgrade. I'll probably forget to post here when I upgrade if the issue is fixed, but then you can assume it is 😛 |
The async data no need fetching in server. |
@danielroe this last fix solved my problem perfectly, so I think the core issue is resolved at least as far as I can tell. |
if page uses layout, child page will setup twice |
I'm on "nuxt": "3.0.0-rc.5", and I'm still seeing this same behavior. All useFetch (or $fetch) calls occur twice - once SSR, and again on client. It doesn't matter if I am using a layout or not. |
@nathanchase would you create a new issue with a reproduction? 🙏 |
It appears to be pinia at fault. If I delete pinia from my modules in nuxt.config, useFetch/$fetch no longer loads data twice. I'm using "@pinia/nuxt": "^0.3.0", and "pinia": "^2.0.16". Will try to create a barebones repro. |
@danielroe False alarm. It was a matter of data being pushed into an array errantly inside a for loop inside a store action. |
Hey, I just came across this thread because I faced the same issue. When using a Pinia action within I boiled it down to this issue: I wrote a wrapper composable to have a workaround that looks like this: // Use this composable to prefill a store with an action
// Hack to tell nuxt that this function was executed
export const usePrefillStoreAction = async (action: () => Promise<unknown>) => {
await useAsyncData(async () => {
await action();
// TODO: create issue that Pinia somehow needs to return a value from the action?
return Promise.resolve('true');
});
}; Not sure if I need to file an issue on the Nuxt repo or Pinia repo. Let me know what you think. cc: @danielroe |
In this case you might even find it better to use the vue |
@danielroe my use case is pretty simple: I want to invoke a pinia action to get page-specific data whenever a user navigates to that page, either by visiting it directly or on client-side navigation. As far as the docs say and the name implies In Nuxt 2 asyncData was sufficient for this basic use case. |
Yes, that's right. |
@danielroe what would be your recommended solution then? Not using Pinia? |
The way I've done it is like so: const { data: user } = await useAsyncData(username, async () => {
await usersStore.getUser(username); // <- this is calling the getUser action from the usersStore
return usersStore.user; // <- this returns the actual state value from the store once the above promise resolves
}); |
@nathanchase good to know that this works. I will have a look and think about the pros and cons between your solution and mine. Thanks a lot 👍 |
So, FWIW... I've stumbled upon this behavior while working on a simple app to test out Nuxt 3 and I've noticed that it exists even without a template going on. I tested a couple of solutions others have mentionned but to no avail so I tried something; used a reactive value instead of constant to generate my API url and lo and behold, it ended up working. Sadly, I'm no nuxt/Vue wizard, but I thought I'd share this with you guys as it could maybe help you guys out figuring the root of this. Here's a StackBlitz example, you'll see the second Pokemon flashing on the client side fetching. PS: see, this is what happens when you have a 4 year run old in your house, all your test cases end up being about Pokemons ;x |
@Nicolas-Nmedia @milelazar @danielroe I've tried countless things trying to debug this but just can't seem to figure it out. So far what I've noticed is that:
Route 1:
Route 2:
Both pages contain the exact same code. I've tried removing You can see the behavior on this link. Inspect and see network tab. You'll notice the "Recent blog posts" section appear and then disappear because a client side call happened and didn't hit any endpoints because this is SSG. |
@MrSunshyne would you create a new issue with a reproduction? That should not be happening. |
@danielroe I managed to narrow it down to this. It appears the problem is not nuxt3 itself but looks like something could be related to this issue #19887 |
@MrSunshyne have you tried useNuxtData? Maybe you can build a caching logic. Fetch some data with useFetch and then useNuxtData pulls that cached data without fetching again. This solved my problem with refetching. Take a look at this: #19912 (comment) |
In my project useFetch only runs twice when it gets 500 response. Does this maybe relates to this issue? Also using layout and running with nuxt 3.3.3 |
This really worked for me. I still don't understand why, but thanks. |
Environment
Reproduction
https://github.com/lukaszflorczak/nuxt3-demo/tree/test/fetch (branch
test/fetch
)./
page and check console logsindex.vue
and setlayout: false
indefinePageMeta()
Describe the bug
Today I noticed that
useAsyncData
anduseFetch
run requests twice – both server and client-side. I tested it in component and page.During my investigation, I found, that the problem exists only if the page uses a layout.
Probably it's related to nuxt/framework#3011
The text was updated successfully, but these errors were encountered: