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.

Configuration

In the nuxt.config.ts, you can configure caching options for client side requests and proxied server side requests (if the proxy is enabled) in the cache property of the client configuration:

~/nuxt.config.ts
export default defineNuxtConfig({
  shopify: {
    clients: {
      storefront: {
        cache: {
          // Default cache presets for client and proxy caches
          options: {
            short: { swr: true, maxAge: 1, staleMaxAge: 9 },
            long: { swr: true, maxAge: 3600, staleMaxAge: 82800 },
          },
        },
      },
    },
  },
})

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 and Proxy

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:

The client side cache is not persistent and will be cleared when the page is refreshed.
Proxy caching is persistent and done on the server side.
~/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,
  },

  // Set 'short' cache for client and proxy
  cache: 'short',

  // Or set client and proxy cache separately
  cache: {
    client: 'short',
    proxy: 'long',
  },
})
</script>
Known limitations:
  • Nitro will currently deliver stale requests even if staleMaxAge has been reached: issue.

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