Essentials

Caching

Caching Shopify Storefront API and Admin API requests, best practices and strategies for improving performance in your Nuxt Shopify app.

If you want to improve the performance of your Nuxt Shopify app, consider using a cache for your Storefront API and Admin API requests. Caching can help reduce the number of API calls, decrease latency, and improve the overall user experience.

Caching Storefront API Requests

Since the Storefront API can be used on the server and client side, there are different approaches to caching requests depending on where they are made.

Client Side

On the client side, you can use the built-in caching mechanism provided by the useStorefront composable. The client-side cache is an in-memory LRU cache that stores the results of API requests based on the query and variables. Caching is disabled by default, you can enable it per request. When making a request, you can specify caching options in the cache property of the request configuration:

~/pages/products.vue
<script setup lang="ts">
const storefront = useStorefront()

const { data } = await storefront.request(`#graphql
  query FetchProducts($first: Int) {
    products(first: $first) {
      nodes {
        ...ProductFields
      }
    }
  }
  ${PRODUCT_FRAGMENT}
`, {
  variables: {
    first: 5,
  },

  // Cache settings for this request
  cache: {
    ttl: 1000 * 60 * 60, // 1 hour
    updateAgeOnGet: true, // Update age when accessed
  },

  // Or true, to use default cache settings from module configuration
  cache: true,

  // Or false, to disable caching for this request (default)
  cache: false,
})
</script>

To set default cache settings for all client-side requests, you can configure the cache property in the module configuration:

~/nuxt.config.ts
export default defineNuxtConfig({
  shopify: {
    clients: {
      storefront: {
        // Default cache settings, can be overridden per request
        cache: {
          ttl: 1000 * 60 * 5, // 5 minutes
          max: 100, // Maximum number of items in cache
          maxSize: 1000 * 1024 * 5, // 5 MB
          // ...
        },

        // Or true, to use default cache settings (default)
        cache: true,

        // Or false, if you don't want to use the client side cache
        cache: false,
      },
    },
  },
})

Server Side

On the server side, you can use Nitro's built-in caching utilities to cache Storefront API requests:

~/server/api/products.ts
export default defineCachedEventHandler(async (event) => {
  const storefront = useStorefront()

  const { data } = await storefront.request(`#graphql
    query FetchProducts($first: Int) {
      products(first: $first) {
        nodes {
          ...ProductFields
        }
      }
    }
    ${PRODUCT_FRAGMENT}
  `, {
    variables: {
      first: 5,
    },
  })

  return data
}, {
  // Cache settings for this handler
  ttl: 1000 * 60 * 60, // 1 hour
})

Caching Admin API Requests

Since the Admin API is only accessible on the server side, you can use Nitro's caching utilities to cache Admin API requests as well:

~/server/api/orders.ts
import { z } from 'zod'

export default defineCachedEventHandler(async (event) => {
  const admin = useAdmin()

  const { id } = getValidatedQuery(event, z.object({
    id: z.string(),
  }).parse)

  const { data } = await admin.request(`#graphql
    query FetchOrder($id: ID!) {
      order(id: $id) {
        id
        name
        totalPrice
        financialStatus
        fulfillmentStatus
      }
    }
  `, {
    variables: {
      id: `gid://shopify/Order/${id}`,
    },
  })

  return data
}, {
  // Cache settings for this handler
  ttl: 1000 * 60 * 60, // 1 hour

  // Use order ID as cache key
  getKey: event => `order-${getQuery(event).id}`,
})
Copyright © 2026