Launched:self-serve migrations intoSuperhuman Docs (Coda)
Try it now
01Agent-first
Runs where you already work
Plug it into Claude, ChatGPT or Cursor. Describe the move in plain English; the agent runs it.
02Engineer-led
Our production engine, unlocked
The pipeline our engineers use on managed enterprise migrations — the same code, now something you can drive yourself.
03Pricing
Try 10 pages free, then $1 a page
Credit-based, pay-as-you-go. No scoping call, no quote — sample it on your own docs before you spend anything.
04Sources
NotionSlabConfluenceSoonGoogle DocsSoon
Skip to content

Notion to SharePoint: How to Preserve Page Hierarchy

Notion nests pages infinitely; SharePoint caps navigation at 3 levels. Learn how to extract, map, and rebuild your page hierarchy during migration.

Nachi Raman Nachi Raman · · 17 min read
Notion to SharePoint: How to Preserve Page Hierarchy
TALK TO AN ENGINEER

Planning a migration?

Get a free 30-min call with our engineers. We'll review your setup and map out a custom migration plan — no obligation.

Schedule a free call
  • 1,500+ migrations completed
  • Zero downtime guaranteed
  • Transparent, fixed pricing
  • Project success responsibility
  • Post-migration support included

Notion to SharePoint: How to Preserve Page Hierarchy

Notion lets you nest pages inside pages indefinitely. Modern SharePoint Online caps its navigation at three levels. That mismatch is where most Notion-to-SharePoint migrations lose their structure — not during the content transfer, but during the hierarchy translation.

The data arrives, but nobody can find anything. The tree that organized everything in Notion has no native equivalent in SharePoint. If you export Notion pages and upload them to a Site Pages library, you get a flat, unorganized list of hundreds of .aspx files with no grouping and no discoverable navigation.

Scope: This guide covers Modern SharePoint Online exclusively. Classic SharePoint subsite patterns, managed paths, and legacy navigation behavior are not addressed — they are deprecated for new deployments and behave differently in every dimension discussed here.

This guide covers how Notion's page hierarchy works at the data level, why SharePoint rejects it, and the concrete strategies for rebuilding that hierarchy so your team's navigation survives the move.

For the full migration picture — block mapping, API extraction, file handling — see Notion to SharePoint Migration: The Complete Technical Guide. For database-to-list column mapping, see Mapping Notion Databases to SharePoint Lists.

Why Notion's page hierarchy breaks in SharePoint

The two platforms use fundamentally different data models for organizing content.

Notion's data model is a recursive block tree. Every element — pages, paragraphs, toggles, databases — is a block with a unique ID. A page is a block. If you drag Page B inside Page A, Page A's block lists Page B's ID in its children array. Because any block can have children, Notion supports unlimited nesting depth, though performance degrades and most teams stop around three or four levels in practice. (developers.notion.com)

Modern SharePoint's data model is flat sites connected by hubs. Modern SharePoint pages live in the Site Pages library — a single flat list. Hierarchy comes from three layers of navigation (global, hub, and local), not from pages owning other pages. Hub sites connect independent site collections; they don't create parent-child page relationships. Subsites, which did create hierarchical ownership, are a deprecated pattern that Microsoft explicitly discourages for new deployments. (learn.microsoft.com)

Concept Notion Modern SharePoint Online
Fundamental unit Block (pages are blocks) Site, list, library, page
Nesting model Unlimited parent-child depth Flat sites connected by hubs
Navigation depth Follows page tree (unlimited) 3 levels max (mega menu / cascading)
Child links per nav level N/A (tree-based) 500 hard limit, ~100 recommended
Content storage JSON block tree via API CanvasContent1 JSON in Site Pages library
Hierarchy signal parent block ID Hub association + navigation nodes
Subsite support N/A Deprecated; avoid for new deployments

When you migrate, you are forcing a recursive tree into a flat container. The physical storage of a page must be decoupled from its logical position in the hierarchy.

