The Topical Map Editor is a visual tool for building, editing, and exporting structured content plans. It represents your site architecture as a graph of nodes (pages, sections, FAQs) connected by edges (links and relationships). You can load a generated map, edit it interactively, visualise it in four layouts, and export it as CSV, JSON, PNG, or SVG.
Every topical map has four hierarchy levels. Each level contains a specific type of node.
| Level | Node Type | Tier | Purpose | Example |
|---|---|---|---|---|
| Macro | Macro | 0 | The broadest subject area — the category | Dog Breeds |
| Seed | Seed | 1 | The primary topic the map is built around | Golden Retriever |
| Topic | Topic | 2 | Main subtopic areas of the seed | Golden Retriever Health |
| Subtopic | Subtopic | 3+ | Specific sub-pages under a topic | Golden Retriever Hip Dysplasia |
| FAQ | FAQ | 2–4 | Question-based section or page | Are Golden Retrievers Hypoallergenic? |
| Comparison | Comparison | 2–3 | Versus or comparison content | Golden Retriever vs Labrador |
Every node is classified as either a Standalone page (has its own URL) or a Section (appears as a section within a parent page, no URL of its own).
/golden-retriever/health/A Hub page is a standalone page that also acts as a navigation centre for its child pages. Hub nodes are shown with a gold ring around them in the graph.
Golden Retriever Health (Hub)
├── Summary: Hip Dysplasia ──→ /health/hip-dysplasia/
├── Summary: Cancer ──→ /health/cancer/
└── Summary: Lifespan ──→ (section on hub page)
| Edge Type | Colour | Meaning |
|---|---|---|
| Parent → Child (1) | Grey | Hierarchy link — parent page to child page |
| FAQ Attachment (3) | Orange dashed | FAQ node attached to its parent page |
| Related (4) | Purple | Related topic recommendation — not required |
Each node has a confidence score between 0 and 1 that reflects how strongly the AI pipeline believes this topic belongs in the map for this seed.
The editor includes a built-in Golden Retriever starter map that demonstrates a complete topical map with all node types, hub pages, sections, FAQs, entities, aliases, confidence scores, and a full edge set.
?starter=true in the URL to load it automaticallySwitch between four layouts using the buttons in the toolbar. Each layout shows the same data from a different perspective. Your edits and node positions are preserved when switching.
A physics-based simulation where nodes repel each other and edges act as springs. Connected nodes are pulled together while disconnected nodes spread apart. The layout is non-deterministic — it settles into a stable position over time.
A left-to-right tree layout. The Macro or Seed node is on the left and child nodes expand rightward. Depth (tier level) maps to horizontal position — Tier 1 is leftmost, deeper tiers are further right.
A top-to-bottom tree layout. The Macro or Seed node is at the top and child nodes expand downward. Depth (tier level) maps to vertical position — Tier 1 is at the top, deeper tiers are further down. Sibling nodes spread horizontally across the canvas.
| Property | Horizontal Tree | Vertical Tree |
|---|---|---|
| Root position | Left edge | Top edge |
| Tier axis | Horizontal (x = depth) | Vertical (y = depth) |
| Spread axis | Vertical (siblings spread up/down) | Horizontal (siblings spread left/right) |
| Edge shape | Left-to-right cubic bezier | Top-to-bottom cubic bezier |
| Best for | URL depth review | Wide maps, org-chart style |
A circular tree layout. The Seed node is at the centre, Tier 2 Topics form the first ring, Tier 3 Subtopics the second ring, and so on. Each tier sits on its own concentric ring with faint dashed guide circles and tier labels.
| Feature | Force Graph | Horizontal Tree | Vertical Tree | Radial Tree |
|---|---|---|---|---|
| Layout style | Physics simulation | Left-to-right hierarchy | Top-to-bottom hierarchy | Concentric rings |
| Tier visible? | Indirectly | Yes — column position | Yes — row position | Yes — ring position |
| Spread direction | All directions | Vertical | Horizontal | Radial |
| Drag nodes? | ✓ Full physics | ✓ Manual reposition | ✓ Manual reposition | ✓ Manual reposition |
| Best for presentations? | Moderate | Good (org chart) | Good (org chart) | Best (authority map) |
| Handles 100+ nodes? | Good | Moderate — can be tall | Moderate — can be wide | Good — rings spread out |
| Edge style | Straight lines | Horizontal bezier | Vertical bezier | Curved radial |
Switch between Circular and Rectangular node styles using View → Circular Nodes / Rectangular Nodes.
Each rectangular node has a small icon on the left side that identifies its type at a glance.
| Icon | Node Type |
|---|---|
| ◈ | Macro |
| ⬟ | Seed |
| ▣ | Topic |
| ▪ | Subtopic |
| ? | FAQ |
| ⇄ | Comparison |
Hover over any node to see a tooltip with full details: label, node type, tier, confidence score, canonical URL, child count, edge count, entities, and aliases.
Click any node to select it. The node is highlighted with a yellow border and the Node Properties panel opens on the right.
The edit panel on the right shows all properties of the selected node. Edit any field and click Apply Changes to save.
| Field | Description |
|---|---|
| Label | The display name of the node. Used for graph labels and CSV export. |
| Slug | URL-friendly version of the label. Auto-generated from label when URL is empty. |
| Node Type | Macro / Seed / Topic / Subtopic / FAQ / Comparison. |
| URL Role | Standalone = has its own page. Section Only = section within a parent page, no URL. |
| Hub Role | Mark this node as a Hub Page. Shows gold ring in graph. |
| Tier | Hierarchy depth. Macro=0, Seed=1, Topic=2, Subtopic=3+. |
| Parent Node | Dropdown of all valid parent candidates. Changing this re-parents the node — triggers a full layout redraw since the tree structure has changed. |
| Canonical URL | Auto-generated from parent URL + slug. Edit manually if needed. |
| Confidence | 0.00–1.00. How confident the AI is that this topic belongs in the map. |
| Entities | Named entities for this topic (pipe-separated). E.g. Hip Dysplasia | OFA | PennHIP |
| Aliases | Alternate search phrases (pipe-separated). Used for keyword targeting. |
When the Canonical URL field is empty, typing a label automatically generates the URL based on the parent's URL and the slug:
Parent URL: /dog-breeds/golden-retriever/health/
Slug: hip-dysplasia
Result: /dog-breeds/golden-retriever/health/hip-dysplasia/
Click Node → + Add Child Node to add a node under the currently selected node. The new node type is inferred automatically:
| Selected Node | New Node Type | Tier |
|---|---|---|
| Nothing selected | Topic | 2 (under Seed) |
| Macro | Seed | 1 |
| Seed | Topic | 2 |
| Topic | Subtopic | 3 |
| Subtopic | Subtopic | Parent tier + 1 |
| FAQ | Subtopic (sibling) | FAQ's tier |
| Comparison | Subtopic | 3 |
Select a node and click Node → 🗑 Delete Node or the Delete Node button in the edit panel. You can also press Delete or Backspace when a node is selected and no text field is focused.
To move a node to a different parent, select it and change the Parent Node dropdown in the edit panel, then click Apply Changes.
| Key | Action |
|---|---|
| / | Focus the search input |
| F | Fit view to all nodes (accounts for node width and label overhang) |
| Escape | Close the edit panel / clear search |
| Delete / Backspace | Delete the selected node (when not typing in a field) |
| Button | Layout | When to use |
|---|---|---|
| ⬡ Force | Force Graph | Explore clusters, spot disconnected nodes |
| ⟶ Tree H | Horizontal Tree | Review hierarchy and URL depth left-to-right |
| ⬇ Tree V | Vertical Tree | Org-chart style, wide maps with many siblings |
| ◎ Radial | Radial Tree | Presentations, exports, authority map view |
| Item | Description |
|---|---|
| 📂 Load JSON | Load a topical map JSON file from your computer. Replaces the current graph. |
| 🗺 Import Starter Map | Load the built-in Golden Retriever example map. Demonstrates all node types, hubs, FAQs, entities, and edges. |
| 📋 Import CSV | Import a CSV file of nodes via the server-side CSV importer. |
| ⬇ Export CSV (Client) | Export all nodes as CSV directly in the browser. No server needed. |
| 📋 Copy JSON | Copy the current graph JSON to your clipboard. Falls back to download if clipboard is unavailable. |
| 🖼 Export PNG — Viewport | Export what is currently visible on screen as a high-resolution PNG (4× scale). |
| 🖼 Export PNG — Full Map | Export the entire graph regardless of zoom. Minimum 4800px on the longer side. Node widths and label overhang are accounted for so nothing is clipped. |
| 📐 Export SVG — Viewport | Export the current viewport as a vector SVG with inlined styles and markers. |
| 📐 Export SVG — Full Map | Export the entire graph as a vector SVG. Scalable to any size. |
| 💾 Save | Save the current graph JSON to the server and download a copy. |
| Item | Description |
|---|---|
| + Add Child Node | Add a new node under the selected node. Type is inferred from the parent. New node spawns in a position appropriate for the current layout. |
| ⧉ Duplicate Node | Copy the selected node with all its properties. The copy gets a new ID and spawns near the original. |
| 🗑 Delete Node | Delete the selected node and all its edges. Children become orphaned — re-parent them if needed. |
| Item | Description |
|---|---|
| ↺ Reset Positions | Clear all manual node drag offsets and recompute the layout from scratch. |
| ⤢ Fit View | Zoom and pan to fit all nodes in the visible area. Also available with F. Accounts for node width and label overhang so nothing is clipped at the edges. |
| 🗺 Toggle Minimap | Show or hide the minimap in the bottom-right corner. Hidden by default — toggle to enable. |
| ▭ Rectangular Nodes | Switch to rectangular node style with full label text and word wrapping. |
| ● Circular Nodes | Switch back to circular node style. |
| ⟷ Full Labels / Short Labels | Toggle between full label text and truncated labels (circle mode) or wrapped labels (rect mode). |
| 🔗 Hide Section-Only Nodes | Hide all nodes with URL Role = Section Only from the graph. The data is preserved — toggle off to restore them. The stats bar shows visible/total when filtering is active. |
| ☀ Light Theme / 🌙 Dark Theme | Toggle between dark and light colour themes. |
Type in the search box (or press /) to search all nodes by label, slug, canonical URL, aliases, and entities.
The minimap shows a bird's-eye view of the entire graph with a viewport indicator (purple dashed rectangle). It is hidden by default — enable it via View → 🗺 Toggle Minimap.
The stats bar below the toolbar shows live counts from the current graph. When Hide Section-Only Nodes is active, the Nodes count shows visible/total.
-viewport.png-full.pngSVG files are vector format — they can be scaled to any size without loss of quality. All styles, colours, and arrow markers are inlined into the SVG so it is fully self-contained.
The client-side CSV export builds the file entirely in the browser from the current graph data — no server call required.
Columns exported:
Copy JSON writes the full graph to your clipboard as formatted JSON. Paste it into any text editor, API client, or database tool.
Save posts the JSON to the server and also triggers a
download of topical-map-edit.json so you always have a
local copy.
| Goal | Layout | Export |
|---|---|---|
| Client presentation image | Radial Tree → Fit View | PNG — Full Map |
| Org-chart style image | Vertical or Horizontal Tree → Fit View | PNG — Full Map |
| Print-quality vector | Any → Fit View | SVG — Full Map |
| Content brief spreadsheet | Any | Export CSV (Client) |
| Pipeline reload / CMS import | Any | Copy JSON or Save |
| Neo4j / D3.js import | Any | Copy JSON — nodes + edges structure |
| Pattern | What to Do |
|---|---|
| Topic with 3+ subtopics | Mark the Topic as a Hub. Add a summary section for each child on the hub page. |
| FAQ with no parent | Assign it to the Seed or the most relevant Topic using the Parent Node dropdown. |
| Section-only node that should be a page | Change URL Role to Standalone. The URL auto-generator will propose a URL immediately. |
| Duplicate or near-duplicate labels | Delete one and re-parent its children. Or merge by making one a Section under the other. |
| Low confidence nodes (below 0.70) | Review whether the topic genuinely belongs. Delete if it is off-topic or too thin. |
| Map has no Hub pages | Any Topic with 3+ subtopics should be a Hub. Select it and set Hub Role = Hub Page. |
| Tier 5+ nodes | Deep subtopics may be too granular. Consider making them sections within their parent. |
| Map looks crowded in Vertical Tree | The Vertical Tree works best for maps with fewer than 6 Topics. For wider maps use Horizontal Tree or Radial. |
| Nodes clipped in export | Press F (Fit View) before exporting. The export bounding box accounts for node width and label overhang. |
| Mistake | Why It Matters | Fix |
|---|---|---|
| Standalone node with no URL | The page cannot be indexed if it has no canonical URL | Type a label — the URL auto-generator fills the field automatically |
| Section-only node with a URL | Creates a phantom URL that will return 404 | Change URL Role to Section Only — the URL field will clear |
| Hub with fewer than 2 children | A hub with one child is just a normal page with extra navigation complexity | Add more child nodes or remove the Hub Role designation |
| FAQ marked as Standalone with a URL | FAQs are almost always sections, not full pages | Change URL Role to Section Only unless the FAQ is a genuinely full dedicated page |
| Deleting a node that has children | Children become orphaned — they disappear from tree layouts | Re-parent children before deleting the parent, or delete them first |
| Circular parent reference | Node A → parent is Node B, Node B → parent is Node A. Creates an infinite loop. | The Parent Node dropdown excludes descendants to prevent this — if it happens via import, fix in the JSON before loading |
| All nodes at the same tier | A flat map has no topical authority signal — Google cannot determine what is most important | Establish a clear Macro → Seed → Topic → Subtopic hierarchy with at least 3 levels |
| No Seed node | The tree layouts create a virtual root and the hierarchy looks disconnected | Ensure exactly one node has nodeType = 1 (Seed) |
| Switching layout without Fit View | After switching to Vertical or Horizontal Tree the map may render off-screen | Press F immediately after switching layout to re-centre the view |
The editor reads and writes JSON in the following shape. Both PascalCase (pipeline output) and camelCase (editor export) are supported on import.
{
"Metadata": {
"macro": "Dog Breeds",
"seed": "Golden Retriever",
"generatedAt": "2025-01-15T00:00:00Z",
"pipelineVersion": "1.0.0",
"siteUrl": "https://example.com"
},
"Nodes": [
{
"Id": "topic-golden-retriever-health",
"Label": "Golden Retriever Health",
"Slug": "golden-retriever-health",
"NodeType": 2,
"Tier": 2,
"ParentId": "seed-golden-retriever",
"MacroId": "macro-dog-breeds",
"SeedId": "seed-golden-retriever",
"UrlRole": 1,
"HubRole": 1,
"ArchitectureType": 4,
"CanonicalUrl": "/dog-breeds/golden-retriever/health/",
"ParentUrl": "/dog-breeds/golden-retriever/",
"ConfidenceScore": 0.97,
"Entities": ["Canine Hip Dysplasia", "OFA"],
"Aliases": ["golden retriever health issues"]
}
],
"Edges": [
{
"Id": "edge-seed-to-health",
"SourceId": "seed-golden-retriever",
"TargetId": "topic-golden-retriever-health",
"EdgeType": 1,
"Weight": 0.98,
"RecommendedAnchorText": "Golden Retriever Health",
"IsRequired": true
}
]
}
| Field | Values |
|---|---|
NodeType |
0 Macro · 1 Seed · 2 Topic · 3 Subtopic · 4 FAQ · 5 Comparison |
UrlRole |
0 Section Only · 1 Standalone |
HubRole |
0 Not a Hub · 1 Hub Page |
ArchitectureType |
0 None · 1 SectionOnly · 2 HubOnly · 3 StandaloneOnly · 4 SectionAndHub · 5 StandaloneAndHub |
EdgeType |
1 Parent-Child · 3 FAQ Attachment · 4 Related |