Munchable scans a food label and tells you whether the product suits the gut conditions you manage. Its public side is 516 URLs: a landing page, eight condition guides at munchable.app/conditions, 38 recipes, a reference list, four fixed pages and 461 generated pages that each answer one ingredient question.
I have written tests for most of what makes those pages correct. What I had not done is ask production. So I took the sitemap as the list of URLs the site claims to publish, fetched every one of them, and recorded six things per page: status code, response time, transfer size, the canonical URL, the number of h1 elements, the length of the meta description, and whether the word noindex appears anywhere in the HTML.
What came back clean
URLs fetched 516 HTTP 200 516 exactly one h1 516 pages with a meta description 516 pages carrying a noindex 0 served from the edge cache (HIT) 515 median transfer 40 KB (26 KB to 151 KB, 20.6 MB total) median response 313 ms (118 ms to 801 ms) Nothing has rotted. No generated slug has fallen out of the build while staying in the sitemap, which is the specific failure a derived site invites and the one I most expected to find. The single cache miss is the homepage, which is the one page rendered per request because it localises the advertised price, so that is the architecture rather than a surprise.
The heaviest page is munchable.app/answers at 151 KB, because its job is to link all 461 question pages from one place, and the lightest is munchable.app/licenses at 26 KB, which is a few short paragraphs plus the shared chrome. A site whose pages are mostly text has a floor somewhere around 26 KB, and that floor is the header, the footer and the framework payload rather than anything I wrote.
Then there are the two findings.
One: the homepage is a condition behind
The app covered seven conditions until coeliac disease went in. That change was 63 files, and most of what made it survivable was that counts are derived from the registry rather than typed. Fourteen files still needed the word "seven" replaced with "eight" by hand.
I grepped all 516 downloaded pages for the word. Exactly one still says it:
curl -s https://munchable.app/ | grep -o '<meta name="description" content="[^"]*"' # ... with the reasons behind it. Seven gut conditions, one scan. It is in the homepage's meta description. Not in its h1, not in its body, not in the FAQ underneath it, all of which were updated. The source is a string in a metadata object:
export const metadata: Metadata = { ...pageMetadata({ title: 'Munchable | Trust your gut again', description: 'Scan a barcode. Get a clear Good fit, Caution, or Avoid answer for your gut, with the reasons behind it. Seven gut conditions, one scan.', path: '/', }), Three things have to be true at once for a string to survive like that, and all three are ordinary.
It is not on the page. Every sweep I do, including reading the rendered site, is a sweep of what a visitor sees. A meta description is read by a crawler and shown in a search result, so a stale one is wrong in the one place that matters for a stranger's first impression and invisible in every place I look.
It is checked, but for the wrong property. This string goes through a test on every run. That test measures its length against the 160 characters a search result can show, and it passes, because 136 characters of wrong is still 136 characters. A test that checks the shape of a string says nothing about its truth.
And it is a number. Deriving it is what the rest of the site does: the recipe pages say "all eight conditions" from a count of the registry, so 19 pages updated themselves when the eighth arrived. The homepage description predates that habit and never got it.
So the fix is not to change the word. It is to interpolate the count the way everything else does, and the reason that is worth the extra line is that this exact string is the thing a stranger reads before they decide whether to click.
Two: two of our generators spell the homepage differently
Each page's canonical came back matching the URL the sitemap publishes. Except one:
sitemap: https://munchable.app/ canonical: https://munchable.app og:url: https://munchable.app 515 of 516 agree exactly. The homepage differs by one character.
Both forms resolve to the same page, and a trailing slash on the root is the one case search engines treat as equivalent, so the practical impact is nil. What I like about it is that my own code says it cannot happen. The comment at the top of the file that builds all of these reads:
// Every canonical URL, sitemap entry and Open Graph tag resolves through here, // so the origin cannot drift between them And it is true. They do all resolve through one helper, which produces https://munchable.app/ for the root. The divergence happens after that: the sitemap writes its strings out verbatim, and the metadata goes through the framework, which normalises a canonical by the site's trailing-slash setting and drops the slash. One generator respects my string, the other respects its own rules, and the only path where those two disagree is the one path that is nothing but a slash.
That is a good reminder about this class of invariant. "They come from one function" is a claim about my code. "They are identical on the wire" is a claim about the output, and only one of those can be checked by fetching the page. Of the two, the sitemap is the one that should move: a URL that a crawler will normalise anyway is better published in the normalised form.
The incidental finding: the hand-written pages sit closest to the cut
The description budget is 160 characters. Across all 516 pages:
shortest 83 median 118 longest 157 The longest four are munchable.app/terms and three recipe pages, all at 157 characters, three characters from the cut. Every one of the 461 generated pages is at 148 or below.
Which is the opposite of what I would have guessed before measuring. The generated descriptions are assembled from a template, so their length is bounded by the longest ingredient name and they are all comfortably inside the budget. The tightest pages are the ones a human wrote, where the temptation is to fit one more clause, and the only thing standing between that clause and a truncated snippet is a test asserting a number.
If you want to poke at any of this, the list of URLs is public at munchable.app/sitemap.xml, and curl plus grep -o is the whole toolchain I used.
