docs
  1. Storefront Application
  2. Technical Foundation
  3. Data & State

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.