#True or False: If SSR data-fetching is working correctly, I shouldn't see fetches in client devtools

19 messages · Page 1 of 1 (latest)

raven plank
#

Assuming the route is set to ssr: true, and I'm using either useFetch() or useAsyncData() as a top-level await within a component, the data should be fetched on the server then pushed to the client.

Am I wrong in my understanding that there should be no evidence of any fetches from my browser? I don't have a repro for you, but this is a build on Netlify: https://powerconnector.netlify.app/

On that site, navigation from / to /products to /products/cable-mount-power and back result result in a client fetch request every time (I think). Unless I'm completely misunderstanding this, it seems like I shouldn't see those in Chrome's Network tab.

Furthermore, regardless of the origin of these fetch requests, I was under the impression that useFetch() and useAsyncData() were supposed to prevent redundant API calls. Am I misunderstanding this? I have three components with one useFetch() each. They are always the same, the parameters/queries never change, and they are each designated with a unique key. I can see the fetched data in the Payload tab of the Nuxt Devtools. Yet they appear to be refetched every time I return to the components/pages within which they reside.

Am I crazy?? Thank you in advance. goodGuyDom

quasi plaza
#

Is this in dev mode?
I might be wrong, but I seem to remember that in dev mode the fetch happens on both server and client?

bleak scarab
raven plank
raven plank
#

But can anyone address the true or false question in the post title? I know it must seem like a no-brainer question, but I'm mostly self-taught and I have no confidence in my own judgement 😅

#

In the meantime I'll reproduce a slice of the project for sharing

bleak scarab
#

When you navigate (/a to /b) that can still happen though

raven plank
#

iiiiiiiinteresting... in that case, it IS working as intended. THANK YOU!

#

So client fetches can happen when navigating between routes. But they don't necessarily have to?

For instance, when I go back-and-forth between /products and /products/[slug], even if I expect to wait for a client fetch upon loading each page for the first time, by my reading of the Data Fetching guide (https://nuxt.com/docs/getting-started/data-fetching), I'd expect the "effective caching" to kick in and reduce load times upon revisiting the pages

#

Is it because it's a nested route?

#

I understand useNuxtData() is there to access the cached data, but the line "useFetch and useAsyncData use keys to prevent refetching the same data." Leads me to believe it should be done automatically.

bleak scarab
raven plank
#

Okay, follow up. Mind if I run this by you, @bleak scarab ?

I've implemented a "fetch and store" pattern on app.vue and the child components that use API data. It's filled with intentional redundancies. It works, and I'm happy with it, but I'm afraid there might be a smarter way to do it. Does this look kosher to you?

Here's an example from my /products page:

// get the composables
// fetchProducts is a $fetch call
// storeAll is a useState; transform is an argument for useAsyncData

const { fetchProducts } = useWoo()             
const { storeAll, transform } = useProducts()  


// fetch the data immediately if rendering on server, if on client we'll check for existing state data first

const { data, pending, execute } = await useAsyncData(
  'fetch-products-page',
  () => fetchProducts(), {
    transform,
    immediate: !!process.server,
  },
)


// compute the value of the 'products-all' state

const storedProductsAll = computed(() => storeAll().value)


// compute the value of any existing fetch cache; check if there's any from THIS page first, or else the one from app.vue ('fetch-products-all')

const cachedProductsPage = computed(() => useNuxtData('fetch-products-page').data.value ?? useNuxtData('fetch-products-all').data.value)


// compute the value of this page's fetch

const fetchedProductsPage = computed(() => data.value)


// if there isn't any 'products-all' state, await this page's fetch and store the result as the 'products-all' state
// and if we're the client, execute the fetch first

if (!storeAll().value) {
  if (process.client)
    execute()
  await until(pending).toBe(false)
  storeAll().value = fetchedProductsPage.value as Product[]
}


// finally, allProducts is the variable the <template> actually uses
// if there's a state, use that; otherwise check for the fetch cache, or as a last resort, await the fetch itself

const allProducts = computed(() => storedProductsAll.value ?? cachedProductsPage.value ?? fetchedProductsPage.value)

edited for readability

frank oyster
#

Looks more vegan than kosher 😏

raven plank
#

I'll take it!

bleak scarab
raven plank