TL;DR
- What we built:
Plovant(https://plovant.com), a multi-tenant CMS that runs our 10+ websites from a single repository and a single dashboard. It combines a block-based CMS, AI generation for pages, images and logos, block-level multilingual translation, unified SSO through our in-house IdP, and a SaaS control plane that manages organizations, permissions and domains. - Why we built it: AWS Amplify hosting is pay-as-you-go and practically free, so we kept adding a separate app per site — until build costs and the number of things to manage grew with every site. At one point a push to main redeployed 7 sites at once.
- The key idea: we dropped the one-app-per-site mapping and consolidated everything into a single app that routes each request to the right site by hostname. Sites keep multiplying; management stays in one place.
Main article (about 13 min read)
Continuing from last time — the answer to "we need something we can fix from a dashboard"
A while ago I wrote We let AI handle our legacy website migration. We migrated old WordPress and plain-HTML sites with AI, started operating them ourselves, and noticed we had built the same contact form four times across four sites. We also learned that for day-to-day operations, a dashboard you can edit from, like WordPress, beats asking an AI every time.
This article is the sequel. The need we saw back then grew into a product. That article was the migration experience; this one is the product it produced.
Websites multiply. Should the machinery multiply with them?
Company websites multiply before you notice. A corporate site, a landing page per product, a recruiting page, campaign pages. We ended up with more than 10.
At first we did the straightforward thing and served each site as its own app. Our delivery platform is AWS Amplify. Amplify doesn't rent you a server around the clock — it bills for what you use, and for a small site the hosting cost is close to zero. So at the time we figured "it's free, we can pile on as many sites as we like," and added one more Amplify app every time a site appeared.
That premise collapses. Hosting may be practically free, but builds are billed. Amplify charges by build time, so the more apps you have, the more builds you run and the more you pay. On top of that, every new site adds a domain configuration, another set of environment variables to manage, another line on the invoice. Each site has its own separate console, too. At one point, a push to the main branch redeployed 7 sites at once. A one-line fix triggered 7 builds and 7 sites' worth of build-time charges. "It's free, pile them on" stopped holding up against the reality of build costs and management overhead.
The dominant cost of running websites turns out not to be the cost of serving pages, but the cost of maintaining per-site machinery. Unless you fix that, you become a company where every proposal to add a site needs a budget discussion.
We also considered "just run 10 WordPress instances." That satisfies the edit-from-a-dashboard requirement. But 10 WordPress installs mean 10 admin panels, 10 rounds of updates, and 10 places to patch for security. I've seen neglected WordPress installs become the attack entry point at consulting clients more than once. WordPress multisite exists, but once you add our requirements — unify authentication on our own SSO platform, connect to our own billing and notification platforms — we judged that customizing an off-the-shelf product would cost more than building our own. Note that this judgment only holds because, as described later, we already had those in-house platforms to connect to. With different premises, the conclusion will differ.
The shift — don't split apps; route by hostname
So we cut the site-to-app mapping. Rather than abandoning Amplify for some other delivery mechanism, this was our answer to "how do we achieve it on the same Amplify?" We consolidated every site into a single Amplify app that looks at the requested hostname (which domain the visitor came through) and decides which site's content to serve.
- One delivery surface: there is exactly one Amplify app. To add a site, you create it in the dashboard and assign a domain. No new delivery app.
- One dashboard: every page of every site is edited from the same admin console (web-admin).
- Costs drop through consolidation: a push now triggers a single build, and the per-site build costs and management overhead fold into one. Consolidating 7 apps into 1 was a design decision that put cost reduction first.
The migration did not go without incident. While moving domains from the old apps to the new platform, we did briefly take one site down. We also fought a "zombie" state where supposedly deleted legacy delivery configurations kept lingering. We used the opportunity to permanently delete 5 unused sites. Consolidation is moving house while everything keeps running — I'll be honest that it doesn't end with zero accidents.
Editing happens in blocks
Plovant's unit of editing is the block. A text block, an image block, a contact-form block. A page is a sequence of blocks, and the dashboard lets you reorder, swap and publish them.
The block components live in a shared package used across multiple products — the same consolidation this series keeps coming back to: we don't build a separate block editor per repository. Commonly used sections (intro, features, pricing, FAQ and so on) ship as 9 finished premium blocks, and templates are implemented as "presets of block combinations." Because templates ride on the existing block mechanism instead of being a separate system, a page created from a template can still be fixed block by block afterwards.
Putting AI on top — pages, images and logos, all inside the dashboard
On top of that, we added AI.
- AI page generation: describe what you want, and the AI infers the page type (landing page? informational page?), picks a structure and assembles the blocks. It's content-first: instead of a human pre-deciding the layout, the content determines the structure.
- AI image and logo generation: generate the images for a landing page right in the dashboard. Logos are generated as vectors, which stay crisp at any size.
- Block-level translation: pages are localized block by block, not as a whole. When you fix one sentence, you re-translate only the changed block. We rolled multilingual support out gradually while growing the automated test suite from 303 to 331 tests.
We spent three days fighting timeouts in AI image generation — the fix, pushing heavy generation into background jobs, reuses a lesson learned in promptflow. Never make the same mistake twice across products — that's the lifeline when one person runs many products.
How it's actually used — a new landing page now ships in a day
Consolidation, blocks and AI changed daily operations like this.
Example 1: launching a product landing page. It used to be weeks of work after the decision — set up a repository, commission or reuse a design, implement, configure delivery… Now we create the site in the dashboard, hand the product description to AI page generation for a first-draft sequence of blocks, swap the copy and images, and hit publish — all within the same day. Domain assignment and DNS setup happen automatically when the site is created.
Example 2: fixing copy. An everyday fix like "correct the pricing wording" is just opening the block and editing it. No more locating the repository, editing code and waiting for a build. And since there's no build to wait for, a fix no longer redeploys 7 sites as a side effect.
Example 3: maintaining multilingual pages. Fix one block on the Japanese page, re-translate just that block. Since you never re-translate the whole page, translations elsewhere stop drifting every time you touch something.
When we say internally that "we stopped outsourcing landing pages," it isn't only that payments to design agencies disappeared. The biggest felt change is that the request–wait–review round trip that used to accompany every fix is gone.
The reality of "AI builds your landing page" — dividing generation and editing
Marketing that says "AI will build your landing page" is everywhere. Here is the reality after operating it on all of our own sites.
Where AI generation shines is the first draft. Facing a blank canvas and inventing a structure is heavy work for a human. Handing over a product description and getting a plausible block sequence in minutes removes the psychological barrier to starting. We chose the content-first approach (AI picks the page type from the content) because it produced more usable first drafts than a human pre-committing to "I'm building a landing page" ever did.
Meanwhile, finishing remains human work. Exact pricing, legal wording, brand voice. Delegate those to AI and you publish text that sounds right but isn't. So Plovant's design is fixed on this division of labor: AI generates, a human fixes things block by block, and a human presses the publish button. Fully automatic publishing is deliberately not built.
Images are the same. Generated images are fine for setting a landing page's mood, but a product's actual screens must be screenshots or you're lying. We mix generated and real, and a human chooses which to use. AI multiplies the options; humans choose — the same philosophy as every other product we run.
Vector logo generation turned out to be more useful than expected. Raster logos (the kind that degrade when scaled) are useless for print and large displays, so a designer commission used to be mandatory. Generating directly in vector form (crisp at any scale) removed the wait for logo delivery when standing up a new site.
Turning site operations into SaaS — the control plane and unified SSO
Plovant started as the platform for our own sites, and is now on its way to being offered externally (as SaaS). What we built for that is the management core — the control plane.
- Organizations, teams, permissions (RBAC): who can edit which site is managed through an organization → team → member structure.
- Unified SSO: login is delegated to our in-house IdP (ELN ID), standardized on OAuth 2.0 + PKCE. Plovant itself has no login form. It's a live example of the "consumers don't build login forms" principle from this series' article on our auth platform.
-
API keys and a subdomain ledger: issuing keys for machine integrations, and allocating subdomains under
*.sites.plovant.com, are both ledger-managed. - Bring-your-own domains: customers can use their own domains (apex domains included) — verified with a real proof of concept. The full story, zone-setup traps included, is in another article.
"CMS" sounds like it's about the editing screen, but to lease the system to multiple organizations, the real substance is outside the editor: who is allowed what, and who owns which domain.
Behind the development — two months of preparation, one month of implementation
Plovant's development history has a distinctive shape. After the first commit in February, April had 2 commits and May had 5. It looks almost stalled. What was actually happening was preparation of the development process itself: at the end of May we introduced our standard toolchain (automated quality checks and a spec-first development process) and cleared out every existing type error.
Then in June, implementation surged: 2,633 recorded observations and 125 commits. The day we finalized the SaaS multi-tenancy requirements, we wrote 4 architecture decision records and 3 design docs in one sitting, and implemented organizations, permissions, sites, API keys and the subdomain ledger. The 7-apps-to-1-hub consolidation decision also happened that month. Two months of preparation, one month of implementation — not planned, but it became a clean demonstration that putting the mold in first makes implementation fast.
The core of the block CMS lives in shared packages (block definitions, editor, delivery) whose source of truth is a separate repository; Plovant is a consumer. It's exactly the provider/consumer split described in our shared-platform article — when we moved the landing-page feature into the shared package, the change touched 60 files and deleted 15 files of duplicated consumer-side implementation.
Prehistory — the pivot from an SEO platform
Plovant wasn't actually born as a CMS. It started as an SEO (search engine optimization) platform, later split the SEO features off into a separate product (aio-helper), and pivoted to being a CMS platform. The rule was "when two products start cohabiting in one repository, split them" — and that separation is what let Plovant focus on being a proper CMS.
And as I wrote at the top, the decisive input was the ELNW-017 experience. The migration revealed we had "built the same thing four times," and operations convinced us a dashboard-editable system was necessary. The seed of the product came not from a grand vision but from operational pain.
If you were to do this at your company — where consolidation starts to pay
Plenty of companies share this problem (sites multiply, management scatters), so here are the decision points from our experience.
With 1–2 sites, you don't need consolidation. WordPress or static sites, individually owned, are simpler. The consolidation machinery itself has an upfront cost.
Past 3 sites and still growing, consolidation is worth considering. Three tests: ① Are sites starting to duplicate the same features (contact forms, analytics, multilingual support)? ② Do per-site delivery costs, certificates and domain configurations exist only in someone's head? ③ Does the engineering side wince at every "can we add a site?" proposal? If all three apply, consolidation will pay off.
Build your own, or use an off-the-shelf multi-site CMS? As a general rule, start with off-the-shelf. We built our own because we already had in-house auth, billing and notification platforms and planned to connect to them. As this series has repeatedly shown, when the platforms already exist, the cost of "building the glue" drops. Conversely, building just a CMS from scratch with no platforms behind it is not something I recommend.
The scariest part of migration is DNS. We briefly took one site down during domain migration and watched supposedly deleted legacy delivery configurations live on. Write the rollback procedure for every site before you switch it, and switch one site at a time, not all at once. Those two rules avoid most of the accidents.
Where it stands, and what's next
Plovant is the operations platform actually carrying our 10+ sites, and simultaneously a product being turned into SaaS. The domain architecture now cleanly separates the delivery plane from the management plane, bring-your-own domains are verified, and the rebrand to the Plovant name is complete.
External availability as SaaS is still in preparation. We're polishing the mold hardened by internal use — consolidation, blocks, AI generation, multilingual — into a form other companies can use as-is. Dogfooding first to crush the operational weak points, then offering it outside: the same order as every other product introduced in this series.
Lessons you can reuse
- Mapping sites one-to-one to apps makes costs and management grow with every site. Consolidating into a single app that routes by hostname is worth considering once you pass 3 sites.
- Even when hosting is pay-as-you-go and practically free, builds and management multiply with the number of apps. "It's free, pile them on" does not hold. Instead of switching platforms, consider consolidating the structure on the same platform.
- Structural waste like "one push redeploys 7 sites" should be fixed structurally the moment you notice it. Keep dodging it operationally and the cost becomes permanent. But consolidation migrations do have accidents — prepare the failure scenarios and rollback procedures before you move.
- Standardizing the editing unit on blocks means AI generation, translation and templates all become "create or swap a block," which keeps new features simple.
- The substance of a SaaS you lease to multiple organizations is not the editing screen but the permissions, authentication and domain management around it. Don't own authentication yourself; delegate to an IdP.
- Product seeds come from operational pain. The discovery that "we had built the same thing four times" is where this product began.







Top comments (0)