You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Storage: TipTap JSON in a json column, AsBlockDocument cast (sanitizes on set for its profile; reads Document, empty for null; serializes to the array for Inertia).
Validation: BlockContent rule (structure via content expressions, profile, marks, attribute rules, depth, required(), maxBlocks()). Errors go on the field (Block 3 (Button): …) and on the JSON path (body.content.2.attrs.url), which the editor shows on the block.
Sanitizing: unknown, disallowed and misplaced nodes and marks are dropped, attributes are cast, URLs are checked (including java\tscript:), and HTML blocks go through symfony/html-sanitizer. It runs on save and again on render.
Rendering: Blade views per block (<x-block-editor::content>, {{ $doc }}) and React BlockContent. Both are checked against the same fixtures in tests/Fixtures/content, so the markup is identical.
Activity
PHP block classes, registry, sanitizing, validation and Blade rendering
TipTap editor core, Blade entry and React renderer
n4ff4h commentedon Nov 5, 2026
Done on
main.AsBlockDocumentcast (sanitizes on set for its profile; readsDocument, empty for null; serializes to the array for Inertia).BlockContentrule (structure via content expressions, profile, marks, attribute rules, depth,required(),maxBlocks()). Errors go on the field (Block 3 (Button): …) and on the JSON path (body.content.2.attrs.url), which the editor shows on the block.java\tscript:), and HTML blocks go through symfony/html-sanitizer. It runs on save and again on render.<x-block-editor::content>,{{ $doc }}) and ReactBlockContent. Both are checked against the same fixtures intests/Fixtures/content, so the markup is identical.