How to Set Up a Jamstack Site with a Headless CMS Backend

The Jamstack architecture (JavaScript, APIs, Markup) combines a pre-built static frontend with a decoupled content API — giving you a fast, secure static site while still allowing non-technical content editors to manage content through a CMS interface.

The Jamstack Architecture

Headless CMS (content storage/editing) → Build process (fetches content, generates static HTML) → Static hosting (Nginx)

Choosing a Headless CMS

OptionNotes
Strapi (self-hosted)Full control, runs on your own VPS
WordPress (headless mode)Familiar editing UI, exposed via its REST/GraphQL API
Directus (self-hosted)Wraps an existing database with a CMS-style admin UI and API

Step 1 — Deploy a Self-Hosted Headless CMS (Strapi Example)

npx create-strapi-app@latest my-cms --quickstart

Deploy following the same Node.js deployment pattern as How to Deploy a Node.js Application with PM2 and Nginx.

Step 2 — Configure the CMS API

In Strapi's admin panel, define content types (e.g. "Blog Post" with title, body, image fields) and set API permissions for public read access to published content.

Step 3 — Fetch Content at Build Time

In your static site generator (Astro, Next.js static export, Hugo with a data pipeline):

// Astro example
const response = await fetch('https://cms.yourdomain.com/api/blog-posts');
const posts = await response.json();

Step 4 — Build the Static Site

npm run build

This generates static HTML pages incorporating the fetched content at build time — no runtime API calls needed when visitors actually load the site.

Step 5 — Deploy the Static Output

See How to Host a Static Website on a VPS with Nginx for the deployment itself.

Triggering a Rebuild When Content Changes

Since the site is static, new content published in the CMS doesn't appear until the next build. Set up a webhook from your CMS to trigger a rebuild-and-deploy automatically:

// Strapi webhook configuration points to your CI/CD trigger endpoint
// which runs: npm run build && rsync deployment

See How to Deploy Automatically on Git Push for the underlying webhook-triggered deployment pattern, adapted here to trigger on CMS content publish events rather than Git pushes.

Handling Preview Content Before Publishing

For editors to preview unpublished changes, either run a separate "preview" build pulling draft content, or use your framework's built-in preview mode feature if available — consult your specific static site generator's documentation.

Securing the CMS Admin

The CMS backend itself should follow standard application security practices — HTTPS, strong authentication, and ideally IP restriction on the admin panel:

location /admin {
    allow YOUR_TRUSTED_IP;
    deny all;
}

Why This Architecture Is Attractive

  • The public-facing site is static — extremely fast, minimal attack surface
  • Content editors get a familiar CMS editing experience
  • The CMS backend, if compromised, doesn't directly expose the live site (since it's pre-built, not rendering content dynamically per visitor)

Common Errors

Content changes don't appear on the live site — expected behavior until a rebuild runs; verify the webhook-triggered rebuild is correctly configured.

Build fails due to CMS API being unreachable — verify network connectivity between the build environment and the CMS API, and that API permissions allow the necessary read access.

Continue Reading

Browse more articles in Static Site Hosting & Frontend Deployment.

  • jamstack, headless cms, static site cms, strapi
  • 0 Utenti hanno trovato utile questa risposta
Hai trovato utile questa risposta?

Articoli Correlati

How to Host a Static Website on a VPS with Nginx

Static websites — plain HTML, CSS, and JavaScript with no server-side processing —...

How to Deploy a Next.js Application on a VPS

Next.js supports several deployment modes — fully static export, server-side rendering with...

How to Deploy a Static Site Built with Astro, Hugo, or Jekyll

Static site generators (Astro, Hugo, Jekyll) produce plain HTML/CSS/JS at build time —...

How to Optimize Images for Web Performance

Images are typically the largest contributor to page weight and load time. This guide covers...

How to Configure Nginx for Single Page Applications (SPA Routing)

Single Page Applications (React, Vue, Angular) handle routing client-side in JavaScript —...