What does "preserve hierarchy" actually mean in SharePoint?

Hierarchy preservation in SharePoint means preserving wayfinding, not replicating Notion's page tree. When teams say "preserve hierarchy," they're usually mixing four distinct concerns:

  • Navigation hierarchy: the links people browse in headers, left nav, hub nav, and landing pages.
  • Container hierarchy: which site, library, list, or folder stores the item.
  • Link hierarchy: which pages reference which pages via internal links.
  • Permission hierarchy: where access inherits cleanly and where it breaks into unique scopes.

In modern SharePoint, these layers don't have to be identical. Hub relationships are link-based rather than ownership-based. Site navigation is persistent across pages. Item-level permissions can break inheritance at any point. If you don't pick one layer as the source of truth for your migration, you end up preserving none of them well. (learn.microsoft.com)

For most knowledge-base migrations, navigation hierarchy is the layer that matters most — it determines whether people can actually find content after the move.

How to extract the page tree from Notion

Build the hierarchy map before migrating any content. The Notion API doesn't offer a single endpoint to download your workspace tree. You must start at root pages and traverse downward, recording every parent-child relationship into an intermediate manifest.

Warning

Access scope matters. The Notion search endpoint only returns pages and data sources shared with the integration connection, and Notion exports also omit pages the exporter cannot access. Hierarchy problems often start as access problems, not transformation problems. Verify sharing permissions on your integration before building the pipeline. (developers.notion.com)

Recursive API extraction

The Notion API returns only first-level children for any block. You call GET /v1/blocks/{block_id}/children, get up to 100 results per page, check each block's has_children property, and recursively call the same endpoint for every child. Each level requires at least one API call.

One edge case that silently breaks traversal scripts: a Notion page can simultaneously be a child page and contain an inline database. The child_page block type and child_database block type appear in the same children array. If your traversal recurses into both without distinguishing them, you will attempt to navigate into database records as if they were page subtrees. You must check block ["type"] and branch: child_page continues the hierarchy walk; child_database is flagged for separate SharePoint List creation.

def extract_hierarchy(block_id, depth=0, parent_path="", node_type="page"):
    """Recursively extract Notion page tree with path tracking and type disambiguation."""
    children = notion.blocks.children.list(block_id=block_id)
    pages = []
    for block in children["results"]:
        if block["type"] == "child_page":
            title = block["child_page"]["title"]
            path = f"{parent_path}/{title}"
            pages.append({
                "id": block["id"],
                "title": title,
                "path": path,
                "depth": depth,
                "node_type": "page"
            })
            if block["has_children"]:
                pages.extend(extract_hierarchy(block["id"], depth + 1, path, "page"))
        elif block["type"] == "child_database":
            title = block["child_database"]["title"]
            path = f"{parent_path}/{title}"
            pages.append({
                "id": block["id"],
                "title": title,
                "path": path,
                "depth": depth,
                "node_type": "database"  # Routes to SharePoint List, not Site Page
            })
            # Do NOT recurse into database records as hierarchy nodes
    return pages

This traversal produces a flat list of pages, each tagged with its depth, full path, and node type — the raw material for all downstream decisions. (developers.notion.com)

Building the intermediate manifest

Store the relationships in a structured format. Your manifest must capture the Notion page ID, title, parent ID, depth, full path, and node type. The node_type field is what determines whether a node becomes a SharePoint Site Page or a SharePoint List in later steps.

[
  {"id": "abc123", "title": "Engineering", "parent_id": null, "depth": 0, "path": "/Engineering", "node_type": "page"},
  {"id": "def456", "title": "Backend", "parent_id": "abc123", "depth": 1, "path": "/Engineering/Backend", "node_type": "page"},
  {"id": "ghi789", "title": "API Design", "parent_id": "def456", "depth": 2, "path": "/Engineering/Backend/API Design", "node_type": "page"},
  {"id": "jkl012", "title": "REST Conventions", "parent_id": "ghi789", "depth": 3, "path": "/Engineering/Backend/API Design/REST Conventions", "node_type": "page"},
  {"id": "mno345", "title": "Endpoint Registry", "parent_id": "def456", "depth": 2, "path": "/Engineering/Backend/Endpoint Registry", "node_type": "database"}
]

