Skip to content

fix(variable): stop React reconciling the editable font specimen#14

Draft
posthog[bot] wants to merge 1 commit into
mainfrom
posthog-code/fix-glyph-viewer-removechild
Draft

fix(variable): stop React reconciling the editable font specimen#14
posthog[bot] wants to merge 1 commit into
mainfrom
posthog-code/fix-glyph-viewer-removechild

Conversation

@posthog

@posthog posthog Bot commented Jul 27, 2026

Copy link
Copy Markdown

Summary

The glyph viewer's type specimen on /variable is a contentEditable region that rendered its placeholder text as a React child. When the browser mutates that editable subtree — typing, IME composition, or a page-translation extension — a later re-render makes React try to remove a text node that has moved out from under it, throwing NotFoundError: Failed to execute 'removeChild'. The div re-renders on every weight-slider move (its fontVariationSettings style changes) and on font switches, so the throw is easy to hit after any edit.

The fix seeds the placeholder once via dangerouslySetInnerHTML with a module-level constant. React never reconciles a dangerouslySetInnerHTML subtree while the string is unchanged, so it treats the editable region as opaque and stops competing with the browser for those nodes. suppressContentEditableWarning is dropped since there are no longer any React children.

Why

A caught production exception (removeChild NotFoundError) was reported on the /variable font tool. It surfaced in the blode.co PostHog project because this child app initializes PostHog with the same project token, but the root cause is here in apps/web/components/glyph-viewer.tsx. The two adjacent dynamic-DOM surfaces flagged for a look — build-tool.tsx (conditional subtree swaps) and font-preview.tsx (FontFace injection into a non-editable preview) — have no contentEditable and don't participate in this symptom, so they're left unchanged.

Test plan

  • npm run typecheck — passes
  • npm run check (ultracite format) — passes
  • Manual: type into the specimen, then move the weight slider / switch fonts — no removeChild exception; edited text and weight preview both persist.

Created with PostHog Desktop from this inbox report.

The glyph viewer's type specimen is a contentEditable region that rendered
its placeholder text as a React child. Once the browser mutates that
subtree (typing, IME, or a translation extension), a later render — every
weight-slider move rebuilds the div's style, and font switches re-render it
— makes React try to remove a text node that has moved out from under it,
throwing `NotFoundError: Failed to execute 'removeChild'`.

Seed the placeholder once via `dangerouslySetInnerHTML` with a constant
string so React treats the editable subtree as opaque and never reconciles
the nodes the browser is editing.

Generated-By: PostHog Code
Task-Id: 9b24f831-baed-47fe-a18a-0195e756a18f
@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
static-to-variable Ready Ready Preview, Comment Jul 27, 2026 10:45am

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants