or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

block-property-utilities.mdcontent-extraction.mddata-operations.mdid-url-management.mdindex.mdnavigation-structure.mdpage-analysis.mdtext-processing.md

navigation-structure.mddocs/

0

# Navigation & Structure

1

2

Tools for building navigation elements and extracting structural information from Notion pages including table of contents generation and workspace traversal.

3

4

## Capabilities

5

6

### Get Page Table of Contents

7

8

Generates a table of contents by parsing H1, H2, and H3 header elements from a page.

9

10

```typescript { .api }

11

/**

12

* Gets the metadata for a table of contents block by parsing the page's H1, H2, and H3 elements

13

* @param page - The page block to analyze

14

* @param recordMap - Extended record map containing all blocks

15

* @returns Array of TOC entries with hierarchy information

16

*/

17

function getPageTableOfContents(

18

page: PageBlock,

19

recordMap: ExtendedRecordMap

20

): Array<TableOfContentsEntry>;

21

22

interface TableOfContentsEntry {

23

/** Block ID of the header */

24

id: string;

25

/** Block type (header_1, header_2, header_3) */

26

type: BlockType;

27

/** Header text content */

28

text: string;

29

/** Indentation level (0, 1, 2) */

30

indentLevel: number;

31

}

32

```

33

34

**Usage Example:**

35

36

```typescript

37

import { getPageTableOfContents } from "notion-utils";

38

39

const toc = getPageTableOfContents(pageBlock, recordMap);

40

toc.forEach(entry => {

41

const indent = " ".repeat(entry.indentLevel);

42

console.log(`${indent}- ${entry.text} (${entry.type})`);

43

});

44

45

// Example output:

46

// - Introduction (header_1)

47

// - Overview (header_2)

48

// - Getting Started (header_2)

49

// - Installation (header_3)

50

// - Advanced Topics (header_1)

51

```

52

53

### Get All Pages in Space

54

55

Performs a traversal over a Notion workspace to collect all reachable pages.

56

57

```typescript { .api }

58

/**

59

* Performs a traversal over a Notion workspace starting from a seed page

60

* @param rootPageId - Starting page ID for traversal

61

* @param rootSpaceId - Space ID containing the pages (can be undefined)

62

* @param getPage - Function to fetch page data by ID

63

* @param options - Traversal configuration options

64

* @returns Promise resolving to a map of all discovered pages

65

*/

66

function getAllPagesInSpace(

67

rootPageId: string,

68

rootSpaceId: string | undefined,

69

getPage: (pageId: string) => Promise<ExtendedRecordMap>,

70

options?: TraversalOptions

71

): Promise<PageMap>;

72

73

interface TraversalOptions {

74

/** Number of concurrent page requests (default: 4) */

75

concurrency?: number;

76

/** Whether to traverse collection database items (default: true) */

77

traverseCollections?: boolean;

78

/** Optional target page ID to stop at when found */

79

targetPageId?: string;

80

/** Maximum traversal depth (default: Infinity) */

81

maxDepth?: number;

82

}

83

84

type PageMap = Record<string, ExtendedRecordMap>;

85

```

86

87

**Usage Example:**

88

89

```typescript

90

import { getAllPagesInSpace } from "notion-utils";

91

92

// Function to fetch a page (you provide this)

93

async function fetchPage(pageId: string): Promise<ExtendedRecordMap> {

94

// Your implementation to fetch page data

95

return await notion.getPage(pageId);

96

}

97

98

// Traverse workspace starting from a root page

99

const allPages = await getAllPagesInSpace(

100

"root-page-id",

101

"space-id",

102

fetchPage,

103

{

104

concurrency: 6,

105

traverseCollections: true,

106

maxDepth: 10

107

}

108

);

109

110

console.log(`Found ${Object.keys(allPages).length} pages`);

111

112

// Access individual pages

113

Object.entries(allPages).forEach(([pageId, recordMap]) => {

114

const title = getPageTitle(recordMap);

115

console.log(`Page ${pageId}: ${title}`);

116

});

117

```

118

119

### Get Page Content Block IDs

120

121

Gets all block IDs contained within a page, including nested content.

122

123

```typescript { .api }

124

/**

125

* Gets the IDs of all blocks contained on a page starting from a root block ID

126

* @param recordMap - Extended record map containing all blocks

127

* @param blockId - Starting block ID (uses first block if not provided)

128

* @returns Array of all block IDs found on the page

129

*/

130

function getPageContentBlockIds(recordMap: ExtendedRecordMap, blockId?: string): string[];

131

```

132

133

**Usage Example:**

134

135

```typescript

136

import { getPageContentBlockIds } from "notion-utils";

137

138

// Get all block IDs for a page

139

const blockIds = getPageContentBlockIds(recordMap);

140

console.log(`Page contains ${blockIds.length} blocks`);

141

142

// Get blocks starting from specific block

143

const childBlockIds = getPageContentBlockIds(recordMap, "specific-block-id");

144

console.log(`Section contains ${childBlockIds.length} blocks`);

145

146

// Use block IDs to access individual blocks

147

blockIds.forEach(blockId => {

148

const block = recordMap.block[blockId]?.value;

149

if (block) {

150

console.log(`Block ${blockId}: ${block.type}`);

151

}

152

});

153

```

154

155

## Types

156

157

```typescript { .api }

158

// Re-exported from notion-types

159

interface ExtendedRecordMap {

160

block: Record<string, Block>;

161

collection?: Record<string, Collection>;

162

collection_view?: Record<string, CollectionView>;

163

notion_user?: Record<string, NotionUser>;

164

collection_query?: Record<string, any>;

165

signed_urls?: Record<string, string>;

166

preview_images?: Record<string, string>;

167

}

168

169

interface PageBlock extends Block {

170

type: "page";

171

properties?: {

172

title?: Decoration[];

173

};

174

format?: {

175

page_icon?: string;

176

page_cover?: string;

177

page_cover_position?: number;

178

page_full_width?: boolean;

179

page_small_text?: boolean;

180

};

181

}

182

183

// Navigation-specific types

184

interface TableOfContentsEntry {

185

id: string;

186

type: BlockType;

187

text: string;

188

indentLevel: number;

189

}

190

191

interface TraversalOptions {

192

concurrency?: number;

193

traverseCollections?: boolean;

194

targetPageId?: string;

195

maxDepth?: number;

196

}

197

198

type PageMap = Record<string, ExtendedRecordMap>;

199

type BlockType = 'header_1' | 'header_2' | 'header_3' | 'text' | 'bulleted_list' | 'numbered_list' | 'page' | /* ... many other block types */;

200

```