Why Your JavaScript Ecommerce Store Isn't Ranking (And How to Fix It)
React, Vue, and Next.js stores have unique SEO failure modes that traditional stores don't. Here's the JavaScript-specific SEO audit for headless and SPA ecommerce.
Ecommerce is moving to JavaScript-heavy architectures — Next.js, Remix, Hydrogen, Shopify Hydrogen, custom React on top of Shopify Storefront API. These stacks are faster, more flexible, and more developer-friendly than traditional Liquid templates. They also introduce SEO failure modes that don't exist on classic Shopify or WooCommerce, and most JavaScript ecommerce stores we audit have at least one of them.
Issue 1: Client-Side Rendered Product Data
Your product page's HTML might contain a beautiful loading skeleton. The actual product details — price, description, availability — render only after a JavaScript bundle loads and makes an API call.
Googlebot renders JavaScript, but with delays (up to 7 days in some cases) and with a much stricter resource budget than a real browser. If your product data depends on a slow or conditional API call, Google may index an empty loading state as your product page.
Fix: Server-side render (SSR) product data. In Next.js 16, use generateStaticParams or generateMetadata to ensure product info is in the initial HTML response.
How to verify
- Run
curl -A "Googlebot" https://yourstore.com/products/example - Search the response for your product title, price, and description
- If they're not in the raw HTML, Google might not see them
Issue 2: Meta Tags Applied by JavaScript
On SPAs, the meta tags (title, description, Open Graph) are often set via React Helmet or similar libraries. Googlebot can execute JavaScript, but your title tag showing up in the Final Rendered DOM isn't the same as it being in the initial HTML.
Social media crawlers (Facebook, Twitter, LinkedIn) do not execute JavaScript. If your Open Graph tags are client-side rendered, your links share with generic previews instead of product-specific ones.
Fix: Server-render all meta tags. In Next.js 16, use the metadata export or generateMetadata function, not next/head in client components.
Issue 3: Hash-Based Routing
Any URL with a hash (/products#/example) is treated as the same page as /products by Google. The content after the hash doesn't get its own indexation.
This is a classic early-React issue. If you're still on hash routing in 2026, the fix is: migrate to proper URL-based routing (React Router, Next.js App Router, etc.). Hash routing is not a viable SEO strategy.
Issue 4: Infinite Scroll Without Pagination
An infinite-scroll category page can display 500 products, but Googlebot might only see the first 20 (whatever's in the initial HTML). The rest, loaded via scroll-triggered API calls, may never be discovered.
Fix: Implement paginated URLs alongside infinite scroll. Use the History API to update the URL as users scroll (/category?page=2, /category?page=3), and make those pages directly accessible and crawlable.
Issue 5: Link Elements Using onClick Instead of href
JavaScript frameworks make it tempting to use <div onClick={navigate}> instead of <a href="..."> because it's easier to intercept for client-side routing. This breaks SEO entirely — Google doesn't follow JavaScript navigation the way it follows real links.
Fix: All navigation must use real <a> tags with real href attributes. In React, use Link components from Next.js or React Router — they render real anchors.
Issue 6: Slow Largest Contentful Paint
JavaScript ecommerce sites tend to have poor Core Web Vitals scores out of the box. LCP (Largest Contentful Paint) is the most common failure: hero images and product images don't paint until hydration completes.
Fix:
- Use
<Image priority>for LCP candidates in Next.js - Preload critical images in HTML
- Don't lazy-load above-the-fold images
- Serve modern formats (WebP, AVIF) via
next/image
Issue 7: Lighthouse Scores Lying to You
Lighthouse measures your store from a fast connection with a warm browser cache. Real mobile users on 4G don't get that experience. A Lighthouse LCP of 1.8s translates to a real-user LCP of 3-5s on mobile.
Always check field data (Chrome User Experience Report, or your analytics) in addition to Lighthouse lab data. The difference is often dramatic.
Issue 8: Structured Data in Client Components
Product JSON-LD needs to be in the initial HTML, not injected by a client component after hydration. Google parses structured data aggressively but with time limits.
Fix: Put JSON-LD in the server component tree, directly in the <script type="application/ld+json"> tag on the server.
Issue 9: Third-Party Script Overload
Headless commerce stores tend to accumulate more third-party scripts than traditional stores because the front end is decoupled from the platform. Each script gets added independently.
Audit: open your store in Chrome DevTools → Network → Filter: "3rd party". Count the scripts. Anything over 15 is hurting performance. Kill the ones you're not actively using.
The Headless Commerce SEO Checklist
If you run a headless or JavaScript-heavy ecommerce store, audit quarterly:
- All meta tags in initial HTML (not client-rendered)
- Product title, price, description in initial HTML
- JSON-LD in initial HTML
- All navigation uses real
<a href>elements - Paginated URLs for infinite scroll
- LCP image preloaded and priority-rendered
- Third-party script count under 15
- Real-user Core Web Vitals acceptable (not just Lighthouse)
- No hash routing
A StoreVitals scan runs the full technical audit including JavaScript-specific checks: DOM size, render-blocking scripts, inline styles, and structured data presence. For headless stores, running it weekly catches regressions that sneak in with each deploy.