This manifest is your single source of truth for every downstream decision — which SharePoint site a node belongs to, whether it becomes a page or a list, where it sits in navigation, and what its URL slug should be.

Extraction constraints to plan for

  • Rate limiting. Notion enforces per-connection rate limits based on workspace plan — 600 requests per minute for Business and Enterprise workspaces, 180 requests per minute for other plans. A workspace with 500 pages and average nesting depth of 3 requires ~1,500+ API calls for the hierarchy walk alone. Build in exponential backoff on 429 responses. (developers.notion.com)
  • Pagination. Each children.list call returns up to 100 blocks. If a page has more than 100 direct children, you must follow the next_cursor value to retrieve subsequent pages.
  • Child pages vs. inline databases. As described above, your traversal must distinguish child_page blocks (hierarchy continuation) from child_database blocks (structured data going to SharePoint Lists). Conflating them corrupts the manifest.
  • Unsupported block types. The Notion API returns type: "unsupported" for block types it cannot expose. Synced blocks are a specific trap — the API documents original and duplicate synced blocks but does not support updating synced block content. Build explicit fallback rendering for both. (developers.notion.com)
  • Untitled pages. Notion allows pages without titles. SharePoint requires a valid filename for each .aspx page. Your script must detect empty title properties and assign a fallback (e.g., Untitled-Page-abc123.aspx) to prevent the Microsoft Graph API from rejecting the request with a 400 Bad Request error.
Tip

Alternative extraction path: Notion's native HTML export with "Include subpages" and "Create folders for subpages" enabled produces a ZIP where the folder structure mirrors the page hierarchy. This is faster than API extraction for smaller workspaces and gives you the hierarchy implicitly through the filesystem. You lose block-level metadata, database properties, and relations, so it's best for validation or archive use cases — not production migrations where databases need to become SharePoint Lists. (notion.com)

Decision tree: which hierarchy strategy to use

Before examining each strategy in detail, use this decision logic to identify the right starting point for your workspace. Most real migrations combine two strategies.

Is your Notion hierarchy 3 levels deep or fewer?
├── YES: Is your total page count under 300?
│   ├── YES → Strategy 1: Site navigation with mega menu
│   └── NO  → Strategy 1 + consolidate top-level sections to stay under 100 nav nodes
└── NO (depth > 3): Do top-level sections represent distinct domains with separate audiences?
    ├── YES → Strategy 2: Hub sites per domain
    │         Within each hub site, apply Strategy 1 for local navigation
    └── NO  → Strategy 3: Managed metadata + page tagging
              Surface deep pages via filtered views and highlighted content web parts
              Use in-page "Related Pages" sections for Level 4+ nodes

Is the content primarily reference/archive (read-only, rarely updated)?
└── YES → Strategy 4: Document library folders (PDF/HTML export)
          Only if active editing and wiki-style browsing are not required

Four strategies for representing hierarchy in SharePoint

Strategy 1: Site navigation with mega menu (up to 3 levels)

Best for: Workspaces where the Notion hierarchy is 3 levels deep or fewer AND the total number of top-level sections is under 100.

SharePoint's mega menu supports three navigation levels and is the closest structural analog to a shallow Notion tree. Each top-level Notion page becomes a Level 1 heading; child pages become Level 2 links; grandchild pages become Level 3 links. Every page exists in the Site Pages library, and the navigation menu provides the tree.

PnP PowerShell is one implementation path. The Microsoft Graph API (/_api/web/navigation/quicklaunch) is the canonical, version-stable alternative that works without community tooling installed. Both approaches are shown below.

PnP PowerShell:

Connect-PnPOnline -Url "https://tenant.sharepoint.com/sites/wiki" -Interactive
Set-PnPWeb -MegaMenuEnabled $true
 
