Why is hreflang missing from a Next.js site when it is actually there?
I was reviewing search visibility for a bilingual site, and searched the built page:
rg -o 'hreflang="[^"]*"' index.html
Nothing.
I concluded on the spot that the alternate links were missing. On a two-language site that is a real problem: search engines lose the signal that the two pages are versions of one another, and might treat them as duplicate content.
I nearly wrote the report. Then I checked a second way.
What I found
rg -o 'rel="alternate"[^>]*' index.html
rel="alternate" hrefLang="en" href="https://example.com/"
rel="alternate" hrefLang="ar" href="https://example.com/ar/"
rel="alternate" hrefLang="x-default" href="https://example.com/"
All three links were there, intact. Written hrefLang, with a capital L.
Why
React property names are camelCase (hrefLang, className, tabIndex), and a static HTML export can carry them into the output exactly as they appear in the source. Browsers read them fine, since HTML attribute names are case-insensitive, and search engines cope just as well. grep compares characters exactly as written.
The real lesson
An empty search result is not evidence of absence. It is evidence that the pattern failed to match.
This one nearly became a false report about a gap that did not exist. The owner would have spent time fixing something that already worked, and could easily have broken it in the process.
How to actually verify
Grep answers questions about the bytes in a file. For questions about the document, ask the browser:
[...document.querySelectorAll('link[rel="alternate"]')]
.map(l => [l.hreflang, l.href])
Attribute names get normalised during parsing, so this query reports what the document actually contains, whatever the casing in the markup.
A rule I have followed since that day
Before reporting that anything is missing, I look for it in at least two different ways. When the results disagree, the first thing I debug is my own pattern.
Related reading
Tell me what you want to build. Your first 15 minutes of consulting are free.
Book a consultation