> ## Documentation Index
> Fetch the complete documentation index at: https://superdoc-caio-pizzol-sd-docs-snippet-typecheck-2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Navigation

> Scroll comments and tracked changes into view. Navigate by element id. Track nodes through edits.

The controller exposes navigation helpers for the everyday cases (scroll a comment or a tracked change into view, step through review). For raw element-id navigation and cross-session tracking, the host SuperDoc and the editor expose `scrollToElement` and `PositionTracker`.

## Comments and tracked changes

`ui.comments.scrollTo(id)` and `ui.trackChanges.scrollTo(id)` land on a specific entity. `ui.trackChanges.next()` and `previous()` advance `activeId` and return the new id, but they don't move the viewport on their own. Pair them with `scrollTo` to navigate.

```ts theme={null}
ui.comments.scrollTo('c-123');

const nextId = ui.trackChanges.next();
if (nextId) ui.trackChanges.scrollTo(nextId);
```

`ui.trackChanges.scrollTo` is story-aware: a tracked change in a header, footer, or footnote activates the right surface before alignment. `ui.comments.scrollTo` is body-scoped today; non-body comment scroll lands in a follow-up.

## Generic viewport scroll

`ui.viewport.scrollIntoView` accepts the same `target` shapes the doc-API uses (entity address, text address, text target). Pair it with `block` and `behavior`:

```ts theme={null}
await ui.viewport.scrollIntoView({
  target: { kind: 'entity', entityType: 'comment', entityId: 'c-123' },
  block: 'center',
  behavior: 'smooth',
});
```

See [Selection and viewport](/editor/custom-ui/selection-and-viewport#scroll-an-entity-into-view) for the full target list and the `not-mounted` / `not-ready` reasons.

## Navigate by element ID

`scrollToElement` takes any element ID: paragraph, comment, or tracked change: and scrolls to it. Use `doc.extract()` to get all IDs at once, or `query.match` for targeted lookups.

```javascript theme={null}
// Extract all content with stable IDs
const { blocks, comments } = editor.doc.extract();

// Navigate to any block
await superdoc.scrollToElement(blocks[0].nodeId);

// Navigate to a comment
await superdoc.scrollToElement(comments[0].entityId);
```

This is the approach to use for:

* **RAG citations**: store `nodeId` alongside embeddings, navigate on click
* **Cross-references**: link to specific paragraphs from external UI
* **Search results**: scroll to the matching paragraph
* **Cross-session addressing**: IDs from DOCX-imported content survive reloads

For the full extraction pattern, see [content extraction for RAG](/document-api/common-workflows#content-extraction-for-rag). For the cross-session pattern, see [cross-session block addressing](/document-api/common-workflows#cross-session-block-addressing).

## Track nodes during edits

When users edit a document, stored positions can drift. Use `PositionTracker` so navigation targets stay stable within the current session.

### Hyperlinks example

```javascript theme={null}
// 1) Find hyperlink nodes
const found = editor.doc.find({
  select: { type: 'node', nodeType: 'hyperlink', kind: 'inline' },
});

// 2) Track each found node
const links = found.items.map((item) => ({
  item,
  trackerId: editor.positionTracker.trackNode(item),
}));

// 3) Navigate later (for example, from a sidebar click)
function goToLink(link) {
  if (!link?.trackerId) return;
  editor.positionTracker.goToTracked(link.trackerId);
}
```

## Best practices

* Use `ui.comments.scrollTo` / `ui.trackChanges.scrollTo` for the everyday cases. They're the shortest path and they activate non-body surfaces correctly.
* Use `superdoc.scrollToElement` when you have a stable element id from `doc.extract()` or the Document API (RAG citations, cross-references, search hits).
* Use `editor.positionTracker` when you need to follow a node that moves during edits within the current session.
* For cross-session use, store `nodeId` values (not `sdBlockId`: those regenerate on each open).
* Handle missing targets gracefully: every API above returns `false` if the element no longer exists.
