CMS
Connect a Custom Next.js Site to Wix CMS
August 6, 20263 min read
On this page
A headless CMS separates content management from page rendering. Editors work in Wix, while your Next.js app decides how that content looks and where it appears. WebSync uses this pattern for the three feature cards on its homepage. The cards are part of the custom frontend, but their titles, descriptions, and order come from one Wix CMS collection.
What you are connecting
Start with a clear content contract. WebSync has a collection named Features with three fields: title and description are Text fields, and order is a Number field. Each published item must have a unique order of 1, 2, or 3. Anonymous visitors need read permission because the public site fetches these records without asking a visitor to sign in.
This small schema is intentional. The CMS owns content that editors should change. The repository owns layout, icons, spacing, and motion. Keeping that boundary visible prevents the collection from turning into a second design system.
Create the Features collection in the WebSync Headless project.
Add title, description, and order fields with the exact field keys.
Publish three complete items and allow anonymous read access.
Add the public Wix client
Install the Wix SDK and Wix Data package, then create one reusable public client. The OAuth client ID is safe to expose because it identifies the headless project; it is not a secret. Keep it in NEXT_PUBLIC_WIX_CLIENT_ID and make sure the value belongs to the same WebSync project that contains the collection.
import { items } from "@wix/data";
import { createClient, OAuthStrategy } from "@wix/sdk";
export const wix = createClient({
modules: { items },
auth: OAuthStrategy({ clientId: process.env.NEXT_PUBLIC_WIX_CLIENT_ID! }),
});Create the client on the server and reuse it. A module-level singleton is enough for this small site. Do not add an API key to the browser client. Public content reads should use the OAuth strategy, while server-only actions such as form submissions use their own protected credentials.
Query, sort, and validate
Fetch the collection with the current items.query API and sort by order before rendering. Sorting in Wix makes the content order deterministic. Validation then protects the UI from incomplete records, duplicates, and accidental schema changes.
const result = await wix.items
.query("Features")
.ascending("order")
.find();
if (result.items.length !== 3) {
throw new Error("Expected exactly three published features.");
}WebSync goes further by checking every item ID, title, description, and integer order. It also confirms that the orders are exactly 1, 2, and 3. This may feel strict for a practice site, but strict validation gives you a useful failure instead of a half-empty production section.
Render from a Server Component
The homepage remains a Server Component. It awaits the Wix query, passes a small normalized array into the feature grid, and exports hourly revalidation. Visitors receive a static response, while Wix edits can appear without another Git deployment.
export const revalidate = 3600;
export default async function Home() {
const features = await getFeatures();
return <FeatureGrid features={features} />;
}There is no hardcoded fallback. If the first build cannot read three valid records, the deployment should stop. After a successful deployment, Next.js keeps the last valid cached page if a later background refresh fails. That is a better operational contract than silently replacing editor content with stale copy hidden in the codebase.
A practical publishing routine
Edit the three records in the Wix dashboard, publish the changes, and allow up to one hour for the page to become eligible for regeneration. Test schema changes in Preview before Production. When you add a field, update both the Wix collection and the TypeScript validator in the same release.
The main lesson is simple: define ownership first. Wix CMS should own structured editorial content. Next.js should own rendering and behavior. A narrow query, strict normalization, and hourly ISR make that connection easy to understand and easy to operate.