# Level 1: top-level section
$parentNode = Add-PnPNavigationNode -Title "Engineering" `
  -Url "/sites/wiki/SitePages/Engineering.aspx" `
  -Location QuickLaunch
 
# Level 2: child page
$childNode = Add-PnPNavigationNode -Title "Backend" `
  -Url "/sites/wiki/SitePages/Backend.aspx" `
  -Location QuickLaunch -Parent $parentNode.Id
 
# Level 3: grandchild page
Add-PnPNavigationNode -Title "API Design" `
  -Url "/sites/wiki/SitePages/API-Design.aspx" `
  -Location QuickLaunch -Parent $childNode.Id

Microsoft Graph API (REST, portable across tools):

POST https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items
 
{
  "fields": {
    "Title": "Engineering",
    "Url": "/sites/wiki/SitePages/Engineering.aspx",
    "ParentId": 1002
  }
}

For programmatic navigation builds from your manifest, the Graph API is preferable: it doesn't require PnP module installation and returns structured JSON you can parse to capture new node IDs for parent-child linking.

This approach breaks once your Notion tree exceeds three levels. Anything at Level 4+ has no navigation node — users can reach the page via direct link or search, but it becomes invisible in the menu.

Warning

Navigation node limits: SharePoint enforces a hard limit of 500 child links per navigation level. Microsoft recommends roughly 100 items for acceptable load performance. If your Notion workspace has 300 top-level sections, you must consolidate before building navigation. (learn.microsoft.com)

Strategy 2: Hub sites for top-level sections (deep hierarchies)

Best for: Large workspaces where top-level Notion sections are distinct domains (Engineering, Sales, HR) with deep internal trees, OR any workspace where total depth exceeds 3 levels and content has separate audiences.

Each major Notion section becomes its own SharePoint site, associated to a central hub. Within each site, you use the 3-level local navigation for that section's subtree. This effectively gives you a fourth level: Hub nav → Site → Local nav (3 levels).

The trade-off: hub sites are a governance commitment. Each site has its own permissions, storage quota, and admin surface. Creating 15 hub-associated sites for a 15-section Notion workspace adds real operational overhead. Hub site association is managed through the SharePoint Admin Center or via Set-SPOHubSite in SharePoint Online Management Shell.

Strategy 3: Managed metadata + page tagging (flat pages, structured discovery)

Best for: Teams willing to move away from tree navigation in favor of metadata-driven discovery, or workspaces with depth > 3 where splitting into hub sites would create too many separate sites to manage.

Create all Notion pages as flat SharePoint site pages. Attach a managed metadata term set that mirrors the Notion hierarchy: Engineering > Backend > API Design > REST Conventions. Users find pages through filtered views, search, and highlighted content web parts.

You can also add a custom ParentPageID lookup column to the Site Pages library and use highlighted content web parts to dynamically display "child pages" at the bottom of each parent page. This preserves infinite nesting and keeps the navigation menu clean, but users can't see the entire tree at a glance — they must click through pages to navigate deeper.

This approach also integrates with Viva Topics, which can auto-tag pages to term sets and surface related content without manual metadata entry — relevant for large, evolving content sets where maintaining term assignments manually is impractical.

SharePoint content types are worth considering alongside managed metadata, particularly for regulated industries. A content type — for example, EngineeringKBArticle — can carry default column values, metadata templates, and retention policies. When all pages of a given type inherit the same content type, bulk metadata updates (including hierarchy path columns) can be applied centrally without touching individual pages.

This approach requires the most change management but scales the best for large, evolving knowledge bases.

Strategy 4: Document library folders (archive-only content)

Best for: Notion pages that are primarily reference documents, SOPs, or templates — content you're archiving, not actively editing.

Export Notion pages to PDF or HTML and upload them into a SharePoint document library with a folder structure mirroring the Notion tree. Document libraries support deep folder nesting up to 400 characters in the decoded URL path. (support.microsoft.com)

