Sitecore to Optimizely: Feature Gaps That Bite at Go-Live

Someone on the migration call reads the totals out loud with genuine relief: every item exported, every page created, the two numbers matching down to the last digit. The room exhales. I never can, because I have watched that exact number lie to a whole team. A Sitecore-to-Optimizely migration almost never falls over at the URL level first; redirect mapping, done properly, handles that. What falls over is everything Sitecore was quietly doing offstage and Optimizely stages differently: personalization rules, datasource-driven renderings, media library references, multisite context resolution, language fallback. None of it rides along in a content export. Think of it as shipping the full script of a play but leaving the set, the lighting cues, and the stage directions behind. Every line is intact and nobody knows where to stand. These seams tear open when a real editor or a real visitor hits an edge case, usually the morning after cutover. So go looking for them on purpose first. A matching page count is not a promise.

Why a clean content export still ships a broken site

Sitecore stores content as items in a tree, with presentation details (which renderings show, bound to which datasource items) layered on top through the Layout Service or the presentation details field. Optimizely (CMS 12 / SaaS) uses a block-and-page content model with content areas. The two do not translate one-to-one. A row that migrates perfectly as text can still render as an empty page because the component that displayed it, and the binding between component and data, never came across.

Teams that count "12,400 items exported, 12,400 pages created" and call it done are measuring the wrong thing. Parity of records is not parity of rendered output.

The features that break most often

Sitecore feature | Optimizely equivalent | What silently breaks
Rendering + datasource binding | Blocks in content areas | Content migrates but appears on no page; components lose their data source
Personalization rules (xDB/rules engine) | Optimizely visitor groups / experimentation | Rules don't port; default variant ships to everyone, quietly killing conversion tests
Media Library item references | Assets / media in the content repository | Image and file GUID references break; body copy links 404 or resolve to nothing
Multisite via site definition + hostname | Site definitions / start pages | Wrong site context resolves; shared content shows on the wrong brand
Language versions + fallback | Language settings + fallback config | Untranslated pages 404 instead of falling back; hreflang drifts
Sitecore Forms | Optimizely Forms | Form definitions and submit endpoints don't map; leads silently drop
Wildcard / dynamic items | Partial routing / custom routers | Catalog or dynamic URLs stop resolving; large orphan clusters appear

1. Datasource orphans

Every Sitecore rendering points to a datasource item. When you migrate the items but rebuild presentation manually in Optimizely, some datasources never get bound to a block. The content exists in the repository but appears on zero pages, a textbook orphan. Crawl the new site and reconcile rendered content against the export; anything present in the source and absent from any rendered page is your break list.

2. Personalization silently reverting to default

Sitecore's rules engine ("if visitor is in segment X, show variant Y") does not export as content. It lives in presentation and xConnect data. Migrations almost always ship the default variant to everyone and lose the conditional logic. Nothing 404s, so QA passes, but your personalized homepage is now static. Inventory every page carrying personalization before cutover and rebuild each rule explicitly in visitor groups.

3. Media references that resolve in Sitecore's syntax only

Sitecore stores media links as -/media/{GUID}.ashx or as internal dynamic links inside rich-text fields. Optimizely uses a different asset path scheme. Unless you rewrite those inline references during transform, images and PDFs embedded in body copy break even when the asset itself migrated fine. This is one of the highest-volume, lowest-visibility failures because it hides inside field content, not in the page URL.

A pre-go-live checklist that actually catches these

Rendered-output diff, not record count. Crawl staging Optimizely and the live Sitecore site; compare rendered text and asset presence per URL.

Datasource reconciliation. List every source item and confirm it appears on at least one target page, or is a deliberate kill.

Personalization inventory. Enumerate pages with active rules; verify each visitor group and variant post-migration.

Inline media reference scan. Grep rich-text fields for -/media/ and old-domain asset paths; confirm each resolves on the target.

Multisite context test. Hit each hostname and confirm the correct start page and shared-content scoping.

Language fallback test. Request an untranslated URL and confirm fallback behaves, not 404s.

Form submission end-to-end. Submit every form and confirm the payload lands where marketing expects.

Where redirects fit in

URL changes still matter. Sitecore's item paths and Optimizely's routing rarely produce identical slugs, and wildcard/dynamic items can generate thousands of URLs that need explicit rules. But treat redirects as one workstream among several, not the whole migration. A perfect 301 map that lands users on a page with broken images and no personalization is still a failed cutover.

Catch the seams before real traffic does

So here's what I actually think: that matching count is the most dangerous number in the whole project, because it feels like an answer and it's really just a receipt. Sitecore said most of what it meant through presentation, personalization, and dynamic routing, and none of that behavior survives an export. It's the staging, not the words on the page. So treat those behaviors as real things you inventory and test one at a time against the target, and refuse to call it done until rendered output matches, not record counts. That's the pre-migration crawl and scoring we map for Sitecore-to-Optimizely moves: it flags orphaned datasources, broken media references, and redirect risk while they're still cheap to fix, before they turn into production incidents with your name on the ticket. Start from a page-by-page migrate / rewrite / kill plan, and the next time those totals match on the call, you'll actually get to exhale along with everyone else.