The SEO cluster nobody could see
I spent an evening building a proper SEO cluster for the wedding app. Ten landing pages generated from one template: six use-case pages, four style pages, each with its own title, description, structured data, and a link graph connecting them so search engines could follow the trail. A sitemap tied it together. Tidy work, the kind you finish and feel good about.
The site’s robots.txt said Disallow: /.
Every crawler that arrived was being turned away at the door. The landing pages, the sitemap, the structured data — none of it existed as far as search engines were concerned. The file was a leftover from the private phase, when the app was just our own wedding site and hiding it from Google was the right call. Nobody thought about it again, because nobody looks at robots.txt. It’s two lines. It never changes. That’s exactly why it bit.
The generator is the part worth keeping
The cluster itself is one script, gen-seo.js, that renders all ten pages
from a single template. No build step; I run it by hand when something
changes. Each page gets unique copy and metadata from a config block, and
because every page comes from the same source, they can’t drift apart.
When I want to change the checkout CTA on all ten, that’s one edit.
I like this pattern more than a static site generator for a case this small. There’s nothing to install, nothing to configure, and the whole thing is readable in one sitting.
What goes on the checklist now
The deploy checklist for the wedding app already had the serious-sounding items: test the payment webhook, verify email delivery, check the RLS policies. It now also has: read robots.txt out loud.
The embarrassing failures aren’t the complicated ones. Payments got tested because payments feel dangerous. A two-line text file blocked more traffic than a broken checkout ever could, and it sat there for weeks because it didn’t feel like anything at all.