20-minute walkthrough with 2–3 personalized examples on your real pages.
Email, chat, or 24/7 phone support included on every paid plan.
Headless and composable stacks split the content (an API-first CMS) from the front end that renders it. That’s great for flexibility — one content source feeding a website, an app, and the edge — but it complicates personalization, which used to rely on a single page and a script tag swapping elements in the browser.
In a headless setup, personalization has to become a decision layer: something that decides who sees what for a given slot, and hands that decision to whatever front end is doing the rendering. Here’s a practical architecture for headless CMS personalization with Personyze — the building blocks, two ways to integrate, and the questions to settle before you build.
A traditional CMS renders the page and a personalization script rewrites the DOM after load. Headless breaks that model: the CMS is just a content API, and your front end — Next.js, Nuxt, a mobile app, an edge function — fetches content and renders it. There is no single page to inject into.
So personalization splits into three jobs: define audiences (who), decide the content or variant for this visitor and slot (what), and render it wherever your front end lives. Personyze handles the first two and hands the decision to your stack — on the server or in the browser.
Audiences define who. The easiest path is to embed the Personyze Audience Builder in an iframe inside your own UI: editors define rules using your customer and account fields, and Personyze returns a compiled audience id/definition. You get a full rules engine without rebuilding audience UI or logic yourself. Audiences can combine on-site behavior, CRM data, and first-party signals.
Placements mark where personalized content goes. Each is a placement_id — you can create a universal placement or one scoped strictly to a given page or URL.
placement_id
Decisions tie it together: given a visitor_id and the placement_ids on a page, Personyze resolves the visitor’s audience and returns the content_id and variant to show. The same decision flow powers A/B tests, so testing is not a separate system.
visitor_id
content_id
There’s no single “right” integration — it comes down mostly to whether you render on the server or in the browser.
Your CMS/back end stores the content_id, the placement_id (universal or page-scoped), and the audience id/definition. On each request, your server reports the visitor_id plus the placement_ids on the page to Personyze; Personyze returns the content_id and variant (the same flow as A/B tests); and your app renders the content.
Benefits: no coupling to content type, more control over content management, and a workflow that stays simple even when an update requires content edits. It fits server rendering, SSR, and edge cleanly.
The trade-off: server-to-server means you send Personyze the visitor context it needs to decide — the current page and URL, the referrer, the user agent, and the behavior events that build the visitor’s profile. The client-side option collects all of that automatically from a single Personyze tag (70+ attributes out of the box); server-to-server trades that convenience for control, keeping decisions on your backend. It’s the right call for many teams — just budget for the extra integration work.
Your front end sends the actual content payload to Personyze, and Personyze places it on the page in the browser. Use this when you want client-only rendering or rapid UI experiments without server hooks.
Because it runs through the Personyze tag, it also captures the visitor context for you — page, referrer, device, and on-site behavior — so there’s far less to wire up than the server-to-server path.
Because the decision flow is “visitor_id + placement_id → variant,” the same wiring runs A/B and multivariate tests. Test content variants per placement and audience, and let Personyze close out losers and roll traffic to winners — no separate testing integration.
Both work, and Personyze supports both a server-side REST API and a client-side JSON API. Server-side (during page generation, SSR, or at the edge) decides before render, so there’s no flicker and it works for SEO, apps, and email. Client-side decides in the browser, which is faster to iterate for SPA experiments. Many teams mix the two.
The same decision layer does more than swap static blocks. Dynamic content — a hero, banner, message, or CTA — can be personalized by audience, with your own custom fields (name, industry, location, account type) inserted as personalization tags right into the content or the recommendation set.
For recommendations, Personyze returns JSON for both product and content recommendations. You pick the algorithm and map the fields you want, and Personyze returns a personalized JSON set per visitor. Your front end reads it from a JavaScript variable and renders it in your own layout — cards, carousels, widgets — which is ideal for SPAs, mobile apps, and custom front ends. Prefer not to build the display? Managed, responsive widgets are available too.
And it fits either render path from above: client-side, using the client-side JSON API read in the browser or app; or server-side, calling Personyze’s API from your backend with the visitor’s id — even their CRM id or email — to get their recommendations back. There’s a full REST API and native iOS/Android SDKs, and the same multilingual logic applies, so content and recs arrive in the visitor’s language.
Build: Define a “Manufacturing accounts” audience in the Audience Builder using your CRM and firmographic fields. Create a placement — home-hero — and store two hero variants in your CMS. On each homepage request, your server sends the visitor_id, home-hero, and the visitor context (page, referrer, and the company from your own data) to Personyze, gets back a content_id, and renders that hero server-side.
home-hero
End result: a classic B2B personalization play — a visitor from a manufacturing account lands on a hero and CTA written for manufacturing — server-rendered, no flicker — while everyone else sees the default. Point the same placement at two variants and you’ve got an A/B test.
Build: Set up a Content Recommendations JSON action with a “readers also read” or “most read by interest” algorithm, map the fields you want (title, image, URL), and assign the result to a JavaScript variable. On your article page, read that variable and render your own card layout — no server changes.
End result: every reader sees a personalized rail in your own design — the heart of publisher & media personalization. New or anonymous readers get trending and popular picks; once an interest is known it shifts to interest-based recommendations — all client-side, and in the visitor’s language.
A short discovery checklist gets a headless integration scoped quickly:
The decision layer is CMS-agnostic: it operates on content_ids and placement_ids, not on a specific product. That means it slots in alongside API-first platforms like Contentful, Sanity, Strapi, Contentstack, or ButterCMS — and it can pull unified profiles from a CDP such as Segment or an integration you already run.
It’s personalizing content that a headless (API-first) CMS delivers to a decoupled front end. Instead of a script rewriting a rendered page, a decision layer decides which content or variant each visitor should see for a given slot, and your front end renders it – on the server or in the browser.
Largely, yes. With the server-to-server pattern, your back end stores content_id, placement_id, and audience, then reports visitor_id + placement_ids and renders whatever Personyze returns. There’s no coupling to content type, so most of the work is wiring events and a decision call.
Server-side (SSR or edge) decides before render, avoids flicker, and works for SEO, apps, and email. Client-side is quicker to iterate for SPA experiments. Personyze supports both a server-side REST API and a client-side JSON API, and many teams mix them.
You can embed the Personyze Audience Builder in an iframe inside your own UI so editors define rules with your customer and account fields, and Personyze returns a compiled audience definition – or build audiences directly in Personyze. Either way you avoid rebuilding audience logic.
Yes. The same decision flow – visitor_id + placement_id returning a variant – runs A/B and multivariate tests, with automatic winner selection. Testing isn’t a separate integration.
Any API-first CMS. The decision layer works on content_ids and placement_ids rather than a specific product, so it fits Contentful, Sanity, Strapi, Contentstack, ButterCMS, and others, and can combine with a CDP like Segment.
Personalize your headless stack without rebuilding it. Book a demo to scope an integration, or view plans.
30 minutes with a personalization expert. Bring your stack, your goals, your skepticism. We'll show you what changes when every visit feels like the only one.