A generated website looks finished long before it is finished. The layout is clean, the copy reads well, the buttons go where they should. Then you try to ship it, and you find there is no sitemap, no prerendered HTML for the crawler, no Open Graph image, no Content Security Policy, and no story at all for how it gets deployed twice a week without someone remembering nine manual steps.
We build a lot of sites at Senternet, for our own products and for the teams we work with. The pattern held every time. The React components were never what slowed us down. The production infrastructure around them was.
The components are the easy part now
This is the part that took us a while to accept. Generating a well-structured component is close to solved. Generating a site that survives contact with Google, LinkedIn, an iMessage link preview, a Lighthouse audit, and a security review is not solved at all, because none of that work is visible in the thing you are looking at.
The gap is not quality of code. It is the long tail of unglamorous, easily skipped production detail: meta tags and canonical URLs, prerendering so the static paint carries the content, share images at exactly 1200 by 630, a sitemap that regenerates from a single source of truth, robots.txt pointing at it, IndexNow submissions on deploy, cache headers, CSP, mobile polish, analytics that does not block the render, and a deploy pipeline that fails loudly instead of silently.
Every one of those is easy in isolation. The problem is that there are eighteen of them, they are different on every project, and a model that has just written you a beautiful hero section has no particular reason to bring them up.
Big prompts do not fix this
Our first attempt was the obvious one: write a very long prompt describing every standard we hold, and paste it in at the start of a project. It did not work, and it failed in a specific way that is worth naming. The model would seize on one instruction and execute it beautifully, and quietly drop another. Not refuse it. Not flag it. Just not do it.
You cannot review for the absence of something you forgot you asked for. A fifteen-hundred-word prompt has no diff, no test, and no way to tell you which of its clauses were honored. It is a wish, not a specification.
The change came when we stopped treating prompts as conversations and started treating them as infrastructure.
Infrastructure has properties a conversation does not. It lives in a file. It is versioned. It gets reviewed. It can be run again next month and do the same thing. It can be improved once and improve every project that uses it.
What we built instead
We broke the standard into narrow, single-purpose Claude Code skills, each one responsible for exactly one slice of production readiness, each one invocable on its own:
- metatags, for SEO meta, canonical URLs, social cards, and schema markup
- prerender, for static HTML per route and stripping runtime-only markup
- share-images, for per-page Open Graph images generated at build time
- sitemap and robots, generated from one route manifest so they cannot drift
- csp, for a Content Security Policy that is actually enforced
- lighthouse and mobile-optimize, for performance and small-screen polish
- indexnow, for pinging search engines on every production deploy
- firebase, for hosting, custom domains, headers, and the deploy script
Each is small enough to read in a sitting, which means each is small enough to review honestly. And because they compose, we added one more on top: a single orchestrating skill that runs the others in the right order to take a site from nothing to production-ready. One entry point, eight standards, no memory required.
The point is consistency, not speed
It would be easy to sell this as a velocity story. That would be the wrong lesson, and mostly untrue. The honest accounting of what improved:
- Fewer regressions, because the same steps run the same way each time
- Fewer forgotten deploy details, because they live in a file, not a head
- Fewer SEO mistakes, because the sitemap and meta tags derive from one source
- Less decision fatigue, because the settled questions stay settled
None of those are speed. All of them are consistency. When the marginal cost of generating code approaches zero, the scarce resource is not output. It is doing the boring parts correctly, every time, on every project, without relying on anyone to remember. That is an operations problem wearing an engineering costume.
Where it still breaks
We would rather say this plainly than oversell the approach. Working this way does not stop a model from over-refactoring code you did not ask it to touch, inventing an architectural decision and then defending it, regressing a layout while fixing something unrelated, or reaching for an abstraction where a function would do. It still implements instructions partially. Frontend polish still takes a human eye and real judgment, and we still spend that time.
What the skills change is the floor, not the ceiling. They make the failures the interesting kind, the ones worth a person's attention, instead of the tedious kind where a site ships without a canonical tag and nobody notices for a month.
What we take from it
The leverage in AI-assisted development is not in generating more code faster. It is in encoding what you already know to be correct, so it happens by default, on every project, forever. The skills are just the artifact. The discipline they encode is the actual asset, and it is the same discipline that makes an operations function work: write the standard down, run it the same way every time, and improve it in one place.
This site is built with those skills, and so is every product we ship. If you want the longer, more personal version of how this started, our founder wrote it up at mattsenter.com. If you want it applied to your codebase, that is roughly what an MVP engagement looks like on day one.