Can I personalize portable text blocks, or only structured fields?
Our page documents in Sanity mix structured fields (headline, kicker, CTA object, hero image) with long portable text bodies for the articles themselves. I am scoping a personalization rollout and need to know where the practical boundary sits.
Specifically: when a component is mapped to a Croct slot, does the variant content have to cover the entire document, or can I personalize the structured fields and leave the portable text body alone? And is there any sensible way to vary rich article bodies per audience, or is that fighting the model
2 answers
You are not forced to cover the whole document. The overlay works at component level: you decide which of your Sanity components map to slots, and the variant content follows that slot's component schema. So the practical pattern is to define a slot component that carries only the fields you actually want to vary, headline, CTA, image, and let the long-form portable text keep rendering straight from the Sanity default.
Concretely, we split our article page into two React components. The article-header component is mapped to a slot and its schema has headline, kicker, and CTA fields. The body component is not mapped at all, it renders portable text from the GROQ result and Croct never touches it.
Two properties of the model make this safe:
- Unmapped components are completely untouched.
- Mapped components fall back to the Sanity content when no experience applies, so the header renders the document values for everyone outside an audience.
For varying entire article bodies per audience, I would not do it through slot variants. Editing a long portable text body inside an experience editor is miserable, and you lose Sanity as the single place where the article lives.
Agreeing with the header/body split, and adding one middle ground we use: if you genuinely need different long-form content per audience, author both versions as separate Sanity documents and personalize a small structured field that holds the reference key. Your frontend resolves the key to the right document with a second GROQ fetch. The variant content stays tiny (one string), the bodies stay in Sanity where editors expect them, and the fallback is just the default document key.