Qwik CMS: Self-Host a Headless Content Backend
Qwik's whole pitch is resumability — ship almost no JavaScript, hydrate nothing up front, load code only when the user needs it. So it's a little ironic that most "Qwik CMS" advice ends at a hosted SaaS box that meters your content and hides its editor. Qwik is about owning your performance. Your CMS can be about owning your content.
What is a Qwik CMS?
A Qwik CMS is any headless CMS that serves content to a Qwik (or Qwik City) app over an API. Qwik renders the page and resumes on the client; the CMS stores your posts and pages and returns JSON. Since Qwik has no coupled backend, you want a headless CMS — and Qwik City's routeLoader$ is the natural place to fetch it, server-side, before the page ships.
The distinction worth knowing: headless doesn't mean hosted. A headless CMS can run on your own server, keeping content in your own database. That decides whether you own your content or rent access to it.
The usual Qwik CMS picks and their tradeoffs
The common suggestions are Storyblok, Contentful, and Strapi. They work with Qwik. The hosted ones share the same friction:
- Your content lives on their servers. Export is possible, rarely pleasant, and the API is theirs to price and change.
- Metered or per-seat pricing. Content-heavy sites pay as they grow.
- A closed editor. You get their dashboard, not one you can fork or restyle.
None of that matters for a weekend build. For a site you'll maintain for years, or content you're required to keep on your own infrastructure, it matters.
The self-hosted alternative
UnfoldCMS is a self-hosted headless CMS on Laravel 12. You run it, content lives in your own MySQL database, and it exposes a REST API at /api/v1/*. Your Qwik app reads it with plain fetch() inside routeLoader$ — no SDK, no account, no per-request meter.
Honest limits up front:
- REST only — no GraphQL. Set on GraphQL? Storyblok or a GraphQL layer over Strapi fits better.
- No official Qwik package — you call the JSON API directly, which in a
routeLoader$is a few lines. - Self-hosted — you run the server. That's the point, and it's real work.
Connecting Qwik to a self-hosted CMS
Qwik City's routeLoader$ fetches on the server, so the content is in the HTML before any JS resumes — exactly what you want for a fast, SEO-friendly page:
// src/routes/blog/index.tsx
import { component$ } from "@builder.io/qwik";
import { routeLoader$ } from "@builder.io/qwik-city";
interface Post {
id: number;
title: string;
slug: string;
short_description: string;
}
export const usePosts = routeLoader$(async () => {
const res = await fetch("https://your-cms.example.com/api/v1/posts");
const json = await res.json();
return json.data as Post[]; // Respond::success — data under .data
});
export default component$(() => {
const posts = usePosts();
return (
<section>
{posts.value.map((post) => (
<article key={post.id}>
<a href={`/blog/${post.slug}`}>{post.title}</a>
<p>{post.short_description}</p>
</article>
))}
</section>
);
});
Because the fetch runs in routeLoader$ on the server, no client JavaScript is needed just to show the list — which is the entire reason you picked Qwik. A single-post route is the same shape with routeLoader$ reading /api/v1/posts/${slug}.
Rebuild on publish
Deploying Qwik as static output? You don't want manual redeploys on every edit. UnfoldCMS ships HMAC-SHA256-signed outgoing webhooks that fire on content events — point one at your deploy hook and a publish triggers a rebuild. Managed from /api/v1/admin/webhooks.
Qwik CMS options compared
| CMS | Hosting | API | Your data? | Pricing |
|---|---|---|---|---|
| UnfoldCMS | Self-hosted | REST | Yes — your DB | One-time license |
| Storyblok | SaaS | REST + GraphQL | Their servers | Per-seat + usage |
| Contentful | SaaS | REST + GraphQL | Their servers | Per-seat + usage |
| Strapi | Self-host / Cloud | REST + GraphQL | Self-host: yes | OSS / metered cloud |
Need GraphQL? Storyblok or self-hosted Strapi. Want to own your data and cap cost while keeping Qwik's server-fetch model? UnfoldCMS or self-hosted Strapi.
FAQ
Can I use a headless CMS with Qwik?
Yes. Any headless CMS with a REST or GraphQL API works with Qwik. Fetch content in a routeLoader$ (server-side) or with fetch in a component, and render it. Qwik is backend-agnostic — the CMS choice is about hosting, pricing, and ownership.
Where should I fetch CMS content in a Qwik app?
Use Qwik City's routeLoader$. It runs on the server before the page ships, so content is in the initial HTML — good for performance and SEO, and it keeps API keys off the client. Client-side fetch is fine for content that loads after interaction.
What's the best self-hosted CMS for Qwik?
If you want content in your own database and no per-request pricing, a self-hosted headless CMS like UnfoldCMS fits, read in a routeLoader$. Self-hosted Strapi is the other main option and adds GraphQL on a Node stack.
Does UnfoldCMS have a Qwik SDK?
No — by design. You call the /api/v1/* REST API directly. In a routeLoader$, that's a plain fetch and a typed return, which is cleaner than pulling in an SDK.
The bottom line
Qwik is built so you ship less and own your performance. Pairing it with a CMS you don't control gives that ownership back to a vendor. A self-hosted headless CMS keeps your content in your database and one routeLoader$ away. See the live demo or the headless CMS guide.
Related: SolidJS CMS: Self-Host a Headless Backend · Angular CMS: Self-Host Your Content · What Is a Headless CMS?
Free & Open Source
Own your CMS. No subscriptions.
Unfold CMS is free to download and self-host. Built on Laravel + React, full source code included.
Share this post: