Back to blog

Blog

Build a Headless Blog with Wix Blog

August 6, 20263 min read

On this page

Wix Blog can act as the editorial backend for a fully custom Next.js publication. Editors get drafts, authors, categories, tags, media, and rich content in Wix. The public WebSync site gets complete control over the blog hub, article cards, metadata, and reading layout.


Install Blog and define the contract


Install Wix Blog on the same WebSync Headless project that already contains CMS and Forms. Create an author, one broad category, and focused topic tags. For this launch, the author is WebSync Team, the category is Wix Headless, and each post carries one topic tag: CMS, Forms, or Blog.


The frontend validates a compact summary for lists and a richer detail object for post pages. Every published summary needs an ID, title, slug, excerpt, publication date, read time, cover image with alt text, and exactly one supported topic tag. Detail pages also require SEO data, Ricos content, and H2 or H3 headings.


  • BlogPostSummary powers homepage and hub cards.

  • BlogPostDetail adds SEO, rich content, and table-of-contents headings.

  • BlogPageResult adds the offset and hasMore state for pagination.


Read posts through the public client


Add the Blog posts and tags modules to the same public OAuth client used by CMS. List requests should ask only for summary fields and sort by firstPublishedDate descending. The post route then fetches one slug with the RICH_CONTENT and SEO fieldsets.


const result = await wix.posts.listPosts({
  sort: "PUBLISHED_DATE_DESC",
  paging: { offset, limit },
});

Resolve tag IDs into labels once per request and normalize Wix media identifiers with the SDK media helper. Preserve the returned width and height so next/image can reserve space before the cover arrives.


const result = await wix.posts.getPostBySlug(slug, {
  fieldsets: ["RICH_CONTENT", "SEO"],
});

if (!result.post) return null;

Keep list and detail queries separate


Homepage cards do not need the article body. Fetching rich content for every card increases response size and makes validation harder to reason about. WebSync therefore uses one summary path for lists and one detail path for the article route.


The homepage requests the newest three posts. The blog hub requests one featured post plus six cards. An accessible Load more button calls a small GET endpoint with an offset and a maximum limit of six. The client appends only IDs it has not already rendered, prevents concurrent requests, announces loading and errors, and disappears at the end.


const response = await fetch(
  `/api/blog?offset=${nextOffset}&limit=6`,
);
const page = await response.json();
setPosts(current => [...current, ...unique(page.posts, current)]);

Render Ricos in one client boundary


The page, query, metadata, and layout remain Server Components. Only the official RicosViewer wrapper is a Client Component because the viewer needs browser behavior. Enable the plugins the content contract needs: images, links, dividers, and code blocks. Headings, paragraphs, and lists render through the core viewer.


Extract H2 and H3 text on the server. Use each top-level Ricos node index to create a deterministic anchor, then assign that ID after the viewer renders. Desktop readers get a sticky contents rail. Mobile readers get a compact On this page disclosure above the article.


Treat metadata as content


Generate each route's title and description from Wix SEO tags, with the post title and excerpt as safe fallbacks. Add a canonical URL, Open Graph article data, and Article JSON-LD. The sitemap should list every valid published slug and use the post's publication date as lastModified.


Unknown slugs return a real 404. Invalid published content throws instead of rendering a damaged page. The launch build also requires at least three complete published posts, so deployment cannot quietly ship an empty gallery.



Draft first, publish deliberately


Wix supports two equal editorial paths. A person can write and edit in the Wix Blog dashboard, or an AI assistant can create structured Ricos drafts through the Wix connector. Both paths end in the same dashboard review. AI-created posts should remain drafts by default, and publishing should always be an explicit decision.


Hourly ISR keeps the first version simple. After an editor publishes, the cached site becomes eligible to refresh within an hour. If a background refresh fails, Next.js retains the last successful page. Signed on-demand revalidation is a good future improvement when faster updates matter, but it is not required to learn the headless Blog connection.


What this setup proves


CMS, Forms, and Blog now share one Wix backend while the custom Next.js frontend owns the public experience. Each product uses a different data flow, but the same operating rules apply: keep secrets on the server, validate external data, preserve accessibility, and make publishing steps visible.