Data & State
Overview
Developing a modern e-commerce application often requires fetching significant amounts of data for a single page, such as category details, product information, and potentially enriching this data by fetching from external sources. Efficiently managing these asynchronous operations and handling the resulting state across your application is crucial for performance and maintainability.
The SCAYLE Storefront Application, built on Nuxt 3, leverages Nuxt's powerful built-in composables like useAsyncData
to address these challenges. useAsyncData
is the recommended way to fetch asynchronous data in Nuxt 3, automatically handling server-side rendering (SSR), client-side navigation, caching, error handling, and data hydration.
Asynchronous Data Fetching
The useAsyncData
composable takes an asynchronous handler function where you place your data fetching logic. This handler function is executed on the server during SSR and on the client during navigation. Within this handler, you have full control over how multiple fetch calls are executed: serially, in parallel, or a combination.
For Storefront Composables, the key
is typically auto-generated internally. You might need to pass it manually, for instance, to simplify debugging of _asyncData
or when using useNuxtData
.
Serial Execution
Place your fetch calls using await
inside the useAsyncData
handler to execute them sequentially. This is necessary when a subsequent fetch call depends on the result of a previous one.
While this approach ensures the correct order of execution, it can potentially increase overall page loading times due to the sequential nature of the requests.
Parallel Execution
If your data fetch calls are independent, use Promise.all
within the useAsyncData
handler to execute them in parallel. This can significantly reduce the total loading time.
This pattern initiates all fetch calls simultaneously and waits for all of them to complete before returning the final data.
Mixed Execution
You can combine serial and parallel execution patterns within the useAsyncData
handler. For example, you might start some independent fetches while waiting for others that have dependencies.
This allows for fine-grained control over your data fetching strategy, balancing dependencies with performance within a single useAsyncData
call.
Shared State and Caching
The useRpc
composable, used by many Storefront composables, internally also relies on shared state behavior that can be manually disabled:
One of the most powerful features of useAsyncData
is its built-in state management and caching based on the unique key
provided as its first argument. This key is used by Nuxt's internal state tree, allowing the state (data, pending, error) associated with a specific key to be shared across your application.
This key-based sharing is crucial for SSR and hydration. Data fetched on the server using useAsyncData
with a specific key is automatically serialized and sent to the client. When useAsyncData
is called on the client with the same key, Nuxt rehydrates the state from the server payload instead of refetching the data, ensuring a smooth transition and immediate reactivity.
SCAYLE Storefront composables, including those that wrap RPC methods, are designed to leverage useAsyncData
and this key-based sharing mechanism.
Managing Shared State
The useRpc
composable, used by many Storefront composables, internally relies on shared state behavior that can be manually disabled.
Consider a useNews
composable (which internally uses useAsyncData
):
In this scenario, both newsA
and newsB
instances returned by useNews
point to the same reactive data state managed by useAsyncData
under the 'my-news-section'
key. This is a fundamental pattern: you can call the same composable in multiple components, but the underlying data fetching and state management for a given key happen only once per request/navigation, and all instances using that key access the shared state.
Preventing State Sharing
If you require independent state for different instances of the same composable or for data that should not be shared via the key, provide unique keys or omit the key (though omitting the key disables caching and is generally not recommended for fetched data). Removing the key
will prevent sharing data and trigger independent calls for the usage of a useAsyncData
instance without request deduping. As Storefront Composables automatically generate unique key
internally, hydration will still work as expected between server and client.
By providing distinct keys, useAsyncData
treats them as separate data sources, managing their state, caching, and hydration independently.
Understanding how useAsyncData
's key facilitates shared state and integrates with Nuxt's SSR and hydration is crucial for effectively handling data and building performant components in the SCAYLE Storefront Application.
More details can be found in the official Nuxt "Data Fetching" Guide or the "useAsyncData vs. useFetch" YouTube video by Alexander Lichter, a Core Maintainer of Nuxt.