Introduction
Headless EC — separating a backend like Shopify from a frontend you build yourself in Next.js — is appealing for its design freedom. But a while after launch, search traffic often fails to grow the way you expected, or drops below where it used to be.
The cause is clear. All the SEO-related output that an off-the-shelf EC theme used to produce automatically stops the moment you build your own frontend. This article walks through how, on an EC site selling motorcycle gear, I rebuilt those features by hand. The individual implementations live in three sub-articles; here I'll cover the big picture of what stops working and which points bring it back.
What Stops the Moment You Build Your Own Frontend
What the Theme Was Quietly Doing
With an off-the-shelf theme, things like a proper h1 (the heading that names what a page is about), server-rendered product descriptions, breadcrumbs, and sitemap.xml generation all happen on the theme side. You never set them up, so you don't notice when they disappear either. Do nothing, and your site looks thin to search engines.
On Screen, but Not Reaching Search Engines
When you write React components in Next.js, it's tempting to render everything in the browser. But if product names and descriptions are drawn only by JavaScript, the first HTML the server returns is just a skeleton. Crawlers (the programs search engines use to read pages) sometimes move on to the next page without waiting for JavaScript to run. The result is content that's on screen yet effectively doesn't exist to search engines.
Content is empty until JS runs. Product info is hard to convey to crawlers
Headings, descriptions, and internal links are in the initial HTML and reliably conveyed
Same screen either way — what changes is whether the first HTML to arrive has anything in it.
The Three Pillars I Rebuilt
1. Putting Content in the HTML with SSR
The first thing I tackled was reliably outputting what I want crawlers to see using server-side rendering (SSR, where the server assembles the HTML before returning it). The h1, the product description, and internal links to related products all go into the initial HTML. Category pages got a lead paragraph and a block of internal links, securing both crawl paths and content volume.
2. Adding Meaning with Structured Data
The second pillar declares, in a machine-readable form, that "this is a price" or "this is stock status" for the content you output. Product information and breadcrumbs are declared in a format called JSON-LD, so prices and site hierarchy can appear in search results.
h1, descriptions, internal links
Product & breadcrumb JSON-LD
Dynamic generation + caching
SEO you don't lose even when headless
The finished state is all three pillars in place, with consistent URL formatting underneath them.
3. Tidying the Entry Points with Sitemaps and URL Normalization
The third pillar is a sitemap.xml and robots.txt that automatically follow products and categories as they come and go. Managing tens of thousands of SKUs by hand isn't realistic, so I automated generation, cached the results, and added a way to monitor the URL count. Alongside that, mixed-case URLs and unnecessary tracking parameters get 301-redirected right at the site's entry point, so evaluation isn't split across duplicate URLs.
Design the Screen and the Search Engine View Separately
What all of this shares is a mindset: design what you show users and what you deliver to crawlers as separate things. But only the format is separate — the substance has to match. Declaring a price you don't display, or hiding text that differs from what's on screen, gets a page treated as untrustworthy by search engines.
The Effect Shows Up as an Accumulation
Add one h1, add one type of declared data, set up one redirect. Each looks small on its own, but once SSR, structured data, sitemaps, and URL normalization are all in place, how readable your site is to a search engine rises across the board.
Conclusion
SEO for headless EC is the work of rebuilding, one piece at a time, what the theme used to do automatically. The points to cover: put real content in the initial HTML, add machine-readable meaning to that content, keep your entry points automatically up to date — and always keep the screen and the declared data in agreement.
The concrete implementations are explored in the three articles below.
Supplementing Crawler-Visible Content with SSR
How to server-render headings, descriptions, and internal links that client rendering alone can't convey.
Implementing JSON-LD Structured Data (Products & Breadcrumbs)
Schema design for products and breadcrumbs that leads to rich results.
Generating and Caching Dynamic Sitemaps and robots.txt
Sitemap generation that follows products as they change, plus URL normalization.