diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee5f11bcd..4aac71408 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@ and this project adheres to
### Changed
- ♿️(frontend) hide mobile left panel from screen readers when collapsed #2450
+- ♿️(frontend) enable blocknote heading ids for toc anchors #2449
## [v5.3.0] - 2026-06-19
diff --git a/src/frontend/apps/e2e/__tests__/app-impress/doc-table-content.spec.ts b/src/frontend/apps/e2e/__tests__/app-impress/doc-table-content.spec.ts
index 3f1766f32..e575fe93f 100644
--- a/src/frontend/apps/e2e/__tests__/app-impress/doc-table-content.spec.ts
+++ b/src/frontend/apps/e2e/__tests__/app-impress/doc-table-content.spec.ts
@@ -41,11 +41,11 @@ test.describe('Doc Table Content', () => {
const editorLevel2 = editor.getByText('Level 2');
const level3 = link3.getByText('Level 3');
- // TOC entries must be links with fragment hrefs
+ // TOC entries must be links with fragment hrefs pointing to block ids
await expect(link1).toBeVisible();
- await expect(link1).toHaveAttribute('href', /^#heading-/);
- await expect(link2).toHaveAttribute('href', /^#heading-/);
- await expect(link3).toHaveAttribute('href', /^#heading-/);
+ await expect(link1).toHaveAttribute('href', /^#.+/);
+ await expect(link2).toHaveAttribute('href', /^#.+/);
+ await expect(link3).toHaveAttribute('href', /^#.+/);
await expect(level1).toBeVisible();
await expect(editorLevel1).not.toBeInViewport();
diff --git a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx
index be47df3d6..5c9b2b1e2 100644
--- a/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx
+++ b/src/frontend/apps/impress/src/features/docs/doc-editor/components/BlockNoteEditor.tsx
@@ -240,6 +240,7 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
cellTextColor: true,
headers: true,
},
+ setIdAttribute: true,
uploadFile,
schema: blockNoteSchema,
},
@@ -341,6 +342,7 @@ export const BlockNoteReader = ({
},
provider: undefined,
},
+ setIdAttribute: true,
schema: blockNoteSchema,
extensions: [
CommentsExtension({
diff --git a/src/frontend/apps/impress/src/features/docs/doc-table-content/components/Heading.tsx b/src/frontend/apps/impress/src/features/docs/doc-table-content/components/Heading.tsx
index 9ceb987da..acc4ff53e 100644
--- a/src/frontend/apps/impress/src/features/docs/doc-table-content/components/Heading.tsx
+++ b/src/frontend/apps/impress/src/features/docs/doc-table-content/components/Heading.tsx
@@ -40,7 +40,7 @@ export const Heading = ({
return (
(`[data-id="${headingId}"]`)
- ?.scrollIntoView({
- behavior: 'smooth',
- inline: 'start',
- block: 'start',
- });
+ const blockEl = document.getElementById(headingId);
+ blockEl?.scrollIntoView({
+ behavior: 'smooth',
+ inline: 'start',
+ block: 'start',
+ });
}}
$radius="var(--c--globals--spacings--st)"
$background={