Web Part Mapping Reference (Supplementary)
Companion reference for the migration pipeline skills. It contains the authoritative mapping tables, CIM schema details, and zone-aware rules used during extraction (Phase 1) and transformation (Phase 2).
For programmatic suggestions with confidence scores, always call get_webpart_mapping_hints first. Use the tables below when AI judgment or exact property details are still needed.
CIM Schema Specification
{
"schemaVersion": "1.0",
"extractedAt": "<ISO 8601 timestamp>",
"source": { "siteUrl": "", "pageUrl": "", "pageName": "", "pageType": "wiki|webpart|publishing", "title": "" },
"metadata": { "author": {}, "created": "", "modified": "", "modifiedBy": "", "contentTypeId": "", "uniqueId": "" },
"publishingLayout": { ... },
"content": {
"title": "",
"publishingFields": { ... },
"webParts": [ ... ],
"wikiZones": [ ... ]
},
"transformationHints": { ... }
}
Publishing fields format
Each field in content.publishingFields has a type discriminator:
| Field Type |
Properties |
Transform Action |
image |
html, imageUrl, altText |
build_text_webpart(html) without sourceUrl (cross-site) |
richHtml |
html, plainText |
build_text_webpart(html, sourceUrl) |
text |
value |
build_text_webpart(<p>{value}</p>) |
dateTime |
value, isoDate |
build_text_webpart(<p>{value}</p>) |
Web part modernMapping
Each entry in content.webParts should include a modernMapping object:
{
"id": "...",
"typeName": "Microsoft.SharePoint.WebPartPages.XsltListViewWebPart",
"title": "Pages",
"listId": "...",
"listUrl": "/sites/pub1/Pages",
"modernMapping": {
"modernType": "List",
"webPartId": "f92bf067-bc19-489e-a556-7fe95f508720",
"builderTool": "build_any_webpart",
"properties": { "selectedListId": "...", "listTitle": "Pages", "selectedListUrl": "..." },
"crossSiteNote": "For cross-site migration, resolve the destination site's equivalent library and update properties accordingly."
}
}
Property validation at transform time is mandatory:
- call
get_modern_webpart_catalog() to get the real property schema
- keep only schema-valid properties
- populate every required property, using
resolve_list_info for destination-site list/view GUIDs as needed
- use the catalog
dataVersion example (typically "1.0") instead of guessing
Zone-Aware Processing
Classic wiki and publishing pages can embed web parts inline with <div class="ms-rte-wpbox"> markers. extract_classic_page splits these into wikiZones.
Extract phase (Phase 1)
When building the CIM:
- consult
get_webpart_mapping_hints for each web part
- populate
modernMapping on content.webParts
- add a
transformationHints.note that names the concrete strategy, not “render as placeholder”
Transform phase (Phase 2)
When processing wikiZones:
- HTML zone (
webPartIds empty): build_text_webpart(zone.html, sourceUrl)
- Web-part zone (
webPartIds non-empty): match by position index, then:
- if
resolvedHtml exists, use build_text_webpart or classify it into a richer web part such as Quick Links or Image
- if
modernMapping exists, validate it against the catalog schema, then use modernMapping.builderTool with modernMapping.webPartId and only schema-valid properties; for cross-site list web parts, call resolve_list_info to resolve destination-site equivalents
- only if neither exists and the type is truly unknown, create a yellow-highlighted text fallback naming the classic type and the recommended modern alternative
Never silently skip embedded web parts.
For every explanatory fallback, wrap the entire notice in <span class="ms-rtebackcolor-3">...</span>. build_text_webpart converts this to SharePoint's native yellow highlightColorYellow. Do not highlight ordinary migrated content.
Classic-to-Modern Type Mapping
| Classic Web Part |
Primary Modern Equivalent |
Builder Tool |
Fallback |
Notes |
| ContentEditorWebPart |
Varies by content |
See CEWP Classification below |
build_text_webpart |
AI adds the most value here |
| ImageWebPart |
Image |
build_image_webpart |
— |
Direct 1:1 mapping |
| XsltListViewWebPart |
List |
build_any_webpart |
build_text_webpart (link to list) |
May need beta API |
| ListViewWebPart |
List |
build_any_webpart |
build_text_webpart (link to list) |
Same as XsltListView |
| PageViewerWebPart |
DocumentEmbed or Embed |
build_any_webpart / build_embed_webpart |
— |
DocumentEmbed for docs, Embed for URLs |
| ScriptEditorWebPart |
Embed (no scripts) or Text (with scripts) |
build_embed_webpart / build_text_webpart |
— |
Scripts cannot run in modern pages |
| SummaryLinkWebPart |
Quick Links |
build_quick_links_webpart |
— |
Natural mapping |
| ContentByQueryWebPart |
Highlighted Content |
build_any_webpart |
build_text_webpart |
Complex queries may need manual config |
| TitleBarWebPart |
Text |
build_text_webpart |
— |
Simple heading/caption |
| Unknown types |
Text + Any |
build_text_webpart / build_any_webpart |
— |
Analyze content directly |
CEWP Content Classification
| Pattern |
Signals |
Action |
| Navigation / Link Lists |
<ul> or <ol> where most <li> contain <a> tags |
build_quick_links_webpart; see Quick Links Layout Guide |
| Embedded Content |
<iframe>, <embed>, <object> tags |
build_embed_webpart with the src URL; YouTube auto-routes to the YouTube web part |
| Image Galleries / Hero Images |
Multiple <img> tags, or a single large image with overlay text |
Single image → build_image_webpart; multiple images → consider build_any_webpart with Image Gallery; image with text overlay → consider Hero via build_any_webpart |
| Data Tables |
<table> with <thead> and <tbody> |
build_text_webpart |
| Styled Banners / Announcements |
Large text, colored backgrounds, CTA buttons |
Consider Hero or Call to Action via build_any_webpart, or build_text_webpart |
| JavaScript-Dependent Content |
<script>, onclick, jQuery references, SP.js calls |
build_text_webpart with the full explanatory note wrapped in <span class="ms-rtebackcolor-3">...</span> |
CTA buttons: Prefer styled <a> tags inside a text web part. The Button and CallToAction web parts are unreliable (inconsistent rendering, style loss, occasional silent drops on save), so a styled anchor inside build_text_webpart is the most predictable reproduction.
Quick Links Layout Guide
| Layout |
Use When |
CompactCard |
Compact navigation tiles |
List |
Detailed lists with descriptions |
Button |
Call-to-action buttons |
FilmStrip |
Horizontal scrollable links with thumbnails |
Grid |
Icon grid navigation |
Waffle |
Dense icon grid |
Important caveat: layoutId is persisted to the page JSON, but SPFx currently renders CompactCard regardless. Plan the visual design around CompactCard. If you need a true Button / FilmStrip / Grid look, fall back to a text web part with hand-built HTML.
JavaScript Alternatives
| Classic Pattern |
Modern Alternative |
| jQuery KPI dashboards |
Power BI embed |
| SP REST API data fetchers |
List web part or SPFx |
| Custom form handlers |
Power Apps embed |
| Custom script web parts |
SPFx web parts |
PnP Selector Functions
| Function |
Used By |
Returns |
ListSelectorListLibrary({ListId},{XmlDefinition/ListViewXml}) |
XsltListViewWP, ListViewWP |
List, Library, Calendar, Issue, TaskList, DiscussionBoard, Survey, Undefined |
ContentEmbedSelectorContentLink({ContentLink},{Content},{FileContents},{UseCommunityScriptEditor}) |
ContentEditorWP |
Link, NonASPXLinkNoScript, NonASPXLink, ContentNoScript, Content, NonASPXUseCSE, ContentUseCSE |
ScriptEditorSelector({UseCommunityScriptEditor}) |
ScriptEditorWP, SimpleFormWP |
UseCommunityScriptEditor, NoScriptEditor |
ContentEmbedSelectorSourceType({SourceType}) |
PageViewerWP |
WebPage, ServerFolderOrFile |
ContentByQuerySelector({ListGuid},{ListName}) |
ContentByQueryWP |
Default, NoTransformation |
SummaryLinkSelector({SummaryLinksToQuickLinks}) |
SummaryLinkWP |
UseText, UseQuickLinks |
UserExistsSelector({PersonEmail}) |
ContactFieldControl |
ValidUser, InvalidUser |
Community Script Editor (CSE)
ControlId: 3a328f0a-99c4-4b28-95ab-fe0847f657a3
| Web Part |
CSE Branch |
Content Source |
| ScriptEditorWebPart |
UseCommunityScriptEditor |
Inline {Script} |
| ContentEditorWebPart |
NonASPXUseCommunityScriptEditor |
Linked file {FileContentsEncoded} |
| ContentEditorWebPart |
ContentUseCommunityScriptEditor |
Inline {Script} |
| SimpleFormWebPart |
UseCommunityScriptEditor |
Form {Script} |
To enable: Deploy PnP react-script-editor to the tenant app catalog, then set pti.MappingProperties["UseCommunityScriptEditor"] = "true". Without this, all script-dependent web parts are dropped.
BaseWebPart Fallback
If a web part type has no specific PnP mapping, the BaseWebPart default is ***Web part {Title} was not transformed***. This is distinct from:
- empty mappings — silently dropped (for example, TitleBar / GettingStarted)
- error text — specific error text (for example, XmlWebPart / DataForm)
- unmapped — properties catalogued but no mapping node, so the web part falls to BaseWebPart (for example, RSSAggregator)
Reference Files
| File |
Contents |
When to Read |
reference/pnp-transformations.md |
Per-webpart PnP details: selectors, branch tables, properties, migration %, corrections |
Need exact PnP branch logic, property names, or migration specifics |
Source data: PnP webpartmapping.xml v1.0.2111.0.
1---2name: webpart-mapping-reference3description: Supplementary reference for PnP selector functions, Community Script Editor, Quick Links layouts, and JavaScript alternatives. Read on-demand for deeper migration details.4---56# Web Part Mapping Reference (Supplementary)78Companion reference for the migration pipeline skills. It contains the authoritative mapping tables, CIM schema details, and zone-aware rules used during extraction (Phase 1) and transformation (Phase 2).910**For programmatic suggestions with confidence scores, always call `get_webpart_mapping_hints` first.** Use the tables below when AI judgment or exact property details are still needed.1112---1314## CIM Schema Specification1516```json17{18 "schemaVersion": "1.0",19 "extractedAt": "<ISO 8601 timestamp>",20 "source": { "siteUrl": "", "pageUrl": "", "pageName": "", "pageType": "wiki|webpart|publishing", "title": "" },21 "metadata": { "author": {}, "created": "", "modified": "", "modifiedBy": "", "contentTypeId": "", "uniqueId": "" },22 "publishingLayout": { ... },23 "content": {24 "title": "",25 "publishingFields": { ... },26 "webParts": [ ... ],27 "wikiZones": [ ... ]28 },29 "transformationHints": { ... }30}31```3233### Publishing fields format3435Each field in `content.publishingFields` has a `type` discriminator:3637| Field Type | Properties | Transform Action |38|------------|------------|------------------|39| `image` | `html`, `imageUrl`, `altText` | `build_text_webpart(html)` without sourceUrl (cross-site) |40| `richHtml` | `html`, `plainText` | `build_text_webpart(html, sourceUrl)` |41| `text` | `value` | `build_text_webpart(<p>{value}</p>)` |42| `dateTime` | `value`, `isoDate` | `build_text_webpart(<p>{value}</p>)` |4344### Web part `modernMapping`4546Each entry in `content.webParts` should include a `modernMapping` object:4748```json49{50 "id": "...",51 "typeName": "Microsoft.SharePoint.WebPartPages.XsltListViewWebPart",52 "title": "Pages",53 "listId": "...",54 "listUrl": "/sites/pub1/Pages",55 "modernMapping": {56 "modernType": "List",57 "webPartId": "f92bf067-bc19-489e-a556-7fe95f508720",58 "builderTool": "build_any_webpart",59 "properties": { "selectedListId": "...", "listTitle": "Pages", "selectedListUrl": "..." },60 "crossSiteNote": "For cross-site migration, resolve the destination site's equivalent library and update properties accordingly."61 }62}63```6465**Property validation at transform time is mandatory:**661. call `get_modern_webpart_catalog()` to get the real property schema672. keep only schema-valid properties683. populate every **required** property, using `resolve_list_info` for destination-site list/view GUIDs as needed694. use the catalog `dataVersion` example (typically `"1.0"`) instead of guessing7071---7273## Zone-Aware Processing7475Classic wiki and publishing pages can embed web parts inline with `<div class="ms-rte-wpbox">` markers. `extract_classic_page` splits these into `wikiZones`.7677### Extract phase (Phase 1)7879When building the CIM:801. consult `get_webpart_mapping_hints` for each web part812. populate `modernMapping` on `content.webParts`823. add a `transformationHints.note` that names the concrete strategy, not “render as placeholder”8384### Transform phase (Phase 2)8586When processing `wikiZones`:87- **HTML zone** (`webPartIds` empty): `build_text_webpart(zone.html, sourceUrl)`88- **Web-part zone** (`webPartIds` non-empty): match by **position index**, then:89 1. if `resolvedHtml` exists, use `build_text_webpart` or classify it into a richer web part such as Quick Links or Image90 2. if `modernMapping` exists, validate it against the catalog schema, then use `modernMapping.builderTool` with `modernMapping.webPartId` and only schema-valid properties; for cross-site list web parts, call `resolve_list_info` to resolve destination-site equivalents91 3. only if neither exists and the type is truly unknown, create a yellow-highlighted text fallback naming the classic type and the recommended modern alternative9293Never silently skip embedded web parts.9495For every explanatory fallback, wrap the entire notice in `<span class="ms-rtebackcolor-3">...</span>`. `build_text_webpart` converts this to SharePoint's native yellow `highlightColorYellow`. Do not highlight ordinary migrated content.9697---9899## Classic-to-Modern Type Mapping100101| Classic Web Part | Primary Modern Equivalent | Builder Tool | Fallback | Notes |102|---|---|---|---|---|103| ContentEditorWebPart | *Varies by content* | See CEWP Classification below | `build_text_webpart` | AI adds the most value here |104| ImageWebPart | Image | `build_image_webpart` | — | Direct 1:1 mapping |105| XsltListViewWebPart | List | `build_any_webpart` | `build_text_webpart` (link to list) | May need beta API |106| ListViewWebPart | List | `build_any_webpart` | `build_text_webpart` (link to list) | Same as XsltListView |107| PageViewerWebPart | DocumentEmbed or Embed | `build_any_webpart` / `build_embed_webpart` | — | DocumentEmbed for docs, Embed for URLs |108| ScriptEditorWebPart | Embed (no scripts) or Text (with scripts) | `build_embed_webpart` / `build_text_webpart` | — | Scripts cannot run in modern pages |109| SummaryLinkWebPart | Quick Links | `build_quick_links_webpart` | — | Natural mapping |110| ContentByQueryWebPart | Highlighted Content | `build_any_webpart` | `build_text_webpart` | Complex queries may need manual config |111| TitleBarWebPart | Text | `build_text_webpart` | — | Simple heading/caption |112| Unknown types | Text + Any | `build_text_webpart` / `build_any_webpart` | — | Analyze content directly |113114---115116## CEWP Content Classification117118| Pattern | Signals | Action |119|---|---|---|120| Navigation / Link Lists | `<ul>` or `<ol>` where most `<li>` contain `<a>` tags | `build_quick_links_webpart`; see [Quick Links Layout Guide](#quick-links-layout-guide) |121| Embedded Content | `<iframe>`, `<embed>`, `<object>` tags | `build_embed_webpart` with the `src` URL; YouTube auto-routes to the YouTube web part |122| Image Galleries / Hero Images | Multiple `<img>` tags, or a single large image with overlay text | Single image → `build_image_webpart`; multiple images → consider `build_any_webpart` with Image Gallery; image with text overlay → consider Hero via `build_any_webpart` |123| Data Tables | `<table>` with `<thead>` and `<tbody>` | `build_text_webpart` |124| Styled Banners / Announcements | Large text, colored backgrounds, CTA buttons | Consider Hero or Call to Action via `build_any_webpart`, or `build_text_webpart` |125| JavaScript-Dependent Content | `<script>`, `onclick`, jQuery references, `SP.js` calls | `build_text_webpart` with the full explanatory note wrapped in `<span class="ms-rtebackcolor-3">...</span>` |126127**CTA buttons:** Prefer styled `<a>` tags inside a text web part. The Button and CallToAction web parts are unreliable (inconsistent rendering, style loss, occasional silent drops on save), so a styled anchor inside `build_text_webpart` is the most predictable reproduction.128129### Quick Links Layout Guide130131| Layout | Use When |132|---|---|133| `CompactCard` | Compact navigation tiles |134| `List` | Detailed lists with descriptions |135| `Button` | Call-to-action buttons |136| `FilmStrip` | Horizontal scrollable links with thumbnails |137| `Grid` | Icon grid navigation |138| `Waffle` | Dense icon grid |139140**Important caveat:** `layoutId` is persisted to the page JSON, but SPFx currently renders **CompactCard regardless**. Plan the visual design around CompactCard. If you need a true Button / FilmStrip / Grid look, fall back to a text web part with hand-built HTML.141142### JavaScript Alternatives143144| Classic Pattern | Modern Alternative |145|---|---|146| jQuery KPI dashboards | Power BI embed |147| SP REST API data fetchers | List web part or SPFx |148| Custom form handlers | Power Apps embed |149| Custom script web parts | SPFx web parts |150151---152153## PnP Selector Functions154155| Function | Used By | Returns |156|---|---|---|157| `ListSelectorListLibrary({ListId},{XmlDefinition/ListViewXml})` | XsltListViewWP, ListViewWP | List, Library, Calendar, Issue, TaskList, DiscussionBoard, Survey, Undefined |158| `ContentEmbedSelectorContentLink({ContentLink},{Content},{FileContents},{UseCommunityScriptEditor})` | ContentEditorWP | Link, NonASPXLinkNoScript, NonASPXLink, ContentNoScript, Content, NonASPXUseCSE, ContentUseCSE |159| `ScriptEditorSelector({UseCommunityScriptEditor})` | ScriptEditorWP, SimpleFormWP | UseCommunityScriptEditor, NoScriptEditor |160| `ContentEmbedSelectorSourceType({SourceType})` | PageViewerWP | WebPage, ServerFolderOrFile |161| `ContentByQuerySelector({ListGuid},{ListName})` | ContentByQueryWP | Default, NoTransformation |162| `SummaryLinkSelector({SummaryLinksToQuickLinks})` | SummaryLinkWP | UseText, UseQuickLinks |163| `UserExistsSelector({PersonEmail})` | ContactFieldControl | ValidUser, InvalidUser |164165## Community Script Editor (CSE)166167**ControlId:** `3a328f0a-99c4-4b28-95ab-fe0847f657a3`168169| Web Part | CSE Branch | Content Source |170|---|---|---|171| ScriptEditorWebPart | UseCommunityScriptEditor | Inline `{Script}` |172| ContentEditorWebPart | NonASPXUseCommunityScriptEditor | Linked file `{FileContentsEncoded}` |173| ContentEditorWebPart | ContentUseCommunityScriptEditor | Inline `{Script}` |174| SimpleFormWebPart | UseCommunityScriptEditor | Form `{Script}` |175176**To enable:** Deploy [PnP react-script-editor](https://github.com/SharePoint/sp-dev-fx-webparts/tree/master/samples/react-script-editor) to the tenant app catalog, then set `pti.MappingProperties["UseCommunityScriptEditor"] = "true"`. **Without this, all script-dependent web parts are dropped.**177178---179180## BaseWebPart Fallback181182If a web part type has no specific PnP mapping, the BaseWebPart default is `***Web part {Title} was not transformed***`. This is distinct from:183- **empty mappings** — silently dropped (for example, TitleBar / GettingStarted)184- **error text** — specific error text (for example, XmlWebPart / DataForm)185- **unmapped** — properties catalogued but no mapping node, so the web part falls to BaseWebPart (for example, RSSAggregator)186187---188189## Reference Files190191| File | Contents | When to Read |192|---|---|---|193| `reference/pnp-transformations.md` | Per-webpart PnP details: selectors, branch tables, properties, migration %, corrections | Need exact PnP branch logic, property names, or migration specifics |194195Source data: PnP `webpartmapping.xml` v1.0.2111.0.