Conversation
…itor
The inline editor used by visual editing (`InlinePortableTextEditor`) had
two bugs that combined into silent data loss:
1. PT → PM coerced unknown block types into a `pluginBlock` ProseMirror
node carrying only `{ blockType, id }`, dropping every other field.
2. The `pluginBlock` node type was never registered as a TipTap extension,
so ProseMirror's schema silently filtered the node out on load.
3. PM → PT serialised back as `{ _type, _key, id }`, persisting the loss.
For a `marketing.hero` block with seven fields, opening the page in edit
mode and pressing save would persist `{ _type, _key, id: "" }` -- the
block's content gone.
Fixes:
- Register a minimal `pluginBlock` TipTap node so ProseMirror accepts it.
Renders as a read-only placeholder ("Plugin block: <type> (edit in
admin)") with dashed border styling. Editing plugin blocks remains an
admin-side feature; the visual editor just preserves them.
- Capture every non-well-known field into a `data` attribute on PT → PM
(filtering `_`-prefixed keys to prevent accumulation), and spread it
back out on PM → PT. Mirrors the lossless pattern in the admin editor
(PortableTextEditor.tsx:572-588 and :298-305).
- Hide the `blockType`, `id`, and `data` attrs from DOM rendering so
they live only on the PM node (no `data="[object Object]"` leakage).
Tests: 10 new unit tests covering both directions plus full PT → PM → PT
round-trips for marketing.hero-shaped blocks, nested objects, and
repeated round-trips (no `_`-key accumulation).
🦋 Changeset detectedLatest commit: 139fed6 The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-perf-coordinator | 139fed6 | Apr 28 2026, 11:56 AM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
docs | 139fed6 | Apr 28 2026, 11:56 AM |
@emdash-cms/admin
@emdash-cms/auth
@emdash-cms/blocks
@emdash-cms/cloudflare
emdash
create-emdash
@emdash-cms/gutenberg-to-portable-text
@emdash-cms/x402
@emdash-cms/plugin-ai-moderation
@emdash-cms/plugin-atproto
@emdash-cms/plugin-audit-log
@emdash-cms/plugin-color
@emdash-cms/plugin-embeds
@emdash-cms/plugin-forms
@emdash-cms/plugin-webhook-notifier
commit: |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-demo-cache | 139fed6 | Apr 28 2026, 11:58 AM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-playground | 139fed6 | Apr 28 2026, 11:58 AM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
emdash-i18n | 139fed6 | Apr 28 2026, 11:58 AM |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Fixes silent data loss in the visual-editing inline editor (
InlinePortableTextEditor) for plugin-contributed Portable Text block types.The bug
For any unknown PT block type (e.g.
marketing.herowithheadline/subheadline/CTAs etc.), opening a page in visual edit mode silently destroyed every field exceptid. Combined with the absence of a registeredpluginBlockTipTap node, ProseMirror also filtered the node out of the document on load -- and the next save persisted the disappearance.A
marketing.heroblock with seven fields became{ _type, _key, id: "" }after a single edit-mode visit + save.The fix
Three small changes, all in
packages/core/src/components/InlinePortableTextEditor.tsx:pluginBlockTipTap node so ProseMirror accepts it on load instead of filtering. Atom +selectable: true+draggable: true. Renders as a read-only placeholder ("Plugin block: marketing.hero (edit in admin)") with dashed border styling.dataattribute on PT → PM (filtering_-prefixed keys to prevent accumulation across edit cycles).databack out on PM → PT so the block round-trips losslessly.This mirrors the lossless pattern already in the admin editor at
PortableTextEditor.tsx:572-588(PT → PM) and:298-305(PM → PT). Closely related to #646's diagnosis, which correctly identified the bug for the inline editor specifically -- this PR ports the round-trip half of that proposal. Editing in visual mode remains intentionally out of scope (admin is the editing surface; visual editing just needs to not destroy data).DOM attributes (
blockType,id,data) are hidden from the rendered DOM viarendered: falseso they live only on the PM node. Otherwise serialised<div data="[object Object]" ...>would leak into the page.Type of change
Checklist
pnpm typecheckpassespnpm lintpasses (4 pre-existing diagnostics inpackages/blocks/src/validation.ts, unchanged from main)pnpm testpasses (4498 tests across all packages)pnpm formathas been runtests/unit/components/inline-portable-text-plugin-block.test.tscovering PT → PM, PM → PT, and full round-trip including amarketing.hero-shaped block, nested objects, and repeated round-tripsAI-generated code disclosure
Screenshots / test output
Verified end-to-end with the marketing template's home page on the
feat/marketing-template-editable-blocksbranch (which has the marketing-blocks plugin):/shows nothing where the four marketing blocks should be -- they've been silently filtered. Next save would persist the disappearance.