Boost SEO and Speed: SSR Catalog Pages in Vue Storefront 3
Learn how to turn Vue Storefront’s client‑only category pages into Nuxt‑powered SSR pages, fetch data on the server, cache wisely, and roll out incrementally. A hands‑on example shows the exact code you need to get started.
12 Oct 2025, 20:41 UTC

Why the current client‑only category pages are a problem
In a typical Vue Storefront 3 setup, the product list on a category page is rendered entirely on the client. The initial HTTP response contains almost no product text—just a loading skeleton. Search engines and users with JavaScript disabled see a blank page, and the first paint is delayed until the GraphQL request finishes in the browser. That hurts SEO, perceived performance, and accessibility.
Thesis: Use Nuxt 3’s server‑side rendering to pre‑fetch the first product set
Nuxt 3’s useAsyncData hook can run on the server during the initial request. By fetching the category’s products before the page is sent, we deliver meaningful HTML to crawlers and users alike. The same payload is then reused by the client, eliminating a duplicate request.
Section 1 – Data flow in a Nuxt 3 Vue Storefront 3 page
- Route parameters (e.g.,
/mens-clothing) are parsed by Nuxt and made available asroute.params.slug. - The page’s
script setupcallsuseAsyncDatawith a unique key that includes the slug. - Inside the async function, a GraphQL wrapper (e.g.,
getCategoryProducts) fetches the first page of products. - Nuxt serializes the result into the page payload and injects it into the HTML.
- When the browser loads the page, Vue hydrates the component using the already‑fetched data, skipping a second network round‑trip.
Worked example – a minimal product list page
// pages/category/[slug].vue
Loading…
Error loading products.
Replace getCategoryProducts with your own GraphQL client. The key string ensures Nuxt can cache the result for subsequent requests with the same slug.
Section 2 – Benefits and caveats of SSR for catalog pages
- SEO – Search engines receive product titles, links, and meta tags in the initial HTML.
- Performance perception – Users see a populated list immediately, even if the JavaScript bundle takes longer to load.
- Accessibility – Users with JavaScript disabled still get a functional list.
- Cost – The server must execute the GraphQL query for each request. Caching mitigates load, but you pay for the extra compute.
- Stale data risk – Inventory, prices, and promotions can change between the server fetch and the client’s first interaction. Define a freshness window (e.g., 5 minutes) and revalidate if necessary.
Section 3 – Caching strategy for anonymous catalog responses
Because SSR runs on the server, you can cache the serialized payload per slug and locale. Use a Varnish‑style edge cache or the built‑in useAsyncData staleWhileRevalidate option.
const { data: products } = await useAsyncData(
`category:${route.params.slug}`,
() => getCategoryProducts(route.params.slug),
{
staleWhileRevalidate: 300, // 5 minutes
maxAge: 300
}
)
Never cache user‑specific data such as the cart or promotional codes. Those should be fetched client‑side after hydration.
Section 4 – Rollout checklist
- Identify a pilot route – Pick a high‑traffic category that is safe to experiment with.
- Enable SSR for the route – In
nuxt.config.ts, setssr: true(default) and ensure the page component usesuseAsyncData. - Verify HTML output – Request the page, view source, and confirm product names and links are present before JavaScript loads.
- Check client hydration – Open the Network tab, reload, and ensure the product query does not fire again.
- Monitor latency – Log the server‑side query duration. If it exceeds your target (e.g., 300 ms), consider caching or optimizing the GraphQL resolver.
- Test with JS disabled – Confirm the list still renders.
- Measure SEO impact – Use Google Search Console or a crawler to see if the page index improves.
- Iterate – Once validated, replicate the pattern for other listing pages (search results, brand pages).
Actionable takeaway
SSR catalog pages in Vue Storefront 3 are a straightforward, low‑risk way to improve SEO and perceived performance. Start with a single category, use useAsyncData to pre‑fetch, cache the payload, and validate the output. Once you’re comfortable, roll the pattern out to the rest of your indexable pages. Remember to keep the data fresh and never expose sensitive user state from the server cache.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.