Note that this 400-character limit applies to OneDrive for Business and SharePoint document libraries stored in the same infrastructure. Deeply nested Notion hierarchies with long page titles will hit this limit at around Level 5–6 depending on title lengths. Test your longest paths before committing to this structure.

The downside: you lose wiki-style browsing and inline editing. Content becomes files, not pages. This is a compromise for archival or compliance use cases, not active knowledge bases.

What about folders in the Site Pages library?

Do not create folders inside the Site Pages library to mimic Notion's structure. While technically possible via the Microsoft Graph API Drive endpoints, Microsoft explicitly advises against it. Folders in Site Pages break modern web part rollups, complicate permission management, and quickly run into SharePoint's URL path limit. A deeply nested Notion page will generate a URL that exceeds the limit, causing a 400 Bad Request error from the Graph API.

How to handle pages deeper than 3 levels

This is the hardest translation problem in the migration. SharePoint's navigation menus max out at three levels — the mega menu renders all three, the cascading menu works best with two. Any Notion page at depth 4+ has no natural home in the menu.

Four resolution strategies, each with trade-offs:

1. Flatten and promote. Audit the tree and ask whether Level 4+ pages genuinely need their own page. A Notion page titled "REST Conventions" with 200 words of content can become an H2 section on the "API Design" SharePoint page instead of a standalone page. This reduces page count and keeps everything within 3 navigation levels.

2. Use in-page link sections. Keep Level 4+ pages as site pages but surface them through a "Related Pages" or "In This Section" web part on their Level 3 parent page. The navigation tree shows three levels; the fourth level is one click away via the page body. This preserves content separation without requiring navigation depth SharePoint can't provide.

3. Split into multiple sites. If a subtree exceeds 3 levels, give it its own SharePoint site associated to the hub. What was Level 3 in the old tree becomes Level 1 in the new site's local navigation, buying you three more levels.

4. Breadcrumb metadata. Tag every page with its full Notion path as a managed metadata column (e.g., Engineering > Backend > API Design > REST Conventions). Users searching or filtering by this column can reconstruct the tree mentally, even if the navigation doesn't show it. Especially useful for compliance and records management scenarios.

In practice, most workspaces use a combination: flatten the obvious candidates, split the deeply nested domains into their own sites, and use in-page link sections for everything in between.

The database-as-parent edge case

In Notion, a database is a page. You can nest a standard page inside a database, or nest a database inside a page. Modern SharePoint separates these concepts entirely. A database becomes a SharePoint List. A page becomes a Site Page. A SharePoint List cannot act as a structural parent to a Site Page in the navigation tree.

The manifest representation must reflect this distinction. A database node in the manifest carries "node_type": "database" and is excluded from navigation node generation. Instead, it gets a corresponding Site Page created as a landing wrapper:

{"id": "mno345", "title": "Endpoint Registry", "parent_id": "def456", "depth": 2, "path": "/Engineering/Backend/Endpoint Registry", "node_type": "database", "sharepoint_list_name": "Endpoint Registry", "wrapper_page": "Endpoint-Registry.aspx"}

To preserve the navigation experience:

  1. Create the SharePoint List to hold the database records (mapped columns per your database schema).
  2. Create a SharePoint Site Page named after the Notion database (e.g., Endpoint-Registry.aspx).
  3. Embed a List Web Part on that Site Page pointing to the new list.
  4. Treat that Site Page — not the list itself — as the navigation node in your hierarchy.

When users click what used to be the "Endpoint Registry" database in the Notion sidebar, they land on a SharePoint page displaying the list — maintaining the expected navigation path. Your navigation script processes the wrapper_page field from the manifest rather than trying to link directly to a list URL.

For details on column and property mapping, see The Ultimate Guide to Mapping Notion Databases to SharePoint Lists.

Rebuilding the navigation programmatically

Once site pages exist in SharePoint, the hierarchy is navigation configuration. Here's the complete sequence:

1. Choose your navigation style. Enable mega menu if your deepest remaining level is 3:

