Building a CMS with Astro
How we built a database-backed CMS on Astro: prerendered pages for speed, a block-based admin, and rebuild-on-publish.
We wanted content that loads instantly without giving up a real editing experience. Astro made that trade-off disappear. Here is how the CMS behind this site is put together.
Static by default
Astro renders to HTML and ships no JavaScript unless a component asks for it. For a content site that means fast pages and strong Core Web Vitals with no tuning. The interactive bits — the comment form, the theme toggle — are islands that hydrate on their own, leaving the rest of the page as plain HTML.
Content in Postgres, not Markdown
Most Astro setups keep content in Markdown files. We put it in PostgreSQL instead and read from the database at build time. Editors never open a file or a git client.
That split keeps things clean:
- The admin is a server-rendered area behind authentication, with a block-based editor for posts, pages, and services.
- The public site is prerendered from whatever lives in the database when the build runs.
Publishing is a rebuild
Static pages only change when the site rebuilds, so the admin's Publish button triggers a webhook that rebuilds the image and restarts the container. The build re-runs the prerender against the current database and the new content goes live — no developer, no deploy.
// Each stored section is matched to a registered block component.
const block = registry[section.type];
const html = block ? block.render(section.content) : '';
What we learned
Reach for boring, well-supported pieces — Astro, Postgres, a plain Node server — and spend the creativity on the product instead of the plumbing. A CMS that is easy to operate beats a clever one every time.
Related Articles
Type-safe Postgres queries
Hand-written SQL kept type-safe end to end — catching a renamed column in your editor instead of in production, no ORM required.
Securing your web app
The security baseline every web app needs: authentication, sessions, input handling, and the boring habits that prevent breaches.