WordPress 7.1 Is Coming. Are Your Custom Blocks Ready? ![rw-book-cover](https://d34adp677peecb.cloudfront.net/static/images/article2.74d541386bbf.png) ๐Ÿ”— **Source:** [WordPress 7.1 Is Coming. Are Your Custom Blocks Ready?](https://www.youtube.com/watch?v=4PrD1jzfD6E) > [!note]+ Document Notes > tags: [iframed-post-editor, block-development, wordpress-7-1, block-api-version-3, editor-styles, breaking-changes] > author: Ryan Welcher > source: Ryan Welcher (Automattic) > reference: https://www.youtube.com/watch?v=4PrD1jzfD6E > date created: 2026-08-01 12:10 > > > [!info] Generated analysis โ€” not the author's words. Sections below are machine-written > > from the captured source. Only text inside `> [!quote]` blocks is verbatim from the author. > > Do not quote or attribute any other line to the named author. > > # ๐Ÿท๏ธ Title: WordPress 7.1 is coming. Are your custom blocks ready? > <!-- deep-read:sections start --> ## ๐Ÿงญ Table of Contents - [๐Ÿ“ Summary](#-summary) - [๐Ÿ“– Main Content](#-main-content) - [๐Ÿ—’๏ธ Notes](#๏ธ-notes) - [๐Ÿ“š References](#-references) - [๐Ÿ—ฃ๏ธ Paraphrase](#๏ธ-paraphrase) - [๐Ÿ“ฐ Newsletter](#-newsletter) - [โœ… Action Items](#-action-items) - [๐Ÿงช Hypotheses](#-hypotheses) - [๐Ÿ“Š Methodology](#-methodology) - [โ“ Questions](#-questions) - [๐Ÿ”ฎ Future Research](#-future-research) - [๐Ÿ’ก Implications](#-implications) - [๐Ÿง  Learning Styles Assessment](#-learning-styles-assessment) - [๐Ÿ“Š Accessibility Assessment](#-accessibility-assessment) - [๐ŸŒ DEIB Assessment](#-deib-assessment) - [โœ… Logical Validity](#-logical-validity) - [๐Ÿ›ก๏ธ DARVO Analysis](#-darvo-analysis) - [๐ŸŽฏ Conclusion](#-conclusion) ### ๐Ÿ”— References - [Ryan Welcher](https://ryanwelcher.com/) โ€” developer advocate at Automattic; demo plugin linked in the video description - [Block API version 3](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-api-versions/) โ€” the `apiVersion` declaration discussed - [@wordpress/compose `useRefEffect`](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-compose/) โ€” the hook that replaces `useRef` + `useEffect` - [patch-package](https://www.npmjs.com/package/patch-package) โ€” the recommended fix for unmaintained dependencies ## ๐Ÿ“ Summary - **What happened.** Ryan Welcher (Automattic) demonstrates, with a purpose-built plugin containing broken and fixed versions of each case, exactly what the iframed post editor breaks in custom blocks โ€” and how to fix each one. WordPress 7.1 ships **August 19** and forces the iframe for everyone, on every theme, regardless of declared API version. - **Why it matters.** One root cause explains every bug shown: editor JavaScript loads in the admin page while block markup renders inside the iframe. Two documents, two windows, and the global `document` points at the wrong one. Every failure mode is **silent** โ€” no error, no warning, just wrong behavior, which Welcher correctly identifies as worse than an error. - **Key stakeholders.** Custom block developers and plugin authors; theme developers with editor CSS; anyone shipping a block with `apiVersion` below 3; the Gutenberg team watching 7.1 feedback; maintainers of third-party DOM libraries. - **Risks and tradeoffs.** The team may roll back to forcing the iframe only on block themes if feedback is bad. Welcher's counterintuitive and correct point: a rollback is a reason to act *sooner*, because it extends how long both worlds coexist. - **Bottom line.** The fixes are small โ€” often two lines, sometimes deleting code โ€” but they must be found before users find them. The single highest-value framing is that `apiVersion: 3` is a promise, not the work. ## ๐Ÿ“– Main Content **The one idea.** Welcher states it plainly and everything else follows: your editor JavaScript loads in the admin page, your block's markup renders inside the iframe, and those are two different documents with two different windows. "Your code is standing in one room. Your DOM is in the other room. And the global document points at the wrong room." Every bug in the video is a consequence. **The history, and why 7.1 is different.** Everything in the editor except the post editor has been iframed for years โ€” block previews, template editor, site editor, device previews; the site editor since day one. The gap has been closing across releases. In **6.3** core began iframing the post editor, but only if *every block registered on the site* was API version 3 โ€” including blocks never inserted, so one v2 block anywhere denied everyone the iframe. In **6.9** registering a block at API version 2 or lower produced a console warning under `SCRIPT_DEBUG`. In **7.0** the check narrowed to what is actually in the post: all v3 gets the iframe, one v2 removes it. In **7.1**, shipping August 19, everyone gets the iframe regardless of theme or declared API version. The caveat Welcher raises and then correctly disposes of: 7.1 is in testing, the team is watching feedback, and they have said they could pull back to forcing the iframe only on block themes. If that sounds like grounds to wait, "it's actually the opposite" โ€” a rollback keeps the non-iframed editor alive *longer*, so you ship into both worlds for more time, not less. Either way the job is identical: work in both. **Why core is doing this, argued rather than assumed.** Welcher makes the case for the change rather than treating it as an imposition. Admin CSS has leaked into the editor canvas forever, and core carries a large pile of style resets whose entire job is to "un-admin your content" and which only mostly work. A real document boundary ends that. Second, viewport units become meaningful: `vw`, `vh`, and media queries now resolve against the canvas rather than the surrounding admin screen, so the tablet preview is a real viewport and responsive styles actually respond. "The canvas finally behaves like a front end because structurally it basically is one." **Demo 1 โ€” the 7.0 compromise, visualized.** On stock 7.0, a demo block shows a pill indicating whether it is iframed (blue) or not (gray), and DevTools confirms `iframe name="editor-canvas"`. Inserting a single API v2 legacy block reloads the canvas, removes the iframe, and flips every pill to gray. Welcher's framing is precise: "Your v3 block did nothing wrong. It got dragged out of the frame with everybody else." The 7.0 behavior protects legacy blocks by changing the world for all of them; in 7.1 that rescue no longer happens and whatever the old block relied on is simply broken. **Demo 2 โ€” measuring the wrong window.** Two blocks report canvas width. The broken one asks `window.innerWidth`, which is the *admin* window because that is where the script loaded. Switching to tablet preview shrinks the canvas; the fixed block updates, the broken one "doesn't flinch," still confidently reporting full browser width. "No error, just wrong, which is worse than an error." The fix starts from the rendered element rather than the global: `element.ownerDocument` gives the document the block actually lives in, and `ownerDocument.defaultView` gives that document's window. Critically, this is version-agnostic โ€” un-iframed, `ownerDocument` is the admin document and everything behaves as before. Write it once and stop thinking about it. He also flags a subtler hook choice: use `useRefEffect` from `@wordpress/compose` rather than `useRef` plus `useEffect`. `useEffect` with an empty dependency array runs once, so if the editor remounts your block into a different document โ€” which it can โ€” your listener stays bound to the old window. `useRefEffect` reruns when the ref changes, so the listener follows the element. **Demo 3 โ€” the click-outside pattern, and "cannot reproduce."** A dropdown closes on outside click via a single listener on `document`. Opening works, because that is a React event and React is unaffected. But clicking another block in the canvas leaves it open, while clicking the toolbar or sidebar closes it. The cause: the listener is on the admin document, clicks in the canvas occur in the iframe's document, and **DOM events do not bubble across an iframe boundary, ever**. The listener hears the admin chrome and never hears the canvas. Welcher draws out the consequence that matters organizationally: this is where bug reports get closed as "cannot reproduce," because whoever tested was on a site where the editor wasn't iframed and it worked fine. The fix is the same `ownerDocument` move with `useRefEffect` โ€” a two-line diff. **Demo 4 โ€” styles loading into the wrong document.** Styling a block's editor UI via `enqueue_block_editor_assets` enqueues into the *admin page*. The stylesheet loads, returns 200 in the network tab, and does nothing, because the block is in a different document and CSS does not cross iframe boundaries either. His demo block loads two stylesheets โ€” green from `editorStyle` in `block.json`, red from `enqueue_block_editor_assets` โ€” and only the green one appears in the iframed editor, because WordPress injects `block.json`-registered styles into the canvas document whether iframed or not. The rule he states: `enqueue_block_editor_assets` styles the admin โ€” chrome, sidebar panels, custom plugin UI. `block.json` styles the canvas. If CSS is aimed at content, it goes through `block.json`. **Demo 5 โ€” the right document, the wrong selector.** Subtler and pure CSS. Editor styles scoped with `.wp-admin` โ€” which many developers wrote deliberately, to prevent editor styles leaking to the front end. Inside the iframe the canvas is its own clean document and its body carries no `wp-admin` class, so "the stylesheet is in the room and the selector is describing the other room." Un-iframed, the red border and banner appear; iframed, both vanish while the block still renders unstyled, because the text comes from JavaScript. The fix is deletion: drop the `wp-admin` prefix and describe your block. The same applies to admin-bar offsets, selectors keyed on `block-editor-page`, and the `!important` walls built to outshout leaking admin styles. "You're not porting those hacks into the canvas. You're deleting them because the thing they were fighting is gone." **Demo 6 โ€” third-party libraries, silently.** Masonry, sliders, lightboxes, maps โ€” "a whole generation of libraries written back when there was one document and everyone agreed on it." A stand-in library does what they all do: `document.querySelectorAll`, find targets, enhance. Inside the iframe it finds zero elements. No error, no warning; the block renders, the library runs, nothing happens. Three remedies, in order of preference. If the library accepts an element rather than a selector, hand it the element from `useRefEffect`. If it is unmaintained and hardcodes `document`, use **patch-package**: edit the module in `node_modules`, swap `document` for `node.ownerDocument`, run `npx patch-package` to generate a diff that reapplies on install, commit it, add the postinstall script. He notes the official migration guide walks through patching panzoom exactly this way. If the library loads inside the iframe as a front-end script, check for it on `defaultView` before calling and bail if absent. **The checklist, and the sharpest line in the video.** Get `apiVersion: 3` into every `block.json` โ€” but he is emphatic about what that is: "It's a promise, not the work. It tells WordPress, I'm iframe ready. You still have to actually be iframe ready." Then audit editor code for `window.` and `document.` โ€” every occurrence is a suspect. Move canvas styles from `enqueue_block_editor_assets` to `editorStyle`. Check editor CSS for `wp-admin`, `wp-admin-bar`, and `block-editor-page` selectors, most of which can simply go. Audit dependencies for element-vs-selector APIs and patch what must be patched. Finally, **test both ways**: Gutenberg 22.6 or later, or any 7.1 beta, for the iframe; stock 7.0 with a v2 block in the post for the version without. Both exist in the wild and will for a while. "Do it today. Don't find out from a support ticket in September." **Uncertainties and contested claims.** Whether the team actually rolls back to block-themes-only is unresolved. The August 19 date is a scheduled release date, subject to the usual slippage. The demos run largely on the Gutenberg plugin as a proxy for 7.1 behavior, which is stated but is a proxy nonetheless. ## ๐Ÿ—’๏ธ Notes #### โฑ๏ธ [00:00](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=0) The cold open - Same block, two editors. Dropdown closes on outside click in one; in the other it stays open when you click the canvas but closes when you click the sidebar. - "Nothing about the block changed. The only difference between these two editors is an iframe." - The stakes: in 7.1 "you stop getting a say in which one you get." #### โฑ๏ธ [00:30](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=30) Who and what - Ryan Welcher, developer advocate at Automattic. A companion plugin with broken and fixed versions of every demo is linked in the description. #### โฑ๏ธ [01:00](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=60) History โ€” everything else was already iframed - Block previews, template editor, site editor, and device previews have been iframed for years. The site editor since day one. - The post editor is the last holdout. #### โฑ๏ธ [01:20](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=80) 6.3 โ†’ 6.9 โ†’ 7.0 โ†’ 7.1 - **6.3**: core begins iframing the post editor, but only if *every registered block on the site* is API version 3 โ€” including blocks never inserted. One v2 block anywhere and nobody got the iframe. - **6.9**: registering a block at API version 2 or lower produces a console warning when `SCRIPT_DEBUG` is on. - **7.0**: the check narrows to what is actually in the post. All v3 โ†’ iframed. One v2 โ†’ no iframe. - **7.1, August 19**: everyone gets the iframe. "Every theme, block or classic, no matter what your API version says." #### โฑ๏ธ [02:20](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=140) The rollback caveat, inverted - 7.1 is in testing; the team is watching feedback and could pull back to forcing the iframe only on block themes. - The counterintuitive read: that is a reason to act sooner, not later. "A rollback keeps the non-iframed editor alive longer, so you're shipping into both worlds for more time, not less." - Demos use the Gutenberg plugin, which has enforced this for months. #### โฑ๏ธ [03:00](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=180) The one idea - Editor JavaScript loads in the admin page. Block markup renders inside the iframe. Two documents, two windows. - "Your code is standing in one room. Your DOM is in the other room. And the global document points at the wrong room." #### โฑ๏ธ [03:30](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=210) Why core is right to do it - Admin CSS has leaked into the canvas forever; core carries a pile of resets whose job is to "un-admin your content," and they only mostly work. A real document boundary ends that fight. - Viewport units now mean something: `vw`, `vh`, and media queries resolve against the canvas, not the admin screen. - In tablet preview "that's a real viewport now" and responsive styles actually respond. "The canvas finally behaves like a front end because structurally it basically is one." #### โฑ๏ธ [04:40](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=280) Demo 1 โ€” the pill indicator - Stock WordPress 7.0, no Gutenberg plugin. Demo blocks carry a pill: blue = iframed, gray = not. - The blocks detect which document they woke up in โ€” which is itself the technique taught in demo 2. - DevTools confirms `iframe name="editor-canvas"`. #### โฑ๏ธ [05:40](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=340) One v2 block changes the world - Inserting a single API v2 legacy block reloads the canvas, removes the iframe, and flips every pill to gray. - "Your v3 block did nothing wrong. It got dragged out of the frame with everybody else." - The 7.0 compromise protects legacy blocks by changing the environment for all blocks. In 7.1 the rescue is gone on any theme, and whatever the old block relied on is broken. #### โฑ๏ธ [07:00](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=420) Demo 2 โ€” the wrong window - Two blocks report canvas width. The broken one calls `window.innerWidth` โ€” the admin window, because that is where the script loaded. "Wrong room." - Switching to tablet preview: the fixed block updates; the broken one "doesn't flinch," still reporting full browser width. - "No error, just wrong, which is worse than an error." #### โฑ๏ธ [08:00](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=480) The `ownerDocument` fix - Start from the rendered element: `element.ownerDocument` is the document the block actually lives in; `ownerDocument.defaultView` is that document's window. - Version-agnostic by design โ€” un-iframed, `ownerDocument` is the admin document and behavior is unchanged. "Either way, you write it once and stop thinking about it." #### โฑ๏ธ [08:50](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=530) Why `useRefEffect`, not `useEffect` - `useEffect` with an empty dependency array runs once. If the editor remounts the block into a different document โ€” which it can โ€” the listener stays bound to the old window. - `useRefEffect` from `@wordpress/compose` reruns when the ref changes, so the listener follows the element. #### โฑ๏ธ [09:40](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=580) Demo 3 โ€” click-outside breaks - Standard pattern: one listener on `document` to close a dropdown on outside click. "Every React tutorial teaches this exact pattern. I have written this exact pattern many, many times." - Opening works because that is a React event. Clicking another block in the canvas leaves it open; clicking toolbar or sidebar closes it. #### โฑ๏ธ [10:30](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=630) Why โ€” events don't cross the boundary - The listener is on the admin document; canvas clicks happen in the iframe's document. **DOM events do not bubble across an iframe boundary, ever.** - The listener hears the admin chrome fine and never hears the canvas. #### โฑ๏ธ [11:00](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=660) "Cannot reproduce" - This is where bug reports get closed as unreproducible, because the tester was on a site where the editor wasn't iframed. "The classic works on my machine." - Fix: the same `ownerDocument` move with `useRefEffect`. "The diff is two lines. That's it. Two lines." #### โฑ๏ธ [11:40](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=700) Demo 4 โ€” styles in the wrong document - `enqueue_block_editor_assets` enqueues into the admin page. The stylesheet loads, returns 200, and does nothing, because CSS does not cross iframe boundaries either. - The demo block loads two stylesheets: green from `editorStyle` in `block.json`, red from `enqueue_block_editor_assets`. Only green appears when iframed. - WordPress injects `block.json`-registered styles into the canvas document, iframed or not. #### โฑ๏ธ [13:00](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=780) The rule - `enqueue_block_editor_assets` โ†’ the admin: chrome, sidebar panels, custom plugin UI. - `block.json` โ†’ the canvas. "If your CSS is aimed at content, it goes through block.json." #### โฑ๏ธ [13:40](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=820) Demo 5 โ€” right document, wrong selector - Pure CSS, no JavaScript needed to break it. Sneakier than demo 4: the stylesheet loads into the *right* document and still does nothing. - Setup: editor styles scoped with `.wp-admin`, which many wrote deliberately so editor styles couldn't leak to the front end. "Very responsible. We were being careful." - Inside the iframe the canvas body has no `wp-admin` class. "The stylesheet is in the room and the selector is describing the other room." #### โฑ๏ธ [14:40](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=880) The fix is deletion - Un-iframed: red border and banner appear. Iframed: both gone, block still renders unstyled because the text comes from JavaScript. CSS loaded fine; the selector matches nothing. - Fix: drop the `wp-admin` prefix and describe your block. Works in both worlds. #### โฑ๏ธ [15:20](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=920) Delete the rest of the admin furniture - Admin-bar offsets, selectors keyed on `block-editor-page`, and the `!important` walls built to outshout leaking admin styles. - "You're not porting those hacks into the canvas. You're deleting them because the thing they were fighting is gone." #### โฑ๏ธ [16:00](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=960) Demo 6 โ€” third-party libraries fail silently - Masonry, sliders, lightboxes, maps โ€” "a whole generation of libraries written back when there was one document and everyone agreed on it." - The pattern: `document.querySelectorAll`, find targets, enhance. Inside the iframe it finds zero elements. No error, no warning, nothing happens. Silent. #### โฑ๏ธ [17:00](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=1020) Three remedies - If the library accepts an element rather than a selector, pass the element from `useRefEffect`. - If unmaintained and hardcoding `document`: **patch-package**. Edit in `node_modules`, swap `document` for `node.ownerDocument`, run `npx patch-package`, commit the patch, add the postinstall script. The official migration guide patches panzoom exactly this way. - If it loads inside the iframe as a front-end script, check for it on `defaultView` before calling and bail if absent. #### โฑ๏ธ [18:20](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=1100) The checklist โ€” apiVersion 3 is a promise - Get `apiVersion: 3` into every `block.json`. One-line change, but: **"It's a promise, not the work. It tells WordPress, I'm iframe ready. You still have to actually be iframe ready."** - Audit editor code for `window.` and `document.` โ€” "every one you find is a suspect." Replace with `ownerDocument`, `defaultView`, `useRefEffect`. - Move canvas styles out of `enqueue_block_editor_assets` into `editorStyle`. - Check editor CSS for `wp-admin`, `wp-admin-bar`, `block-editor-page`. "Those selectors describe a document your block doesn't live in anymore. And most of them can just go." - Audit dependencies: elements not selectors, patch what you must. #### โฑ๏ธ [19:30](https://www.youtube.com/watch?v=4PrD1jzfD6E?t=1170) Test both ways - For the iframe: Gutenberg 22.6 or later, or any 7.1 beta. - For the version without: stock 7.0 with a v2 block in the post. - "Both of those exist in the wild right now, and they're going to for a while." - "Do it today. Don't find out from a support ticket in September." ## ๐Ÿ“š References - [Block API versions](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-api-versions/) โ€” what `apiVersion: 3` declares - [@wordpress/compose](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-compose/) โ€” `useRefEffect` - [block.json metadata reference](https://developer.wordpress.org/block-editor/reference-guides/block-api/block-metadata/) โ€” `editorStyle` vs enqueued assets - [patch-package](https://www.npmjs.com/package/patch-package) โ€” patching unmaintained dependencies - [Gutenberg plugin](https://wordpress.org/plugins/gutenberg/) โ€” 22.6+ enforces the iframe for testing - [WordPress 7.1 field guide / dev notes](https://make.wordpress.org/core/) โ€” the migration guide referenced - Ryan Welcher's demo plugin โ€” broken and fixed versions of every case, linked in the video description ## ๐Ÿ—ฃ๏ธ Paraphrase - The same block behaves differently in two editors, and the only difference is an iframe. - WordPress 7.1, shipping August 19, forces the iframe for everyone regardless of theme or declared API version. - Every part of the editor except the post editor has been iframed for years; the post editor is the last holdout. - 6.3 iframed the post editor only when every registered block was API version 3; 6.9 added console warnings; 7.0 narrowed the check to blocks actually in the post. - The team could roll back to block themes only, but that would extend the period during which both worlds exist, making early action more important rather than less. - The root cause of every bug is that editor JavaScript loads in the admin page while block markup renders inside the iframe, so the global document refers to the wrong one. - Core is right to make the change, because admin CSS has always leaked into the canvas and viewport units now resolve against the canvas as they should. - On 7.0, inserting one API v2 block removes the iframe for every block in the post, which protects legacy blocks by changing the environment for all of them. - A block asking `window.innerWidth` reports the admin window's width and fails silently, which is worse than erroring. - The fix is to start from the rendered element, using ownerDocument and defaultView, which behaves correctly whether or not the iframe exists. - `useRefEffect` should replace `useRef` with `useEffect`, because a listener bound once will not follow a block remounted into a different document. - The standard click-outside pattern breaks because DOM events never bubble across an iframe boundary, so a listener on the admin document never hears canvas clicks. - This produces bug reports closed as unreproducible, because testers on un-iframed sites see correct behavior. - Styles enqueued through `enqueue_block_editor_assets` load into the admin page and do nothing for canvas content, because CSS also does not cross the boundary. - Styles registered through block.json are injected into the canvas document whether iframed or not, so content styles belong there. - Editor CSS scoped with `.wp-admin` fails inside the iframe because the canvas body has no such class, and the fix is to delete the prefix. - Admin-bar offsets, `block-editor-page` selectors, and `!important` overrides written to fight leaking admin styles should be deleted rather than ported. - Third-party libraries using `document.querySelectorAll` find nothing inside the iframe and fail silently. - They can be fixed by passing elements instead of selectors, by patching hardcoded document references with patch-package, or by checking for the library on defaultView. - Setting apiVersion 3 is a declaration of readiness rather than the work of becoming ready. - Both the iframed and non-iframed editors exist in the wild and will for some time, so blocks must be tested in both. ## ๐Ÿ“ฐ Newsletter **`apiVersion: 3` is a promise, not the work.** WordPress 7.1 ships **August 19**, and it forces the iframed post editor on everyone โ€” every theme, block or classic, regardless of what your `block.json` says. Ryan Welcher's walkthrough is the most useful thing published on this, partly because he built [a plugin with broken and fixed versions of every case](https://ryanwelcher.com/) so you can reproduce each failure yourself. One idea explains every bug: **your editor JavaScript loads in the admin page, your block's markup renders inside the iframe.** Two documents, two windows, and the global `document` points at the wrong one. "Your code is standing in one room. Your DOM is in the other room." What that costs you, concretely: - **`window.innerWidth` lies.** It reports the admin window. Switch to tablet preview and your block doesn't flinch. "No error, just wrong, which is worse than an error." - **Click-outside handlers stop working.** DOM events *never* bubble across an iframe boundary, so a listener on `document` hears the sidebar and never hears the canvas. This is where you get bug reports closed as **cannot reproduce** โ€” the tester was on an un-iframed site. - **`enqueue_block_editor_assets` styles vanish.** The stylesheet loads, returns 200, and does nothing. CSS doesn't cross the boundary either. Content styles belong in `block.json` via `editorStyle`, which core injects into the canvas. - **Your careful `.wp-admin` scoping now matches nothing.** The canvas body has no `wp-admin` class. Same for admin-bar offsets, `block-editor-page` selectors, and every `!important` wall you built to outshout leaking admin styles. Good news: the fix is *deleting* them. "You're not porting those hacks into the canvas. You're deleting them because the thing they were fighting is gone." - **Third-party libraries fail silently.** Masonry, sliders, lightboxes, maps โ€” anything doing `document.querySelectorAll` finds zero elements. No error. Nothing happens. The fixes are genuinely small. `element.ownerDocument` and `ownerDocument.defaultView` instead of the globals โ€” and it works whether or not the iframe exists, so you write it once. Use `useRefEffect` from `@wordpress/compose` rather than `useRef` + `useEffect`, because a listener bound once won't follow your block if the editor remounts it into a different document. For stubborn dependencies, `patch-package`, swapping `document` for `node.ownerDocument`. One bit of reasoning worth stealing. The team might roll back to forcing the iframe only on block themes if feedback is bad โ€” and Welcher points out that's an argument for acting *sooner*: a rollback keeps the non-iframed editor alive longer, meaning you ship into both worlds for **more** time, not less. Either way, test both: Gutenberg 22.6+ or a 7.1 beta for the iframe, stock 7.0 with a v2 block for without. "Do it today. Don't find out from a support ticket in September." ## โœ… Action Items #### DevRel - Developer advocacy: this video *is* the model โ€” a plugin shipping broken and fixed versions of each case is far more useful than prose. Copy the format for other breaking changes. - Education: build the "two documents" mental model into every block-development curriculum; it explains six distinct bugs from one principle. - Developer experience: publish a codemod or lint rule flagging bare `window.` and `document.` in editor code โ€” the audit Welcher describes is mechanical. - Developer marketing: lead with the August 19 date and the silence of the failures; "no error, just wrong" is the motivating fact. - Community management: prepare triage guidance so "cannot reproduce" reports get an iframe question before closure. - Internal/external/cross-project: notify maintainers of commonly-bundled DOM libraries; the fix is upstreamable and benefits every consumer. #### OSPO - Policy & Governance: treat forced-environment changes like this as requiring a documented migration path and a stated rollback criterion โ€” both of which exist here and are worth codifying. - License Compliance: patch-package commits modified third-party code into your repository; confirm that is compatible with each dependency's license. - Security Management: patched dependencies bypass normal update paths โ€” track patched packages so security updates are not silently blocked by a stale patch. - Software Inventory: inventory which bundled front-end libraries hardcode `document`; that list is the migration backlog. - Developer Support: office hours before August 19 for teams with large block libraries. - Community Engagement: feed field reports back to the Gutenberg team while the rollback decision is still open. - Strategic Alignment: measure how many owned blocks still declare `apiVersion` below 3 โ€” a single, trackable readiness metric. #### Community - Maintainers: audit and ship fixes before the release, not after; the failure mode is silent and users will report it as your bug. - Contributors: this is an unusually good first-contribution area โ€” the diffs are two lines and mechanical. - Sponsors: fund migration work for widely-used blocks whose maintainers are inactive. - Ecosystem: coordinate a shared list of known-broken third-party libraries so each team does not rediscover them. #### WordPress - Core: consider a developer-facing warning when `document`/`window` access is detected in an iframed editor context, since every failure is currently silent. - Core Performance: measure any canvas-rendering cost difference from universal iframing. - Core AI: not applicable to this source. - **Core Program Team:** track the rollback decision explicitly; the "both worlds for longer" consequence needs to reach plugin authors either way. - Mobile: verify the mobile editor's document model against these assumptions. - Playground: **the highest-value item here** โ€” a Playground blueprint reproducing each of the six failures would let anyone test without a local build. - Community: run a pre-release block-audit workshop at meetups before August 19. - Training: turn the six demos into a Learn module; the broken/fixed plugin is the ready-made lab. - Marketing: not applicable to this source. - Support: prepare canned responses for "my block's styles disappeared" and "my dropdown won't close." - Design: the iframe makes device previews genuinely accurate โ€” worth surfacing to designers as a new capability, not just a migration. - Documentation: the `enqueue_block_editor_assets` vs `block.json` rule needs to be prominent in the block editor handbook, not buried in dev notes. - Photos: not applicable to this source. - TV: caption and chapter this video; each demo is a natural chapter. - Polyglots: not applicable to this source. - Accessibility: verify focus management and screen-reader behavior across the iframe boundary โ€” an accessibility dimension this video does not cover and which the boundary plausibly affects. - Meta: consider surfacing `apiVersion` in the plugin directory so users can see readiness. - CLI: a WP-CLI command auditing installed blocks for `apiVersion` below 3 would be straightforward and useful. - Hosting: hosts could proactively notify customers running blocks with `apiVersion` below 3. - Tide: `apiVersion` and bare `document`/`window` usage are both mechanically detectable โ€” natural scoring signals. - Openverse: not applicable to this source. - Themes: theme editor CSS scoped with `.wp-admin` or `block-editor-page` breaks the same way; audit theme editor styles too. - Plugins: **the directly applicable item** โ€” plugin review could flag `apiVersion` below 3 and bare global access in editor scripts. #### The WPOCC - Programs: fund migration help for community-maintained blocks whose authors have moved on. - Projects: maintain a shared registry of third-party libraries known to break inside the iframe, with the fix for each. - Funding experiments: sponsor a pre-release audit sprint; the work is mechanical, parallelizable, and time-boxed by the release date. ### FAIR - Technical independence: not directly discussed. - Policies and covenants: the stated rollback criterion ("if it causes real pain") is a good example of a change covenant, though it would be stronger with a measurable threshold. - Productized governance artifacts: the broken/fixed demo plugin is a reusable migration-artifact pattern worth generalizing to other breaking changes. ## ๐Ÿงช Hypotheses 1. Blocks declaring `apiVersion: 3` without an `ownerDocument` audit exhibit iframe-related defects at a similar rate to blocks declaring version 2 โ€” because the declaration is orthogonal to the work. 2. Silent failures produce longer mean time to detection than erroring failures, measured from release to first report. 3. Static analysis for bare `window.`/`document.` in editor scripts identifies most iframe-related defects without runtime testing. 4. A measurable share of "cannot reproduce" block bug reports filed between 7.0 and 7.1 are iframe-context mismatches. 5. Deleting admin-scoped CSS (`.wp-admin`, `block-editor-page`, `!important` overrides) reduces total editor stylesheet size without introducing front-end leakage. 6. Universal iframing improves the accuracy of device-preview rendering relative to front-end output. ### ๐Ÿ“Š Methodology - **H1:** Sample plugin-directory blocks by declared `apiVersion`, run each through a scripted iframe test harness, and compare defect rates. This directly tests Welcher's promise-not-work claim, which is currently rhetoric rather than measurement. - **H2:** Compare time-from-release-to-first-report for silent versus erroring defects using plugin support forum and Trac data. Confounder: severity correlates with both. - **H3:** Build the lint rule, run it against a corpus of blocks with known iframe defects, and measure precision and recall against manual audit. - **H4:** Retrospectively sample bug reports closed as unreproducible in the 7.0โ€“7.1 window and re-test each in both editor contexts. Cheap, and immediately actionable if the rate is high. - **H5:** Before/after stylesheet byte comparison plus front-end regression testing across a set of blocks that used admin scoping. - **H6:** Pixel-diff device previews against actual front-end rendering at matched viewports, pre- and post-iframe. This tests the benefit claim rather than the cost. ### โ“ Questions - Will the team roll back to block themes only, and what threshold of "real pain" triggers it? - Is there any legitimate reason to read the admin `window` from a block, and how would a lint rule distinguish it? - Does the iframe boundary affect focus management or screen-reader announcement, which the video does not address? - How many blocks in the plugin directory still declare `apiVersion` below 3? - Does `useRefEffect` fully solve the remount case, or are there remount paths it misses? - What happens to blocks that legitimately need to coordinate across both documents, such as those positioning UI relative to the admin chrome? - Is patch-package a sustainable answer at ecosystem scale, or does it push maintenance debt onto every consumer? - Does the canvas document inherit the admin's language and direction attributes correctly for RTL locales? ### ๐Ÿ”ฎ Future Research - Empirical study of silent versus loud failure modes in platform migrations, using this change as a case with a known date and a clean before/after. - Investigation of automated migration tooling for cross-document DOM access โ€” the transformations here are mechanical enough to codemod. - Accessibility research on iframe boundaries in editing interfaces, particularly focus order and assistive-technology traversal, which is unexamined here. - Analysis of how forced platform changes with stated rollback options affect ecosystem adoption timing, since Welcher's argument is that the rollback option perversely lengthens the migration window. - Study of third-party library assumptions about single-document contexts, which affects far more than WordPress. ### ๐Ÿ’ก Implications - **Practice.** The audit is mechanical and the diffs are small, but the failures are silent โ€” so the work must be scheduled, not discovered. August 19 is a hard forcing function. - **Policy.** A forced environment change shipped with a demo plugin, dev notes, a migration guide, and a stated rollback condition is close to best practice for breaking changes. The missing piece is machine-checkable readiness rather than a self-declared flag. - **Security.** patch-package is the recommended remedy for unmaintained dependencies, and it silently pins modified code. Teams adopting it need a process ensuring security updates are not blocked by stale patches. - **Education.** "Two documents, two windows" is a compact mental model that explains six distinct symptoms; teaching the model beats teaching the six fixes. - **Funding.** Widely-used blocks with inactive maintainers are the ecosystem's exposure here, and nobody is funded to fix them. ### ๐Ÿง  Learning Styles Assessment - Reading level estimate: **Flesch-Kincaid Grade โ‰ˆ 7.5**, Flesch Reading Ease โ‰ˆ 68. Deliberately plain sentences and short constructions. The prose is easy; the domain is not โ€” `ownerDocument`, `defaultView`, `useRefEffect`, `enqueue_block_editor_assets`, and `apiVersion` are all assumed. #### ๐Ÿ‘€ Visual learners - Present: outstanding. Side-by-side broken/fixed comparisons, a colored pill indicating iframe state, DevTools showing the actual iframe element, and live viewport switching. The pill is a particularly good teaching device โ€” it makes an invisible state visible. - Improve: a single diagram of the two-document model would anchor everything; the concept is currently carried by a verbal "two rooms" metaphor. #### ๐Ÿ”Š Aural learners - Present: clear narration with a stated thesis restated at each demo. - Improve: heavily visual content; an audio-only listener would struggle with the demos. A summary of the six failure modes and six fixes would help. #### ๐Ÿ—ฃ๏ธ Verbal learners - Present: the "two rooms" metaphor does real explanatory work, and "it's a promise, not the work" is the kind of line that survives the video. - Improve: a glossary of the API surface; the terms arrive fast and undefined. #### ๐Ÿงฉ Kinesthetic learners - Present: the strongest dimension, and unusually so. A companion plugin with broken *and* fixed versions of every case means viewers can reproduce each failure themselves. "Links in the description so you can break things right along with me." - Improve: pair it with a Playground blueprint so no local environment is needed. #### ๐Ÿง  Logical learners - Present: excellent structure โ€” one root cause, then six consequences derived from it, then a checklist. The release history is presented as a clean progression with the rule at each step. - Improve: a decision table mapping symptom โ†’ cause โ†’ fix would compress the whole video into a reference card. #### ๐Ÿง‘โ€๐Ÿคโ€๐Ÿง‘ Social learners - Present: a genuine call for comments about the weirdest iframe breakage, framed as collective knowledge-gathering rather than engagement bait โ€” "I know these bugs are out there and honestly, I love the weird ones the most." - Improve: point to a shared issue tracker or forum thread so the reports aggregate somewhere durable rather than in video comments. #### ๐Ÿง˜โ€โ™€๏ธ Solitary learners - Present: self-contained and reproducible alone; the plugin plus dev notes support independent work. - Improve: a self-check โ€” "can you name which of your blocks reads a global `window` or `document`?" #### ๐ŸŒฟ Naturalistic learners - Present: minimal. The closest thing is the deletion framing โ€” removing hacks rather than porting them, which is a genuine simplification argument. - Improve: nothing forced is needed here; this dimension is largely not applicable to a technical migration video, and inventing a connection would be worse than noting its absence. ### ๐Ÿ“Š Accessibility Assessment #### Screen reader semantics - Present: auto-captions exist. - Improve: caption accuracy garbles names and API terms โ€” "Ryan Welchure" (Welcher), "Automatic" (Automattic), "Goodenberg" (Gutenberg), "inq block editor assets" (`enqueue_block_editor_assets`), "use ref" for `useRefEffect`, "owner owner document," "Pasti was being careful." Mangling API names in a technical tutorial actively misleads. **WCAG 2.2 AA 1.2.2**. #### Keyboard navigation - Present: standard player controls. - Improve: six clearly demarcated demos with no chapter markers; this is the easiest possible chaptering job. **2.4.5 (Multiple Ways)**. #### Contrast and readability - Present: the pill indicators use color (blue/gray) but are paired with a text notice stating the same thing โ€” a correct redundant encoding. - Improve: code shown in DevTools and the editor is small on screen; zoom during code segments. **1.4.3**, **1.4.1 (Use of Color)** satisfied by the paired notice. #### Text resizing and reflow - Present: platform-level only. - Improve: publish the code snippets as text โ€” the fixes are two-line diffs that should be copy-pasteable rather than transcribed from video. The demo plugin partly addresses this. **1.4.4**. #### Media and captions - Present: captions, and narration that describes most actions. - Improve: the core evidence is visual โ€” a block "not flinching," pills flipping gray, a banner disappearing. These are described but the descriptions rely on the viewer seeing state change. Audio description or more explicit verbal state narration would help. **1.2.3 / 1.2.5**. - Product-side gap worth flagging: the video never addresses whether the iframe boundary affects focus management or assistive-technology traversal of the editor, which is a real accessibility question raised by the change itself. #### Forms and interactions - Not applicable to the video as media. For the *change* being described: the dropdown failure is precisely an interaction defect, and similar patterns (modals, popovers, focus traps) likely share it. **2.4.3 (Focus Order)**, **2.1.2 (No Keyboard Trap)** are worth auditing across the boundary. #### Standards reference - Media gaps: **1.2.2** (caption accuracy on API names), **1.2.3/1.2.5** (visually-carried evidence), **2.4.5** (no chapters). Product gap: focus and screen-reader behavior across the iframe boundary is unexamined โ€” **2.4.3**, **4.1.2**. ### ๐ŸŒ DEIB Assessment #### Cultural breadth - Present: neutral and unmarked; no culturally-specific references or idioms that would exclude non-US viewers. - Improve: the August 19 date is given without timezone or locale context, and "September" as the support-ticket month assumes a Northern-Hemisphere work calendar. Minor. #### Inclusive language - Present: consistently blame-free and inclusive of the audience's past choices. "A lot of us wrote this on purpose... Very responsible. We were being careful" explicitly absolves developers who scoped CSS to `.wp-admin`. "I have written this exact pattern many, many times" puts the presenter in the same position as the viewer. - Improve: the technical vocabulary is dense and undefined, which is a real barrier for less experienced block developers โ€” arguably the group most likely to be caught out by a silent breaking change. #### Neurodiversity support - Present: strong structural properties. One idea stated up front and referenced at each demo; consistent demo structure (show broken, explain why, show fix); a consolidated checklist at the end. Predictable and chunked. - Improve: no chapters despite six naturally-separable segments, and the pace is brisk with rapid screen changes. #### Representation - Present: credits are minimal but the framing is communal โ€” "we" throughout, and an invitation for viewers to contribute their own findings. - Improve: single-presenter format with no other voices; the affected community (plugin authors dealing with this) is addressed but not heard. No named contributors beyond the presenter. #### Psychological safety - Present: notably good, and it is a deliberate rhetorical strategy. He repeatedly normalizes having written the now-broken code: the `.wp-admin` scoping was "responsible," the click-outside pattern is what "every React tutorial teaches" and which he has written "many, many times." He names the social failure mode โ€” bug reports closed as "cannot reproduce" โ€” without blaming the person who closed them. The whole framing is "here is a change coming at you and here is how to survive it," not "you should have known." - Improve: "Don't find out from a support ticket in September" is a mild fear appeal. It is accurate and proportionate, but it is the one moment leaning on anxiety rather than capability. ### โœ… Logical Validity #### Strong reasoning - **Single cause, derived consequences, [03:00].** The strongest structural feature. One mechanism โ€” two documents, two windows, misdirected global โ€” is stated up front and then each of six symptoms is derived from it rather than presented as a separate gotcha. This is explanatory rather than enumerative, and it gives the viewer a model that predicts bugs not shown. - **Inverting the rollback argument, [02:20].** Genuinely counterintuitive and correct: a rollback to block-themes-only would extend the coexistence period, so the possibility of rollback increases rather than decreases the urgency of supporting both. Most presenters would treat the uncertainty as a caveat; he correctly identifies it as reinforcing his conclusion. - **Steelmanning the change, [03:30].** He argues *for* core's decision before demonstrating its costs โ€” leaking admin CSS, resets that "only mostly work," viewport units becoming meaningful. Establishing that a painful change is correct before detailing the pain is both honest and rhetorically stronger. - **Naming silence as the hazard, [07:00].** "No error, just wrong, which is worse than an error" identifies the actual risk property. A failure that announces itself is cheap; one that doesn't is expensive. This reframes urgency correctly. - **The promise/work distinction, [18:20].** "It's a promise, not the work" precisely separates a declaration from the state it declares. This is the single most useful line for anyone tempted to treat a one-line `block.json` change as completion. - **Diagnosing an organizational symptom from a technical cause, [11:00].** Connecting the iframe boundary to bug reports closed as "cannot reproduce" links a code-level fact to a process failure, which is a step most technical explainers never take. #### Fallacies - **Overgeneralization โ€” [15:20].** "Most of them can just go" about `wp-admin`, `block-editor-page`, and admin-bar selectors, and "you're deleting them because the thing they were fighting is gone." **Weakness:** true for canvas-targeted styles, but `enqueue_block_editor_assets` styling of genuine admin chrome โ€” sidebar panels, custom plugin UI, which he himself endorses at [13:00] โ€” legitimately still needs admin selectors. The blanket deletion advice contradicts his own earlier rule. **Fix:** scope the advice to canvas-targeted CSS explicitly. - **Understated cost โ€” [11:00] and [17:00].** "The diff is two lines. That's it. Two lines," and patch-package framed as "move on with your life." **Weakness:** the two-line diff is the fix once you have *found* the defect; discovery across a large block library is the actual cost and is not two lines. patch-package introduces ongoing maintenance โ€” patches break on dependency updates and can mask security fixes โ€” which is never mentioned. **Fix:** separate per-defect fix cost from per-codebase discovery cost, and note patch-package's maintenance burden. - **Appeal to consequences โ€” [19:30].** "Do it today. Don't find out from a support ticket in September." **Weakness:** the anticipated unpleasantness is offered as the reason to act rather than the technical argument, which is already sufficient. Mild and proportionate, but it is persuasion by anxiety where evidence was available. **Fix:** the silent-failure argument at [07:00] does this work better and honestly. - **Unstated assumption about proxy validity โ€” [02:20].** The Gutenberg plugin is used throughout "for simplicity" as a stand-in for 7.1 behavior. **Weakness:** he states the substitution but not that the plugin's behavior may diverge from what actually ships in 7.1, particularly given the rollback possibility he just described. Demos therefore evidence *plugin* behavior, presented as 7.1 behavior. **Fix:** note the divergence risk and recommend retesting against the beta. - **False precision โ€” [01:20].** The August 19 ship date is stated flatly. **Weakness:** WordPress release dates slip routinely, and 7.0 is described in this very video as having "kept getting pushed" in adjacent coverage. Presenting a scheduled date as fixed slightly overstates certainty. **Fix:** "scheduled for August 19." - **Hasty generalization โ€” [16:00].** "A whole generation of libraries written back when there was one document and everyone agreed on it." **Weakness:** many DOM libraries have long accepted element or context parameters precisely because of iframe and shadow-DOM use cases; the sweeping characterization overstates how widespread the assumption is. **Fix:** "many libraries," and note that element-accepting APIs are common enough that option one often suffices. #### Tone of voice - Brisk, practical, and deliberately non-judgmental about the audience's existing code. The dominant rhetorical move is self-inclusion โ€” he has written the broken patterns himself, the responsible-looking mistake was responsible, the React tutorial that taught it was not wrong at the time. The register is a colleague who tested this so you don't have to, and the companion plugin backs that up materially rather than rhetorically. Enthusiasm is reserved for the change itself being correct (the viewport-units segment is the most animated), which is notable given that he is delivering a breaking-change warning. Where the tone tightens is the checklist, which drops metaphor for imperatives. The one soft spot is the closing urgency appeal, which is mild and earned but is the only place he reaches for pressure rather than explanation. ### ๐Ÿ›ก๏ธ DARVO Analysis - **Deny:** Not present. The video's entire purpose is to surface breakage that could have been minimized or left for users to discover; it demonstrates the failures rather than downplaying them. - **Attack:** Not present. Notably, there is no blame directed at developers who wrote the now-broken patterns, at core for making the change, or at third-party library authors. The `.wp-admin` scoping is explicitly defended as having been responsible at the time. - **Reverse victim/offender:** Not present. Welcher speaks from Automattic โ€” an entity with a stake in the change โ€” and does not position developers as unreasonable for being inconvenienced, nor core as a victim of complaints. Responsibility for the disruption is acknowledged as core's decision while arguing it is correct, which is the opposite of a reversal. - **Emotional cues and rhetoric:** Reassurance and self-inclusion dominate. The one pressure move ("don't find out from a support ticket in September") is directed at motivating the audience's own benefit rather than deflecting criticism. - **Assessment:** No DARVO structure present. Recorded per template requirements rather than omitted. ## ๐ŸŽฏ Conclusion - **Bottom line.** WordPress 7.1 forces the iframed post editor on August 19, and one fact explains everything that breaks: editor JavaScript runs in the admin document while blocks render in the iframe, so bare `window` and `document` point at the wrong place. Six distinct failure modes follow โ€” wrong measurements, dead click-outside handlers, stylesheets that load and do nothing, selectors that match nothing, and third-party libraries that find zero elements โ€” and **every one of them fails silently**. The fixes are small: `ownerDocument`/`defaultView`, `useRefEffect`, canvas styles via `block.json`, and deleting admin-scoped CSS rather than porting it. The framing to keep is that `apiVersion: 3` is a declaration of readiness, not readiness itself. - **Next steps for readers.** - Grep your editor code for `window.` and `document.` today. Every hit is a suspect; the replacement is mechanical. - Move any content-targeted CSS out of `enqueue_block_editor_assets` into `editorStyle` in `block.json`, and delete `.wp-admin`, `block-editor-page`, and admin-bar selectors from canvas styles โ€” but keep them for genuine admin chrome, which the video's blanket advice glosses over. - Audit bundled front-end libraries for `document.querySelectorAll` patterns. Prefer element-accepting APIs; use patch-package only with a plan for keeping patches current. - Test in both contexts โ€” Gutenberg 22.6+ or a 7.1 beta for iframed, stock 7.0 with a v2 block for not โ€” and retest against the actual beta rather than trusting the plugin as a proxy. - If you triage bug reports, add "was the editor iframed?" before closing anything as unreproducible. ## ๐Ÿ”„ Refactor Appendix โ€” WordPress 7.1 is coming. Are your custom blocks ready? > Density: 2โ€“5 Literature atoms (H3), 0โ€“3 Permanent candidates (H4). > Defaults: 3 Literature, 1 Permanent. Resonance filter: if you can't > articulate in one line why a claim matters, drop it. > > Konik claim-header rules: present tense, declarative, โ‰ค10 words when > possible, searchable, unique, mirrors annotation focus if present. > > Atomicity: one declarative sentence per atom. "and"/"also" โ†’ split. > > Tag pool: #bmf ยท #addendum ยท #xref ยท #articleseed ยท #storystem ยท #share ยท #aphorisms ### ๐Ÿ“š Literature Atoms (H3) #### [H1] Declaring readiness is not becoming ready > [!quote] ID:rw_iframe_h1 > It&#x27;s a promise, not the work. **Context & use**: - [18:20] โ€” on setting `apiVersion: 3` in block.json - A one-line change tells WordPress you are iframe-ready; it does nothing to make you iframe-ready. The cleanest available statement of the gap between a declaration and the state it declares. **Tags**: #xref #share #aphorisms **Highlight**: [view highlight](readwise://) <!-- atomicity: 1 idea โœ“ --> #### [H2] Silent wrongness costs more than errors > [!quote] ID:rw_iframe_h2 > No error, just wrong, which is worse than an error. **Context & use**: - [07:00] โ€” a block reading `window.innerWidth` reports the admin window and never updates - Every failure mode in this change is silent. Names the actual risk property: a failure that announces itself is cheap to find, one that doesn't is expensive. **Tags**: #xref #share #aphorisms **Highlight**: [view highlight](readwise://) <!-- atomicity: 1 idea โœ“ --> #### [H3] Events never cross an iframe boundary > [!quote] ID:rw_iframe_h3 > DOM events do not bubble across an iframe boundary ever **Context & use**: - [10:30] โ€” why the standard click-outside pattern breaks - The listener on the admin document hears the sidebar and never hears the canvas. Directly explains bug reports closed as "cannot reproduce" โ€” the tester was on an un-iframed site. **Tags**: #xref **Highlight**: [view highlight](readwise://) <!-- atomicity: 1 idea โœ“ --> #### [H4] Start from the element, not the global > [!quote] ID:rw_iframe_h4 > element.ownerDocument gives you whatever document the block really lives in **Context & use**: - [08:00] โ€” the fix that resolves most of these bugs - Version-agnostic by design: un-iframed, `ownerDocument` is the admin document, so behavior is unchanged. Pairs with `useRefEffect` so listeners follow a remounted element. **Tags**: #xref #share **Highlight**: [view highlight](readwise://) <!-- atomicity: 1 idea โœ“ --> #### [H5] Defensive scoping became the defect > [!quote] ID:rw_iframe_h5 > the stylesheet is in the room and the selector is describing the other room **Context & use**: - [13:40] โ€” editor CSS scoped with `.wp-admin` matches nothing inside the canvas - The scoping was deliberate and responsible at the time. The fix is deletion, not migration โ€” the boundary the hacks were fighting now exists structurally. **Tags**: #xref #articleseed **Highlight**: [view highlight](readwise://) <!-- atomicity: 1 idea โœ“ --> ### ๐Ÿง  Permanent Candidates (H4) #### [P1] A compatibility flag records intent, not conformance **Claim** (one sentence, Courtney's voice): A self-declared readiness flag tells the platform what you intend, so treating it as evidence of conformance moves the verification burden onto the people the flag was supposed to protect. **Evidence pointer**: [[#H1]] **Scope & conditions**: Holds wherever a platform accepts a declaration in place of a check โ€” API version flags, feature-support manifests, compliance attestations. Breaks where the platform can mechanically verify the claim, in which case the flag is a cache of a check rather than a substitute for one. Weakens where the declaration carries a real cost or penalty for being wrong, which restores some signal. **Links**: - [[Gate Contributions on Demonstrated Comprehension Not on Tooling]] โ€” because extends: both distinguish a claim about work from evidence the work happened - [[Portability Is Proven by a Second Implementer Not by Design Intent]] โ€” because extends: both replace a stated property with an observed test of it - [[The Maker Should Not Grade Its Own Homework]] โ€” because applies-in: a self-declared flag is the maker grading itself - [[Update Signatures Prove Provenance Not Freshness]] โ€” because contrasts on what a given marker actually licenses you to conclude <!-- atomicity: 1 idea โœ“ --> #### [P2] Silent failures are more expensive than loud ones **Claim** (one sentence, Courtney's voice): A defect that produces wrong behavior without signalling costs more in total than one that crashes, because detection time dominates repair time. **Evidence pointer**: [[#H2]] > [!quote] > No error, just wrong, which is worse than an error. **Scope & conditions**: Holds where the wrong output is plausible enough to pass casual inspection and where the affected path is exercised by users rather than tests. Breaks where the loud failure is catastrophic and irreversible โ€” data loss, security compromise โ€” in which case crashing later is worse than being quietly wrong now. Also breaks where silence is detectable cheaply by monitoring, which converts it into a loud failure. **Links**: - [[The Maker Should Not Grade Its Own Homework]] โ€” because extends: independent checking exists to surface what silence hides - [[A Nondeterministic Check Breaks the Loops Stop Condition]] โ€” because contrasts on how a check fails - [[Expert review failure disproves user-review as defense]] โ€” because applies-in: silent malicious updates are the security instance of this <!-- atomicity: 1 idea โœ“ --> ### โœ๏ธ Fleeting Queue - [F1] Grep my own blocks and any client blocks for bare `window.` / `document.` before August 19. Mechanical, and the failures are silent. #fleeting #inbox - [F2] A Playground blueprint reproducing all six iframe failures would be a genuinely useful teaching artifact โ€” nobody has built one. #articleseed #fleeting #inbox - [F3] Accessibility question the video never asks: does the iframe boundary affect focus order and screen-reader traversal of the editor? #fleeting #inbox - [F4] patch-package pins modified dependency code โ€” check it doesn't silently block security updates. Welcher doesn't mention this cost. #fleeting #inbox - [F5] "It's a promise, not the work" generalizes well past WordPress โ€” compliance attestations, SBOM declarations, accessibility statements. #articleseed #fleeting #inbox - [F6] Note the contradiction: he says delete `.wp-admin` selectors, but his own rule keeps `enqueue_block_editor_assets` for admin chrome, which legitimately needs them. #fleeting #inbox ### โ†’ Things 3 (max 2 actions) - [ ] Audit all owned blocks for bare window/document access and wp-admin-scoped editor CSS before WordPress 7.1 on August 19 โ€” block migration #things - [ ] Test blocks in both editor contexts: Gutenberg 22.6+ for iframed, stock 7.0 with a v2 block for not โ€” regression check #things <!-- deep-read:sections end --> ๐Ÿ“„ **Full text:** [[Full Document Contents/Articles/WordPress 7.1 Is Coming. Are Your Custom Blocks Ready.md|WordPress 7.1 Is Coming. Are Your Custom Blocks Ready? by Ryan Welcher]] ## Highlights - I've got two blocks here and they've got one job. Tell me how wide the canvas is. The broken one asks window.innerWidth, which seems reasonable, right? Except the script's loaded in the admin page. So that's the admin window. Wrong room. So watch what happens when I switch to the tablet preview. The canvas shrinks and the fixed block updates. The broken block doesn't flinch. It's still confidently reporting my full browser width like nothing happened. No error, just wrong, which is worse than an error. ([View Highlight](https://read.readwise.io/read/01kyytp2xwgre4js4pmqmtjk9g)) - Note: [H2] Silent wrongness costs more than errors. EVERY failure mode in this change is silent. Names the actual risk property โ€” a failure that announces itself is cheap to find; one that doesn't is expensive. Seeds Permanent candidate P2. - Tags: atom/zettel/z1, iframed-post-editor, atom/literature/h1 - Honestly, the fix is small. Instead of the global window, you start from the element you actually rendered. element.ownerDocument gives you whatever document the block really lives in. And ownerDocument.defaultView gives you that document's window. And the nice part is this code doesn't care whether the iframe exists. If you're not iframed, ownerDocument is the admin document and everything works like it always did. If you are, you get the iframe's window. Either way, you write it once and stop thinking about it. ([View Highlight](https://read.readwise.io/read/01kyytprn8zjvwqyn1nx741rcc)) - Note: [H4] Start from the element, not the global. The fix that resolves most of these bugs, and it's version-agnostic โ€” un-iframed, ownerDocument IS the admin document. Pair with useRefEffect so listeners follow a remounted element. - Tags: atom/literature/h1, block-development, iframed-post-editor - So the dropdown opens fine because that's a React event and React doesn't care about any of this. But if I click another block in the canvas, it stays open. Click the toolbar or the sidebar, it closes. That makes no sense. Here's why. The listener is on the admin document. Clicks inside the canvas happen in the iframe's document and DOM events do not bubble across an iframe boundary ever. So the listener never hears the canvas, but it hears the admin chrome just fine. ([View Highlight](https://read.readwise.io/read/01kyytpctgt6t1sy0q81pm7pzf)) - Note: [H3] Events never cross an iframe boundary. Why the standard click-outside pattern breaks. Directly explains bug reports closed as "cannot reproduce" โ€” the tester was on an un-iframed site. - Tags: atom/literature/h2, iframed-post-editor, block-development - Here's the setup. This block's editor styles are scoped with .wp-admin. And a lot of us wrote this on purpose. We scoped it to the admin body class so our editor styles couldn't possibly leak into the front end. Very responsible. We were being careful. But inside the iframe, the canvas is its own clean document and its body has no wp-admin class. So now the stylesheet is in the room and the selector is describing the other room. ([View Highlight](https://read.readwise.io/read/01kyytq1fjqz7mh1ax2es0dama)) - Note: [H5] Defensive scoping became the defect. The .wp-admin scoping was deliberate and responsible at the time. Fix is deletion, not migration. CAVEAT his blanket advice: enqueue_block_editor_assets styling of genuine admin chrome legitimately still needs admin selectors. - Tags: atom/literature/h2, breaking-changes, editor-styles - Okay, the checklist. First thing, get API version 3 into every block.json. It's a one-line change, but let's be clear about what it is. It's a promise, not the work. It tells WordPress, I'm iframe ready. You still have to actually be iframe ready. Then take a look through your editor code for window dot and document dot. Every one you find is a suspect. ownerDocument, defaultView, useRefEffect. ([View Highlight](https://read.readwise.io/read/01kyytns8jjswezcftxf226r1q)) - Note: [H1] Declaring readiness is not becoming ready. apiVersion:3 tells WordPress you're iframe-ready; it does nothing to make you iframe-ready. Cleanest statement of the gap between a declaration and the state it declares. Seeds Permanent candidate P1. - Tags: atom/literature/h1, atom/zettel/z1, block-api-version-3