Set-PnPWeb -MegaMenuEnabled $true

For cascading navigation (2 levels), leave this disabled.

2. Generate the navigation script from your manifest. Filter your hierarchy JSON to node_type: "page" nodes at depth 0, 1, and 2 (the three navigation levels). For database nodes, substitute their wrapper_page value. Generate Add-PnPNavigationNode calls or Graph API POST requests from the filtered set, capturing each returned node ID to use as the ParentId for child nodes.

3. Run the script against the target site. For large navigation structures, batch the calls and add a short delay between batches — SharePoint Online throttles REST calls at scale. Microsoft Graph API responses include a Retry-After header on 429 responses; honor it.

4. Rewrite internal links. This is a second pass after all SharePoint pages exist. Map each Notion page ID to its new SharePoint webUrl, then update every internal link in every page body. You can only do this after every target page has been created, because SharePoint returns a webUrl only after the page object exists. (learn.microsoft.com)

5. Handle Level 3+ pages. Add "See Also" links, highlighted content web parts, or breadcrumb metadata as described above.

6. Validate with structured checks — not just manual browsing. "Walk the navigation as a user" is necessary but insufficient. Run these checks programmatically:

Orphan page detection — pages migrated but not reachable from navigation:

GET https://graph.microsoft.com/v1.0/sites/{site-id}/pages

Compare the returned page URLs against your manifest's navigation node URLs. Any webUrl present in the pages response but absent from your navigation node list is an orphan.

Navigation completeness check — manifest nodes at depth 0–2 with node_type: "page" that have no corresponding navigation entry:

def find_missing_nav_nodes(manifest, nav_nodes):
    """Identify manifest pages that were not added to navigation."""
    nav_urls = {node["url"] for node in nav_nodes}
    missing = []
    for item in manifest:
        if item["depth"] <= 2 and item["node_type"] == "page":
            expected_url = f"/sites/wiki/SitePages/{slugify(item['title'])}.aspx"
            if expected_url not in nav_urls:
                missing.append(item)
    return missing

Depth-4+ coverage check — confirm every deep page has at least one of: a breadcrumb metadata value, an in-page parent link, or a search-indexed managed metadata tag. Pages with none of these are structurally invisible.

A migration can look correct in the first 20 pages and be structurally broken at page 200. Programmatic validation is the only way to detect this at scale.

Common failure modes

These are the hierarchy-related failures that appear repeatedly across Notion-to-SharePoint migrations:

  • "Flat dump" migrations. Every Notion page lands in Site Pages with no navigation setup. Content is technically present but undiscoverable. Teams revert to the old system within days.
  • Subsites instead of hub sites. Someone creates a subsite hierarchy to mirror Notion's nesting. Subsites are a deprecated Modern SharePoint pattern — they don't inherit hub navigation, they complicate permissions, and Microsoft explicitly discourages them for new deployments. (learn.microsoft.com)
  • Navigation built manually. A migration moves 400 pages, then someone spends a week clicking through SharePoint's navigation editor. Error-prone and unnecessary — generate it from the manifest.
  • Ignoring depth > 3. Pages at Level 4+ are migrated with no navigation entry, no in-page links, and no metadata tags. They become orphaned content only search can surface — and only if search has indexed them.
  • Overloading a single site. A large Notion workspace loaded into one SharePoint site. Beyond a few hundred pages in the Site Pages library, views slow, navigation becomes unmanageable, and permission administration becomes complex. Split by domain.
  • Conflating child_page and child_database blocks. Traversal scripts that recurse into database records as if they were pages produce a corrupt manifest and navigation entries that point to non-existent SharePoint pages.
  • Unsupported Notion blocks. The Notion API returns type: "unsupported" for blocks it cannot expose. Synced blocks require special handling — the API documents them but does not support updating synced block content. Plan explicit fallback rendering. (developers.notion.com)
  • Permission drift. SharePoint permissions inherit by default, but unique permissions break inheritance. If your Notion hierarchy relied on page-by-page access controls, decide whether those exceptions are genuinely required or social conventions that accumulated over time. Preserving a messy permission tree is usually a governance problem disguised as a migration requirement.
  • Ignoring content types for structured content. Migrating all pages as the default Site Page content type works for general content, but loses the ability to apply bulk metadata, retention policies, or templated views by content category. For regulated industries or large content sets with distinct lifecycles, define content types before migration begins.

