Open a page on the site you just launched and scroll down into the body copy. See that gray box with the little torn-corner icon, sitting where a photo used to be? Somewhere back in 2019, an editor pasted an image URL straight into a rich-text field, pointed it at Sitecore's /-/media/ handler, and never thought about it again. It worked for years. It does not work now, because that handler doesn't exist on the other side, and no field-mapping layer was ever going to catch it. That torn-corner box is what got me writing this. The build went green, the demo looked flawless, and every real failure was hiding one layer down in the rendered output. Four things break with real reliability, none of them throw an error at build time, and every one of them waits politely for real traffic before it shows its face. Here's what breaks, why, and the checks that catch each one before go-live.
1. Media library URLs and asset references
Sitecore serves media through the /-/media/ or /~/media/ handler, often with query-string dimensions like ?w=800&h=600. Optimizely uses a Content Delivery Media model with entirely different URL structure. Every hardcoded image path in rich-text fields, every inline SVG reference, and every PDF link that pointed at the old handler will 404 unless you rewrite it.
The trap: your CMS-managed hero images usually migrate cleanly because they move through the field-mapping layer. The ones that break are buried inside body copy, editors who pasted an image URL directly into a rich-text editor five years ago. There is no field mapping that catches those.
How to catch it: crawl the source site and extract every asset reference from rendered HTML, not just from the content model. Diff that inventory against the assets that actually made it into Optimizely's media tree. Orphaned references, assets linked in content but never migrated, are the single biggest source of post-launch image breakage.
2. Renderings, sublayouts, and the block model gap
Sitecore composes pages from renderings and sublayouts placed into placeholders. Optimizely composes pages from Blocks placed into Content Areas. The concepts rhyme but do not map one-to-one, and this is where content silently disappears.
- Datasource-driven renderings in Sitecore point at a shared item. If two pages reused the same datasource, a naive migration either duplicates the block or drops the reference entirely.
- Nested placeholders (a rendering inside a rendering) rarely translate into Optimizely's flatter content-area model without manual restructuring.
- Rendering parameters, the per-instance settings that control spacing, color, or variant, usually have no home in the new block schema and are lost.
How to catch it: build a rendering-to-block coverage matrix before you migrate a single page. Every Sitecore rendering type needs an explicit Optimizely target or a documented decision to kill it. Any rendering with no mapping is a content area that will render empty.
3. URLs, item paths, and redirect risk
Sitecore URLs frequently derive from the content-tree structure, and many sites relied on Sitecore's display-name logic, wildcards, or link-provider settings to produce clean paths. Optimizely generates URLs from its own routing and the page hierarchy you rebuild. Even when the visible URL looks identical, the underlying resolution is different, and edge cases diverge.
Common breakage patterns:
| Sitecore behavior | What breaks in Optimizely |
|---|---|
| Wildcard items serving dynamic routes | No equivalent; needs custom routing or partial routers |
| Display name differs from item name | URL segment changes, old link 404s |
| Trailing-slash and casing rules | Duplicate URLs or redirect loops if not normalized |
Language embedded in path (/en/) | Optimizely language routing may place it differently |
How to catch it: generate the full source URL set from live crawl data and server logs, not from the sitemap alone. Sitemaps miss the long tail that still earns traffic and links. Then confirm each URL either survives unchanged or has a 301 target. Our Sitecore-to-Optimizely guide walks through building that map, and the migration overview covers the redirect-testing pass in more detail.
4. Languages, versions, and personalization
Sitecore stores every language as a version of the same item; Optimizely uses a master-language model with language branches. If a page had a German version but no French, or a partially translated version, the migration logic has to decide what happens, and the default is often to create empty shells or fall back to the master language silently.
Personalization rules and A/B test variants defined in Sitecore's rules engine do not carry over at all. Treat them as content to re-author in Optimizely, not data to migrate.
How to catch it: inventory language-version completeness per item before migration. Any item where the version count doesn't match your expected locale set needs a human decision, not an automated one.
5. SEO and AEO signals that quietly degrade
Beyond outright 404s, replatforming erodes the signals that keep you in Google's index and in AI answer engines:
- Canonical tags that pointed at Sitecore URLs and now self-reference the wrong path.
- Structured data (JSON-LD) built by Sitecore renderings that no longer emit after the block swap.
- Meta titles and descriptions stored in Sitecore standard-values templates that don't map to Optimizely SEO fields.
- Internal link equity lost when body-copy links point at dead media or old item paths.
AI answer engines are less forgiving than traditional crawlers here: a page with broken structured data and missing canonicals is far less likely to be cited even if it renders fine to a human.
The whole concept map, in one place
The section-by-section walk above is how you brief a team. This is the version you pin above the desk: every Sitecore concept, what it becomes in Optimizely, and the honest answer about what happens to it in transit.
| Sitecore concept | Optimizely equivalent | What actually happens in transit |
|---|---|---|
| Data templates and fields | Content types and properties | Maps cleanly. Mostly mechanical, and the part everyone budgets for. |
| GUID-based internal links | Content references | Must be translated or they die silently — the page still renders, the link goes nowhere. |
Media library (/-/media/) | Media assets | Every path rewritten, including the ones buried inside rich text. |
| Renderings and placeholders | Blocks and content areas | Rebuilt in code, not migrated. Presentation is not a field. |
| Datasource items | Shared blocks | One datasource reused on forty pages becomes forty orphans unless it is consolidated first. |
| Rendering parameters | Block properties | Variants are lost silently — nothing errors, the page just renders the default. |
| xDB / rules-based personalization | Visitor groups | Rebuilt by hand. There is no one-to-one mapping, and the visitor history rarely travels at all. |
| Item path equals URL | Routed content with an editable segment | The path can change without anyone touching the page, and every old URL 404s unless it was mapped. |
| Wildcard items | Custom routing / partial routers | No equivalent. Dynamic routes are re-implemented, not migrated. |
| Aliases and the 301 module | Optimizely URL redirects | Exported and re-imported deliberately, or quietly lost with the old instance. |
| Item versions and languages | Content versions and languages | Maps, but publish state often resets — expect drafts to go live or live pages to vanish. |
| Sitecore Forms | Optimizely Forms | Field types and submit handlers differ, and existing submissions almost never come with you. |
| Solr / Coveo index | Optimizely Search and Navigation | Full reindex. Boosting and synonyms are configuration you rewrite, not data you move. |
A pre-go-live checklist
- Crawl the source site fully; reconcile every asset reference against migrated media.
- Produce a rendering-to-block coverage matrix with zero unmapped renderings.
- Validate the full URL set, including log-derived long tail, against redirects.
- Confirm language-version completeness item by item.
- Spot-check canonicals, JSON-LD, and meta fields on a representative sample of top pages.
- Diff rendered HTML of source vs. staging for your top 200 pages, not just spot pages.
So what do I actually think you should do? Stop trusting the deck that says "done," because the content model coming across clean tells you almost nothing about what the site will render. Every one of these five failures shares the same trick: the data migrates fine, and then the output quietly falls apart where nobody was looking. The only fix I trust is the boring one. Crawl the old site, diff the rendered HTML against staging page by page and asset by asset, and reconcile every reference before you cut over. It is tedious and I will not pretend otherwise. But you get to choose who finds that torn-corner box first: you, on a quiet Tuesday, or Googlebot and a customer, on launch day, and neither of them files a ticket.
