If you build custom WordPress blocks, you have probably seen more talk about the iframed editor and Block API v3. It sounds technical, but the idea is simple: WordPress wants the editor canvas to behave more like the real front end of the site, with fewer style conflicts from the admin screen.
That is a good thing. It means blocks can look more accurate in the editor, theme styles can behave more naturally, and the editing experience becomes cleaner over time. But for older custom blocks, especially blocks still using Block API v1 or v2, the shift can expose small problems that were easy to miss before.
The most common issues are not dramatic. A script looks for the wrong document. A library expects the admin window instead of the iframe window. Editor styles were loaded in the wrong place. A block preview works on the front end but looks broken inside the editor. A click handler works outside the iframe but fails once the block is rendered inside the iframe canvas.
This guide explains what the enforced iframed editor means, why WordPress is pushing blocks toward apiVersion: 3, and how to update blocks from Block API v2 to v3 without turning a small compatibility task into a full rewrite.
TL;DR
```To prepare custom WordPress blocks for the iframed editor, update the block’s apiVersion to 3, test the block inside the iframe editor, fix any direct use of global document or window, load editor styles properly, and check the block in posts, pages, templates, patterns, mobile previews, and reusable/synced pattern contexts.
- Main change: Block API v3 tells WordPress your block is ready for the iframe editor.
- Main benefit: fewer admin-style conflicts and more accurate editor previews.
- Main risk: scripts that depend on global
windowordocumentmay target the wrong place. - Best fix: use a block element ref, then access
ownerDocumentanddefaultView. - Do not just bump the version blindly: change it, test it, then release it.
- Best workflow: update on a development branch, test in staging, check console errors, then ship.
What Is the Iframed Editor?
The iframed editor means the editable content canvas inside WordPress runs inside an iframe instead of directly inside the main admin page.
Think of it like this:
- The WordPress admin interface is one document.
- The editor content canvas is another document inside an iframe.
- Your block appears inside that iframe canvas.
This separation helps WordPress make the editor feel closer to the real site. Admin CSS is less likely to leak into the content area, and content styles are less likely to interfere with the admin UI.
For site owners, this should eventually mean a more consistent editor. For developers, it means older assumptions about the editor environment need to be checked.
Why WordPress Is Moving Toward the Iframed Editor
Before the iframe approach, the post editor and the admin interface shared more of the same environment. That created a familiar but messy problem: admin styles, plugin styles, editor styles, and theme styles could all affect each other.
The iframe editor helps with:
- Style isolation: admin CSS should not accidentally change the look of block content.
- Better layout accuracy: the editor can look closer to the front end.
- Cleaner theme styling: theme styles can be used more naturally inside the editor.
- Viewport units: CSS such as
vwandvhbehaves more predictably. - Media queries: responsive behavior becomes easier to reason about.
- Less CSS fighting: developers spend less time undoing unwanted admin styles.
In short, the iframe makes the editor canvas more independent. That independence is good, but it also means blocks must stop assuming that the editor content lives in the same document as the admin page.
What Is Block API v3?
Block API versions tell WordPress which block behavior model your block supports. Older custom blocks may use API v1 or v2. Newer blocks should use API v3.
For most block authors, the visible change is small:
{
"apiVersion": 3,
"name": "example/custom-block",
"title": "Custom Block"
}
But that small setting has an important meaning. It tells WordPress that the block is expected to work in the iframed editor environment.
The upgrade from v2 to v3 is often simple, but it should never be treated as a blind find-and-replace. The safer mindset is:
“Bump the API version, then test the block in the iframe editor like a real editor would use it.”
Block API v2 vs v3: What Actually Changes?
For many blocks, the jump from v2 to v3 does not require a full rebuild. A simple static block that uses normal block props, editor styles, and no custom DOM scripting may work after changing apiVersion to 3.
The problems usually appear in more interactive blocks.
| Area | Block API v2 Habit | Block API v3 / Iframe-Friendly Habit |
|---|---|---|
| API version | "apiVersion": 2 |
"apiVersion": 3 |
| DOM access | Use global document or window |
Use the block element’s ownerDocument and defaultView |
| Event listeners | Attach events to the parent admin window | Attach events through the element that lives inside the iframe |
| Editor styles | Rely on admin/editor CSS leakage | Load styles intentionally through block metadata or editor assets |
| Third-party libraries | Assume libraries can find the global page document | Initialize libraries with the actual block element when possible |
| Testing | Check only normal post editor view | Check posts, templates, synced patterns, mobile preview, and iframe mode |
When Should You Update Blocks to API v3?
You should update now if you maintain custom blocks, agency blocks, client-specific blocks, internal plugin blocks, or premium plugin blocks that still use apiVersion: 2.
This is especially important if your block:
- Uses custom JavaScript inside the editor.
- Uses sliders, carousels, maps, charts, tabs, accordions, or animations.
- Directly accesses
windowordocument. - Uses jQuery or a third-party DOM library.
- Depends on editor-only CSS.
- Has a custom preview inside the editor.
- Uses synced patterns or reusable blocks.
- Appears inside templates or the Site Editor.
- Is distributed to client websites through a plugin.
If your block is already simple and static, the update may be quick. If it has interactive editor behavior, give yourself time to test properly.
Step 1: Find Blocks Still Using API v2
Start by searching your plugin or theme for apiVersion.
Common places include:
block.jsonregisterBlockType()- PHP block registration files
- Build-generated block folders
In most modern blocks, you will see something like this inside block.json:
{
"apiVersion": 2,
"name": "brand/feature-card",
"title": "Feature Card",
"category": "design"
}
Make a list of every block still using version 1 or 2. Do not update all of them blindly in one commit. If possible, update and test one block group at a time.
Step 2: Change apiVersion from 2 to 3
The basic change is simple:
{
"apiVersion": 3,
"name": "brand/feature-card",
"title": "Feature Card",
"category": "design"
}
If your block is registered directly in JavaScript, it may look like this:
registerBlockType( 'brand/feature-card', {
apiVersion: 3,
title: 'Feature Card',
edit,
save,
} );
After this change, rebuild your block assets if your project uses a build step:
npm run build
Then test the block in WordPress. The version bump is only the first step, not the full migration.
Step 3: Test the Block Inside the Iframed Editor
Now test the block in the contexts where it actually appears.
Check:
- A normal post.
- A normal page.
- A template in the Site Editor.
- A template part if the block is used in headers or footers.
- A synced pattern or reusable block.
- Desktop editor view.
- Tablet and mobile preview.
- Zoomed-out editing mode if used.
Do not just insert the block and save. Actually use it. Change settings. Add inner blocks. Click buttons. Open side panels. Test media selection. Change alignment. Remove it. Duplicate it. Copy and paste it. Save and reload the editor.
A block is not iframe-compatible until it works like a real editor expects it to work.
Step 4: Fix document and window Issues
This is the most important technical change.
In the iframe editor, the block content is inside a different document from the parent WordPress admin page. So if your editor script uses global document or window, it may be looking at the wrong place.
Risky pattern:
useEffect( () => {
window.addEventListener( 'resize', handleResize );
const element = document.querySelector( '.my-block' );
return () => {
window.removeEventListener( 'resize', handleResize );
};
}, [] );
Better pattern:
import { useRefEffect } from '@wordpress/compose';
import { useBlockProps } from '@wordpress/block-editor';
export default function Edit() {
const ref = useRefEffect( ( element ) => {
const { ownerDocument } = element;
const { defaultView } = ownerDocument;
const handleResize = () => {
// Measure or update this block safely.
};
defaultView.addEventListener( 'resize', handleResize );
return () => {
defaultView.removeEventListener( 'resize', handleResize );
};
}, [] );
const blockProps = useBlockProps( { ref } );
return (
<div { ...blockProps }>
Block content
</div>
);
}
The friendly rule is this: start from the block element, not the global page.
Once you have the actual block element, you can reach the correct document and window for the iframe environment.
Step 5: Update Third-Party Library Initializers
Many custom blocks use third-party libraries for sliders, charts, maps, masonry layouts, animations, tabs, or interactive previews.
These libraries often expect a DOM element. That is fine. What causes trouble is when the library internally assumes the global document or window belongs to the content area.
Better initialization pattern:
const ref = useRefEffect( ( element ) => {
const instance = createLibraryInstance( element, {
// Library options here.
} );
return () => {
instance.destroy();
};
}, [] );
Try to pass the actual block element into the library. Avoid asking the library to find the block with document.querySelector() unless you are certain it is using the right document.
If a library is not iframe-aware, you may need to:
- Update the library.
- Initialize it with a specific element.
- Patch the library to use
ownerDocument. - Use a simpler editor preview.
- Render the full interactive behavior only on the front end.
Step 6: Check Editor Styles
Some older blocks looked correct in the editor because their styles accidentally leaked from the admin page or from a broad stylesheet. The iframe editor makes this less reliable.
Make sure your block styles are registered intentionally.
A typical block.json setup may include:
{
"apiVersion": 3,
"name": "brand/feature-card",
"title": "Feature Card",
"editorScript": "file:./index.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css"
}
Use:
editorStylefor styles needed only inside the editor.stylefor styles shared on the front end and editor where appropriate.viewScriptor frontend scripts only when the front end needs behavior.
Do not rely on broad admin CSS to style block content. The iframe editor is specifically designed to reduce that kind of leakage.
Step 7: Check Block Wrapper Markup
Block API v3 expects blocks to behave well with the modern block wrapper system. Make sure you are using useBlockProps() in the editor and matching wrapper behavior in save() where needed.
Editor example:
import { useBlockProps } from '@wordpress/block-editor';
export default function Edit() {
const blockProps = useBlockProps();
return (
<section { ...blockProps }>
Block content
</section>
);
}
Save example:
import { useBlockProps } from '@wordpress/block-editor';
export default function save() {
const blockProps = useBlockProps.save();
return (
<section { ...blockProps }>
Saved block content
</section>
);
}
This keeps WordPress classes, supports, spacing, layout, alignment, and style output more predictable.
Step 8: Test Block Supports
After moving to API v3, test any block supports you expose in block.json.
Common supports include:
- Alignment.
- Spacing.
- Color.
- Typography.
- Layout.
- Dimensions.
- Border.
- Anchor.
- HTML editing.
For example:
{
"supports": {
"align": [ "wide", "full" ],
"spacing": {
"margin": true,
"padding": true
},
"color": {
"background": true,
"text": true
}
}
}
Do not just confirm that the controls appear. Confirm that the generated styles look correct inside the editor and on the front end.
Step 9: Check Dynamic Blocks
Dynamic blocks need extra attention because the editor preview and frontend rendering may use different paths.
For dynamic blocks, test:
- The editor preview.
- The saved frontend output.
- Server-rendered content.
- REST API data calls.
- Loading states.
- Error states.
- Empty states.
- Block previews inside patterns and templates.
If your block uses server rendering in the editor, make sure the preview does not depend on parent-window DOM behavior. The iframe editor should be treated as its own content environment.
Step 10: Watch for Link and Button Behavior
One of the easiest things to miss is click behavior. Inside an iframe editor, clickable content can sometimes behave more like a real page than you expect.
Check blocks that contain:
- Buttons.
- Cards with links.
- Clickable image overlays.
- Navigation-like elements.
- Tabs.
- Accordions.
- Carousel arrows.
In the editor, the user should be able to select and edit the block without accidentally navigating away inside the iframe. If needed, prevent frontend navigation behavior in the edit component while keeping the saved frontend output normal.
Step 11: Check the Browser Console
After updating to API v3, open the browser console while editing a page that uses the block.
Look for:
- JavaScript errors.
- Warnings about deprecated APIs.
- Missing dependencies.
- Failed REST requests.
- Blocked iframe access.
- Style or script loading issues.
- React warnings.
- Errors that appear only after selecting or editing the block.
Some problems only appear after interacting with the block. Click every setting, toggle every option, and test the block like a normal user.
Step 12: Test with Real Content
Empty test blocks are not enough. Test with real content that looks like your client or users will actually publish.
Include:
- Long headings.
- Large images.
- Empty images.
- Missing optional fields.
- Nested blocks.
- Multiple block instances on the same page.
- Blocks inside columns or groups.
- Blocks inside patterns.
- Blocks copied from older posts.
Blocks often pass simple tests and fail when real content is messy. A good migration catches those problems before the client does.
Migration Checklist: Block API v2 to v3
- Find all custom blocks using
apiVersion1 or 2. - Create a development branch.
- Update one block or block group at a time.
- Change
apiVersionto3. - Rebuild block assets.
- Test the post editor in iframe mode.
- Test Site Editor and template contexts.
- Replace unsafe global
documentusage. - Replace unsafe global
windowusage. - Use refs,
ownerDocument, anddefaultViewwhere needed. - Check third-party library initialization.
- Confirm editor styles load correctly.
- Check frontend output.
- Check mobile preview.
- Check synced patterns and reusable blocks.
- Check browser console errors.
- Test old content that already contains the block.
- Release to staging first.
- Keep rollback ready for client sites.
Common Mistakes When Updating to API v3
- Changing
apiVersionto3without testing iframe behavior. - Using global
document.querySelector()to find block elements. - Attaching event listeners to the wrong window.
- Relying on admin CSS to style editor content.
- Testing only one empty block on one post.
- Forgetting synced patterns and template contexts.
- Letting editor buttons navigate inside the iframe.
- Assuming third-party libraries are iframe-aware.
- Ignoring browser console warnings.
- Shipping the change to client sites without a staging test.
Developer-Friendly Example: Before and After
Here is a simplified example of a block that needs cleanup.
Before: v2-style pattern that may break
useEffect( () => {
const element = document.querySelector( '.brand-slider' );
if ( element ) {
window.BrandSlider.init( element );
}
}, [] );
This can fail because document and window may refer to the parent admin page, not the iframe content where the block actually lives.
After: iframe-friendlier pattern
import { useRefEffect } from '@wordpress/compose';
import { useBlockProps } from '@wordpress/block-editor';
export default function Edit() {
const ref = useRefEffect( ( element ) => {
const { ownerDocument } = element;
const { defaultView } = ownerDocument;
const slider = defaultView.BrandSlider?.init( element );
return () => {
slider?.destroy?.();
};
}, [] );
const blockProps = useBlockProps( {
ref,
className: 'brand-slider',
} );
return (
<div { ...blockProps }>
Slider preview
</div>
);
}
This version starts from the real block element and then works outward. That is the safer mental model for the iframe editor.
Should You Rewrite the Whole Block?
Usually, no.
Many blocks only need:
apiVersionchanged to3.- A few document/window references fixed.
- Editor styles cleaned up.
- Third-party library initialization adjusted.
- Better testing across editor contexts.
A full rewrite only makes sense if the block is already hard to maintain, depends on outdated packages, has poor saved markup, or mixes editor and frontend behavior in a messy way.
In most cases, think of this as a compatibility migration, not a rebuild.
How This Affects Agencies and Client Sites
For agencies, this update matters because client sites often have custom blocks created years ago. Those blocks may still work today, but they can become fragile as the editor becomes more iframe-first.
A smart agency workflow is:
- Audit all custom blocks across active client projects.
- Identify blocks using API v1 or v2.
- Prioritize blocks used on important pages.
- Update and test in a shared development environment.
- Release updates during normal maintenance windows.
- Document any block behavior changes for the client.
Do not wait until a client says, “The editor looks broken.” This is the kind of maintenance that is easier when done early.
How This Fits into the WordPress 7.x Update Path
The move toward a more consistent iframed editor is part of WordPress’ broader modernization of the block editor. If you are already preparing for newer WordPress versions, this should be part of your update checklist.
Pair this migration with:
- Safely Update to WordPress 7.0 Without Issues
- WordPress 7.0 Plugin Compatibility Checklist
- Full Site Editing with Gutenberg: Practical Guide
- Fix WordPress 7.0 Issues Fast: Rollback Guide
The bigger goal is not just avoiding warnings. The goal is making your blocks behave well in the direction WordPress is clearly moving.
Final Verdict
Updating blocks from Block API v2 to v3 is not something to fear. For many blocks, the actual code change is small. The important part is testing the block in the iframed editor and fixing the assumptions that no longer hold.
The biggest thing to remember is this: inside an iframed editor, the block content has its own document and window. If your block starts from the actual block element and uses refs, ownerDocument, and defaultView, you are already thinking in the right direction.
Do not rush the migration. Update the API version, test real content, fix document/window issues, check styles, review third-party libraries, and ship through staging. That gives you the best of both worlds: cleaner editor compatibility and fewer surprises for site owners.
Block API v3 is not just a version bump. It is your block saying, “Yes, I am ready for the modern WordPress editor.”
FAQs About Updating Blocks from API v2 to v3
```What is the iframed editor in WordPress?
The iframed editor means the WordPress editor content canvas runs inside an iframe, separate from the main admin page. This helps isolate styles, improve layout accuracy, and make the editor preview behave more like the front end.
What does Block API v3 do?
Block API v3 tells WordPress that a block is built for the modern block editor environment, including iframe editor compatibility. It is commonly set in block.json using "apiVersion": 3.
Can I just change apiVersion from 2 to 3?
Sometimes, yes, especially for simple static blocks. But you should still test the block inside the iframed editor because scripts, styles, third-party libraries, and document/window access can behave differently.
Why do document and window cause problems in the iframe editor?
The iframe editor has a different document and window from the parent admin screen. If your block uses global document or window, it may target the wrong environment. Use the block element’s ownerDocument and defaultView instead.
Do all custom blocks need to be updated to API v3?
Custom blocks using API v1 or v2 should be reviewed and updated where possible. This is especially important for blocks used in plugins, client sites, templates, synced patterns, and interactive editor previews.
Will updating to API v3 change saved content?
Changing apiVersion alone usually does not change saved post content. However, any changes to the block’s save() output, wrapper markup, attributes, or deprecated versions can affect validation, so test old content carefully.
How do I test iframe editor compatibility?
Test the block in posts, pages, templates, synced patterns, mobile preview, and Site Editor contexts. Interact with all controls, check frontend output, reload the editor, and watch the browser console for errors.
Should I update third-party block libraries for iframe compatibility?
Yes, if those libraries interact with DOM elements, events, sliders, maps, charts, or animations. Prefer libraries that can initialize from a passed element instead of relying on global document or window.
What is the safest workflow for migrating blocks to API v3?
Create a development branch, update one block group at a time, change apiVersion to 3, rebuild assets, test in the iframed editor, fix document/window issues, check styles, test old content, then release through staging.
Is Block API v3 only for developers?
Yes, mostly. Site owners do not usually edit Block API versions directly. But if a custom block plugin is old, site owners may need the plugin developer or agency to update it for iframe editor compatibility.
```