Getting the hierarchy right before go-live

The teams that preserve hierarchy best make one decision early: are they rebuilding a working SharePoint knowledge base, or preserving a Notion archive? Once that answer is explicit, the right mapping — site navigation, hub sites, metadata, or document folders — becomes much clearer.

The APIs won't do the mapping for you. You must extract the recursive tree, distinguish page nodes from database nodes, flatten the storage layer, and rebuild the visual hierarchy using SharePoint's native navigation tools. Attempting to force Notion's exact structure into SharePoint through folders in Site Pages or deprecated subsites will result in broken URLs, failed web part rollups, and a degraded navigation experience.

The critical sequence:

  1. Extract the full hierarchy manifest before touching SharePoint
  2. Classify every node as page or database
  3. Apply the decision tree to choose your strategy
  4. Create all target pages and lists
  5. Build navigation programmatically from the manifest
  6. Rewrite internal links after all pages exist
  7. Run orphan detection and navigation completeness checks before go-live

If you're facing a complex move, ClonePartner handles the extraction, transformation, and loading. We offer one fixed price per project starting at $500, with no hourly billing and no change orders. Every project includes a dedicated migration engineer and unlimited sample migrations until the data — and the hierarchy — is exactly right.

Frequently Asked Questions

Can SharePoint natively preserve Notion's nested page hierarchy?
Not natively. SharePoint navigation supports a maximum of 3 levels (mega menu or cascading). Notion pages nested deeper than 3 levels need to be flattened into parent page sections, surfaced through in-page link web parts, split into separate SharePoint sites, or tagged with managed metadata for discovery via search and filtered views.
How many navigation levels does SharePoint support?
SharePoint Online's mega menu and cascading navigation both support a maximum of 3 levels. Each level supports up to 500 child links, though Microsoft recommends keeping navigation to around 100 items for performance.
How do you extract the page hierarchy from Notion?
Use the Notion API to recursively call GET /v1/blocks/{block_id}/children for each page, checking the has_children property to traverse deeper. Store every page's ID, title, parent ID, depth, and path in a JSON manifest. Alternatively, Notion's native HTML export with 'Include subpages' and 'Create folders for subpages' preserves hierarchy as a folder tree, though you lose block-level metadata.
What happens to Notion pages deeper than 3 levels in SharePoint?
Pages at depth 4 or beyond have no navigation node in SharePoint. Common solutions include flattening them into H2 sections of a parent page, surfacing them through 'Related Pages' web parts on the Level 3 parent, splitting the subtree into its own SharePoint site to reset the depth counter, or tagging them with breadcrumb metadata for search-based discovery.
Should I use subsites or folders to mirror Notion's hierarchy in SharePoint?
No. Subsites are a legacy pattern that don't inherit hub navigation and complicate permissions — Microsoft discourages them for new deployments. Folders in the Site Pages library break modern web part rollups and risk exceeding SharePoint's 400-character URL path limit. Use site navigation, hub associations, and managed metadata instead.

More from our Blog

The Ultimate Guide to Mapping Notion Databases to SharePoint Lists
Notion/SharePoint

The Ultimate Guide to Mapping Notion Databases to SharePoint Lists

This engineer-led guide details exactly how to map Notion databases to SharePoint lists while preserving your critical relationships. Learn the 4-step architecture for converting Columns to Types, Relations to Lookups, and using SharePoint 'Dynamic Filtering' to recreate the Notion dashboard experience—ensuring zero data loss during your migration.

Raajshekhar Rajan Raajshekhar Rajan · · 8 min read