Fix duplicated live-preview frontmatter block rendering #242

Closed
opened 2026-06-02 20:08:32 +00:00 by steve · 0 comments
Owner

Fix the sporadic case where the markdown live-preview frontmatter block renders
twice for a single note, most visibly on plugin-markdown/Markdown Feature Tour.md in the e2e vault.

Problem

In live-preview mode, the frontmatter block can appear twice even though the
note contains only one YAML frontmatter section. The bug is sporadic and seems
to surface during live-preview widget refreshes rather than from duplicated note
content. The visible symptom is two .md-frontmatter blocks mounted in the
editor for the same note.

Goal

Ensure markdown live preview renders at most one frontmatter block per note,
including after note open, mode refreshes, and normal CodeMirror widget
rebuilds.

Scope

  • Investigate whether duplication begins in the CodeMirror block-widget pipeline
    or in the Svelte markdown renderer identity/lifecycle.
  • Apply the smallest fix in the markdown plugin to keep frontmatter rendering
    single-instance in live preview.
  • Add regression coverage that asserts exactly one live-preview frontmatter
    block is present for a note with YAML frontmatter.

Non-goals

  • Redesigning the frontmatter UI or changing reading-mode/file-properties
    behavior beyond what is necessary for this duplication fix.
  • Broad markdown renderer refactors unrelated to the frontmatter duplication
    path.

Acceptance Criteria

  • A markdown note with one YAML frontmatter block renders exactly one
    .md-frontmatter block in live-preview mode.
  • The single-block invariant holds after reopening the note or otherwise
    triggering the live-preview refresh path that previously exposed the bug.
  • The fix is covered by focused automated regression coverage.
  • Relevant markdown/workspace validation commands pass.

Implementation Notes

  • Start from the live-preview render path in
    packages/plugins/plugin-markdown/src/lib/codemirror-extensions/rich-editor/index.ts
    and packages/plugins/plugin-markdown/src/lib/renderer/contexts.svelte.ts.
  • First classify whether duplicate DOM comes from duplicate Frontmatter
    decorations or from stale renderer identity/lifecycle.
  • Current working hypothesis: renderer node identity is not stable enough during
    live-preview refreshes, which can let an old frontmatter subtree survive a
    widget rebuild.

Suggested Files or Specs To Inspect

  • packages/plugins/plugin-markdown/src/lib/codemirror-extensions/rich-editor/index.ts
  • packages/plugins/plugin-markdown/src/lib/renderer/Renderer.svelte
  • packages/plugins/plugin-markdown/src/lib/renderer/contexts.svelte.ts
  • packages/plugins/plugin-markdown/src/lib/components/frontmatter/file-frontmatter.svelte
  • packages/workspace/e2e/frontmatter-properties.spec.ts
  • spec/src/20-packages/plugins/markdown/index.md

Validation Commands

pnpm --filter @lapis-notes/markdown check:all
pnpm --filter @lapis-notes/workspace check:all
pnpm --filter @lapis-notes/workspace exec playwright test e2e/frontmatter-properties.spec.ts

Follow-up Tasks

Implementation Summary

Stabilized markdown renderer node identity and added a live-preview frontmatter regression that asserts a single .md-frontmatter block through editor refreshes.

Fix the sporadic case where the markdown live-preview frontmatter block renders twice for a single note, most visibly on `plugin-markdown/Markdown Feature Tour.md` in the e2e vault. ## Problem In live-preview mode, the frontmatter block can appear twice even though the note contains only one YAML frontmatter section. The bug is sporadic and seems to surface during live-preview widget refreshes rather than from duplicated note content. The visible symptom is two `.md-frontmatter` blocks mounted in the editor for the same note. ## Goal Ensure markdown live preview renders at most one frontmatter block per note, including after note open, mode refreshes, and normal CodeMirror widget rebuilds. ## Scope - Investigate whether duplication begins in the CodeMirror block-widget pipeline or in the Svelte markdown renderer identity/lifecycle. - Apply the smallest fix in the markdown plugin to keep frontmatter rendering single-instance in live preview. - Add regression coverage that asserts exactly one live-preview frontmatter block is present for a note with YAML frontmatter. ## Non-goals - Redesigning the frontmatter UI or changing reading-mode/file-properties behavior beyond what is necessary for this duplication fix. - Broad markdown renderer refactors unrelated to the frontmatter duplication path. ## Acceptance Criteria - A markdown note with one YAML frontmatter block renders exactly one `.md-frontmatter` block in live-preview mode. - The single-block invariant holds after reopening the note or otherwise triggering the live-preview refresh path that previously exposed the bug. - The fix is covered by focused automated regression coverage. - Relevant markdown/workspace validation commands pass. ## Implementation Notes - Start from the live-preview render path in `packages/plugins/plugin-markdown/src/lib/codemirror-extensions/rich-editor/index.ts` and `packages/plugins/plugin-markdown/src/lib/renderer/contexts.svelte.ts`. - First classify whether duplicate DOM comes from duplicate `Frontmatter` decorations or from stale renderer identity/lifecycle. - Current working hypothesis: renderer node identity is not stable enough during live-preview refreshes, which can let an old frontmatter subtree survive a widget rebuild. ## Suggested Files or Specs To Inspect - `packages/plugins/plugin-markdown/src/lib/codemirror-extensions/rich-editor/index.ts` - `packages/plugins/plugin-markdown/src/lib/renderer/Renderer.svelte` - `packages/plugins/plugin-markdown/src/lib/renderer/contexts.svelte.ts` - `packages/plugins/plugin-markdown/src/lib/components/frontmatter/file-frontmatter.svelte` - `packages/workspace/e2e/frontmatter-properties.spec.ts` - `spec/src/20-packages/plugins/markdown/index.md` ## Validation Commands ```bash pnpm --filter @lapis-notes/markdown check:all pnpm --filter @lapis-notes/workspace check:all pnpm --filter @lapis-notes/workspace exec playwright test e2e/frontmatter-properties.spec.ts ``` ## Related Issues - Follow-up to #65 — [Harden note-local frontmatter value editing and write semantics](../closed/65-harden-note-local-frontmatter-value-editing-and-write-semantics.md) ## Follow-up Tasks ## Implementation Summary Stabilized markdown renderer node identity and added a live-preview frontmatter regression that asserts a single .md-frontmatter block through editor refreshes. <!-- backlog:task_id=TASK-PLUGIN-LIVE-PREVIEW-FRONTMATTER-DUPE source_spec=spec/src/20-packages/plugins/markdown/index.md related_issue=65 -->
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lapis-notes/lapis#242
No description provided.