Gutenberg Times: How WordPress decides a theme is a “block theme”

The term “block theme” is used a lot in WordPress but it was never really clear to me what that meant exactly from a code point of view. While researching The post editor is going full iframe: what block developers need to know before WordPress 7.1, I learned that the outcome of testing WordPress 7.1 Beta 1 may soften the plan: instead of forcing the iframe for everyone, core might force it only for block themes, while classic themes using blocks with apiVersion 2 or lower keep the current 7.0 behavior. (The linked article covers the 7.0 state of things in full.) If that’s the split, then the exact definition of “block theme” suddenly matters a great deal. So what does core actually check? The public API is wp_is_block_theme(), which just asks the active theme: PHP // wp-includes/theme.php (guard clause trimmed) function wp_is_block_theme() { return wp_get_theme()->is_block_theme(); } // wp-includes/theme.php (guard clause trimmed) function wp_is_block_theme() { return wp_get_theme()->is_block_theme(); } And WP_Theme::is_block_theme() is, in its entirety, a file-existence check: PHP // wp-includes/class-wp-theme.php (caching trimmed) public function is_block_theme() { $paths_to_index_block_template = array( $this->get_file_path( ‘/templates/index.html’ ), $this->get_file_path( ‘/block-templates/index.html’ ), ); foreach ( $paths_to_index_block_template as $path ) { if ( is_file( $path ) && is_readable( $path ) ) { return true; } } return false; } // wp-includes/class-wp-theme.php (caching trimmed) public function is_block_theme() { $paths_to_index_block_template = array( $this->get_file_path( ‘/templates/index.html’ ), $this->get_file_path( ‘/block-templates/index.html’ ), ); foreach ( $paths_to_index_block_template as $path ) { if ( is_file( $path ) && is_readable( $path ) ) { return true; } } return false; } A theme is a “block theme” if it ships an index.html block template, either in templates/, or in block-templates/, the pre-5.9 legacy location. Nothing else is consulted. That has a few consequences that may surprise people: theme.json doesn’t make you a block theme. Neither do patterns, block template parts, or add_theme_support( ‘block-templates’ ). A theme can adopt every one of those “hybrid” features and still land on the classic side of this check, because the test only looks for a top-level index.html template. Child themes inherit the answer. get_file_path() looks in the child theme first and falls back to the parent, so a child theme of a block theme is a block theme even if the child ships no templates of its own. It’s a filesystem check, not a declaration. There’s no header in style.css that opts you in or out. Drop a templates/index.html into a theme and, as far as WordPress is concerned, it is a block theme. The minimum files required for block and classic themes This is the entire minimum viable block theme — two files: Markdown my-block-theme/ ├── style.css ← standard theme header └── templates/ └── index.html ← this file IS the decider my-block-theme/ ├── style.css ← standard theme header └── templates/ └── index.html ← this file IS the decider (WordPress considers a theme valid if it has style.css plus either index.php or templates/index.html, which means for a block theme, index.php, functions.php, and even theme.json are all optional.) And this is a theme that is guaranteed to stay classic: Markdown my-classic-theme/ ├── style.css └── index.php ← the classic fallback template my-classic-theme/ ├── style.css └── index.php ← the classic fallback template Staying on the classic side of the check comes down to two conditions: No templates/index.html and no legacy block-templates/index.html. Other block templates don’t matter: a theme with `templates/single.html` but no `templates/index.html` still tests as classic. (In practice, though, if you’re shipping block templates, ship the index and be a block theme on purpose.) No block-theme parent. The check falls back to the parent theme, so a child of Twenty Twenty-Five is a block theme no matter what the child contains. To be classic, the whole chain has to be. Everything else is fair game. theme.json, patterns, add_theme_support( ‘block-template-parts’ )` custom templates registered from plugins — none of them flip the switch., patterns, add_theme_support( ‘block-template-parts’ ), custom templates registered from plugins: none of them flip the switch. Where real themes land Running that check against some current releases from the theme directory Tests classic Tests block Twenty Twenty-One and every earlier default Twenty Twenty-Two and every later default Astra, Kadence, Blocksy, Botiga, Sydney, Hello Elementor — all ship theme.json GeneratePress, Neve, OceanWP, Storefront Six of the themes in the first column ship theme.json, the marquee “block” feature, and still test classic, because the check never looks at theme.json Twenty Twenty and OceanWP are another good gotcha: both ship a templates/ directory and are still classic, because it’s full of PHP page templates (template-cover.php, landing.php). The check wants templates/index.html specifically, so “does it have a templates folder” is not the indicator you might assume. How the editor reads it On the JavaScript side, the block-theme flag surfaces in two different places, which is worth knowing if you go source-diving. As an editor setting: PHP // wp-includes/block-editor.php, get_block_editor_settings() $editor_settings[‘__unstableIsBlockBasedTheme’] = wp_is_block_theme(); // wp-includes/block-editor.php, get_block_editor_settings() $editor_settings[‘__unstableIsBlockBasedTheme’] = wp_is_block_theme(); and on the REST themes endpoint, which is where @wordpress/core-data picks it up: PHP // wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php $data[‘is_block_theme’] = $theme->is_block_theme(); // wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php $data[‘is_block_theme’] = $theme->is_block_theme(); The one-file switch For all the weight the term carries, “block theme” boils down to a single file: templates/index.html exists, or it doesn’t. Not theme.json, not patterns, not any amount of hybrid adoption. Just one index template, checked up the parent chain. That’s worth keeping in mind if 7.1 does end up drawing the iframe line at wp_is_block_theme(). A hybrid theme that has adopted everything except block templates would keep the classic editor behavior, while adding a single templates/index.html (even accidentally, even in a parent theme you don’t control) would flip a site to the forced iframe. If your theme or your users’ sites sit anywhere near that line, now is a good time to check which side of it you’re actually on: it’s one is_file() call away.

Open Channels FM: Open Source and the Open Source Initiative

People think Open Source is just about having access to the source code. Actually, there’s a much longer history behind it. Open Source existed before the term Open Source was even coined, back in the late 60s. Universities started giving away software like Unix for free under small licenses like BSD or MIT, coincidentally named […]

WordCamp Central: WordCamp Rajshahi 2026: Celebrating Community, Learning, and Open Source

WordCamp Rajshahi 2026, held on July 2nd-3rd, 2026, at the Rajshahi University of Engineering & Technology (RUET) Auditorium, brought together WordPress enthusiasts, developers, designers, business owners, students, and open-source contributors from across Bangladesh and beyond. As a non-profit, community-driven conference, the event demonstrated the strength of collaboration, knowledge sharing, and the spirit of open source. More than just a technology conference, WordCamp Rajshahi became a place where people connected, exchanged ideas, and inspired one another to contribute to the future of WordPress. Sharing Knowledge That Matters The conference featured a diverse lineup of local and international speakers who shared practical experiences, real-world case studies, and emerging trends shaping the web today. Artificial intelligence was one of the most discussed topics throughout the event. Sessions explored how AI is transforming the way developers and businesses work—from integrating AI into WordPress without writing code to building customer support agents, using modern Large Language Models (LLMs) for development, debugging applications, and improving everyday workflows. Performance, architecture, and security also received significant attention. Speakers demonstrated advanced WordPress optimization techniques, object caching strategies, no-code animations using GSAP, methods for identifying system vulnerabilities, and practical approaches to cleaning malware-infected WordPress websites with AI. Beyond technical sessions, the conference emphasized personal and professional growth. Attendees learned about building successful careers, transitioning from startups to multinational companies, product marketing, the realities of remote work, and maintaining mental well-being while working in the technology industry. Contributor Day: Giving Back to WordPress Contributor Day, held on July 2, served as one of the most meaningful parts of the event. Participants worked alongside experienced WordPress contributors and Table Leads to improve the WordPress project itself. Whether they contributed to Core, Accessibility, Themes, Plugins, Polyglots (translations), Education, or Photos, attendees experienced firsthand how community collaboration built the global WordPress ecosystem. For many first-time contributors, it was their first opportunity to make a direct contribution to one of the world’s largest open-source projects. Campus Connect: Inspiring the Next Generation One of the highlights of WordCamp Rajshahi 2026 was the Campus Connect initiative. To encourage student participation in open source, 40 university students received complimentary tickets to attend the event. This initiative introduced young learners to the WordPress community, allowing them to interact with experienced professionals, attend technical sessions, and discover opportunities to contribute to open source. By investing in students today, the community hopes to cultivate the next generation of developers, designers, and contributors who will help shape the future of WordPress. Sponsors Who Made It Possible WordCamp events are made possible through the generous support of organizations that believe in strengthening the open-source ecosystem. Rather than simply sponsoring an event, these companies invest in community growth and knowledge sharing. This year, the sponsorship tiers celebrated Rajshahi’s famous mango heritage. Fazli Majesty (Platinum Sponsors) WebAppick, FluentCart, xCloud. Himsagar Legacy (Gold Sponsor) Hosting.com Amrapali Delight (Silver Sponsors) PaymentForm.io Kirki Community Sponsors Crowd Zone, Exprovia, NT Tech Innovation, Padmazon Limited, ShapedPlugin, Sigmative, Timetics AI, WPBakery. Official Partners FM Networks (Internet Partner) TNR Soft (Payment Gateway Partner) Their support enabled the community to deliver a world-class experience while keeping the event affordable and accessible. Thank You to Everyone Behind the Scenes An event of this scale is never the work of a single person. Our sincere appreciation goes to every speaker and Contributor Day table lead who generously shared their knowledge and experience with the community. We are equally grateful to our organizers and volunteers. From sponsorship coordination, website management, registration, design, photography, audiovisual production, venue operations, food management, and attendee support, every team member played a vital role in ensuring the event ran smoothly. Their dedication transformed months of planning into an unforgettable experience for every attendee. Looking Ahead WordCamp Rajshahi 2026 demonstrated what is possible when passionate volunteers, contributors, sponsors, and community members work toward a common goal. The event was more than a conference—it was a celebration of learning, collaboration, and the open-source values that make WordPress one of the world’s most successful communities. As the community continues to grow, the relationships built, ideas shared, and contributions made during WordCamp Rajshahi 2026 will inspire future events and encourage even more people to participate in the global WordPress ecosystem. Here’s to many more WordCamps, more contributors, and a stronger open-source community in Bangladesh and beyond.

Gutenberg Times: #WCUS Schedule, iframed Post Editor, WooCommerce 11.0 and so much more — Weekend Edition 369

Hi there! What a week! WordPress 7.1 Beta 1 (and Beta 2) arrived with a huge array of updates. We’ll unpack them together over the next four weeks, right up to the final release on August 19, 2026. One thing shouldn’t wait, though: the security release WordPress 7.0.2. Go update your production sites now — this newsletter will still be here when you’re back. In this edition, you’ll also find the first speaker lineup for WordCamp US, a fourth page-builder migration story, WooCommerce 11.0 on the horizon, and plenty of block development goodness: from iframed editors to on-brand maintenance pages. Grab your favorite Saturday beverage and dig in. Yours, Birgit WordCamp US 2026: Four Tracks, Three Workshops, 33 Speakers The first wave of WCUS 2026 speakers is live — and it reads like a who’s-who of WordPress in practice. WordCamp US just published its opening lineup for August 16–19 in Phoenix: 34 confirmed speakers so far, including K Adam White, Brian Coords, Jamie Marsland, Kathy Zant, Miriam Schwab, and Robert Abela, all experienced developers, educators, security specialists, community builders. The program runs four tracks. AI in Action leads with sessions on agentic workflows, AI search, and guardrails for AI-assisted development. Honing Your Skills covers the practical side: maintenance, privacy compliance, creator commerce, security. Technical WordPress digs into block migrations at scale, WP-CLI automation, and plugin pipelines. Beginning WP101 is the on-ramp for newcomers — or for clients you’re bringing along. Three hands-on workshops round out the program, where you build something real in the room and leave with it. The full session schedule isn’t out yet, but the speaker list alone is a useful signal. If someone on that page is a voice you follow, a tool you depend on, or a corner of WordPress you’re actively navigating, you now have a specific reason to be in the room. us.wordcamp.org/2026/tickets — $100 General Admission · $750 Micro-Sponsor (includes listing on the sponsors page) Full speaker list → Developing Gutenberg and WordPress WordPress 7.1 Beta 1 was release on July 15, 2026. is now available for testing. The release post offers instructions how to sent up a test side and shows an extensive list of new features. The security team released WordPress 7.0.2 with the urgent appeal to update right away. The security fixes were also backported in 6.9.5 and 6.8.6. The security fix was also included in WordPress 7.1 Beta 2, so testing sites are also protected during this release cycle. Huzaifa Al Mesbah, from the Core Test team, published the accompanying Help Test WordPress 7.1 post. A few WordPress 7.1 Dev Notes are already available: Consistent navigation in WordPress 7.1 with persistent toolbar The Classic block stays in the inserter for WordPress 7.1 The latest episode is Gutenberg Changelog #132 – Proposals for Core, Calls for Testing, WordPress 7.1 and Gutenberg 23.4 and 23.5 Plugins, Themes, and Tools for #nocode site builders and owners In about 10 days, WooCommerce 11.0 release is schedule. Brain Coords has the skinny for you in what’s coming for developers in WooCommerce. Performance leads the release with 28 PRs — product object caching becomes the default for new stores, speeding up variable products by 9–12%. You’ll also find email verification connecting guest orders to accounts, new phone validation hooks, video embeds in the block email editor, and the final removal of the Product Editor beta. The beta is ready for your testing now. Jamie Marsland followed his instincts and build Jamie’s Front-End Editor for Content Teams, a plugin that lets your editors click any paragraph or heading on the live page and start typing — no block editor required. With the latest updates, you can now edit text, links, buttons and images right on the live page. No wp-admin, no block editor, just click and change it in place. Built on the Interactivity API with no build step, it preserves block markup on save, records edits as native block notes for an audit trail, and lets you restrict chosen roles to front-end-only editing. Let Marsland what you think. Last week, I shared three migration stories from page builders to the Core block editor and block themes. Here’s a fourth perspective: The team at WP Expert, an Ottawa agency founded by Frederic Sune, put together a comprehensive post on migrating agency sites from page builders to Gutenberg, should you go on that journey, too. You’ll find the strategic arguments (better Core Web Vitals, smaller attack surface, less technical debt) alongside a practical playbook covering backups, staging, block theme selection, pattern development, and SEO safeguards. The post also explores what block-based architectures mean for an agency’s business model, from premium modernization packages to fewer layout-related support tickets. An FAQ rounds it out. Theme Development for Full Site Editing and Blocks Brian Coords tackles a common WooCommerce pain point: custom product templates for block themes. He combines two core WordPress features — the plugin template registration API from 6.7 and the venerable single_template_hierarchy filter — to serve custom templates for product collections, like all products in a category. His example plugin falls back to your Single Product template unless you override it. Clone the repo and give it a try; custom Product fields are next on his list. On the WordPress Developer Blog, Troy Chaplin shows you how to build an on-brand maintenance mode for block themes. You add one small hook to your theme’s functions.php once, then design and manage the maintenance page entirely in the Site Editor with full access to your Global Styles. Renaming or deleting the template toggles maintenance mode on and off, no code needed. An SEO-friendly variant adds 503 headers so crawlers know the downtime is temporary. “Keeping up with Gutenberg – Index 2026” A chronological list of the WordPress Make Blog posts from various teams involved in Gutenberg development: Design, Theme Review Team, Core Editor, Core JS, Core CSS, Test, and Meta team from Jan. 2024 on. Updated by yours truly.  The previous years are also available: 2020 |

Matt: Important Security Update

WordPress 7.0.2 went out today with two important security updates. One is a type of pre-authorization RCE we (fortunately!) have only seen a few times in WordPress’ 23-year history; the last, I believe, in the PHPMailer class five years ago. Major kudos to Adam Kues of Searchlight Cyber for finding the batch REST API RCE, to TF1T, dtro, and haongo on the facilitated SQL injection! Thanks to responsible disclosure, the WordPress.org Security team was able to coordinate with hosts and CDNs to mitigate the attack at the network layer. Please upgrade anyway! But it’s a huge relief to know the vast majority of WordPress sites were protected by defense-in-depth even before the updates went out. I really appreciate how people and organizations that otherwise might not be on the best of terms come together in times like this. (Full credits in the release post.) Everyone buries the hatchet to protect as many people as possible as quickly as possible. I’ve said it before, I’ll say it again: security is going to be a big topic this year as the technology industry digests the incredible advances in AI models. It’s a good time to review your plans and processes, sweat the details, invest in maintenance, and hug a sysadmin.

WordPress.org blog: WordPress 7.0.2 Release

WordPress 7.0.2 is now available. The 7.0.2 security release addresses one critical and one high severity security issue. Because this is a security release, it is recommended that you update your sites immediately. Due to the severity, the WordPress.org team have enabled forced updates via the auto-update system for sites running affected versions. To manually update you can visit your WordPress Dashboard, click “Updates”, and then click “Update Now”, or you can download WordPress 7.0.2 from WordPress.org. On sites that support automatic background updates, the update process will begin automatically. Security updates included in this release The security team would like to thank the following people for responsibly reporting vulnerabilities and allowing them to be fixed in this release: A facilitated SQL injection issue reported as a team by TF1T, dtro, and haongo A REST API batch-route confusion and SQL injection issue leading to Remote Code Execution reported by Adam Kues at Assetnote / Searchlight Cyber For more information on this release, please visit the HelpHub site. Backports WordPress 6.9 is affected by both vulnerabilities. Version 6.9.5 has been released containing fixes for both. WordPress 6.8 is only affected by the first vulnerability. Version 6.8.6 has been released containing a fix. The beta release of WordPress 7.1 is affected by both vulnerabilities. Version 7.1 beta2 has been released containing fixes for both. Versions of WordPress prior to 6.8 are not affected. CVE and GHSA references CVE-2026-60137 / GHSA-fpp7-x2x2-2mjf CVE-2026-63030 / GHSA-ff9f-jf42-662q Thank you to these WordPress contributors This release was led by John Blackbourn and Barry Abrahamson. In addition to the security researchers mentioned above, WordPress 7.0.2 would not have been possible without the significant contributions of the following people: Aaron Jorbin, Alex Concha, annezazu, Barry, David Baumwald, Dominik Schilling, Ehtisham Siddiqui, Joe Dolson, Joe Hoyle, John Blackbourn, Jonathan Desrosiers, Marius L. J., Matt Mullenweg, Mohammad Jangda, Peter Wilson, Sergey Biryukov, vortfu, Weston Ruter, plus representatives from Altis, Automattic, Bluehost, Cloudflare, GoDaddy, Hostinger, and WP Engine.

Ultimate WordPress Spam Protection Guide – Step by Step (2026)

If you run a WordPress site, then you know that spam is a real annoying problem whether it comes to contact forms, WordPress comments, or user registrations. The good news is that stopping spam in WordPress is a lot easier than you probably think, and you don’t need expensive tools either. We have spent over 16 years testing anti-spam plugins, tools, and refining strategies to keep WPBeginner and our other business websites safe from daily spam attacks. In this ultimate guide, we’ll walk you through how to block each type of WordPress spam, step by step from the basics to advanced modern automated spam protection. These are the exact methods we’re using to protect our own websites. We’re covering a lot of ground in this ultimate guide, so use the quick links below to jump straight to the section you want to learn about first: 1. Free Built-In Settings to Turn On First 2. Set Up Modern AI-Powered Spam Bot Protection for WordPress 3. Power-User Tips for Stopping WordPress Comment Spam 4. Stopping WordPress Contact Form Spam (Best Practices) 5. Stopping Spam User Registrations in WordPress (Best Practices) 6. Add a Site-Wide WordPress Firewall 7. Cleanup WordPress Spam and Ongoing Monitoring Frequently Asked Questions About WordPress Spam Protection 1. Free Built-In Settings to Turn On First WordPress comes with several anti-spam options that can protect your site against spam. These built-in options won’t stop every bot, but they will remove the easiest targets right away. We always recommend turning these settings on first, because they cost nothing and take only a few minutes to set up. Tighten Your WordPress Discussion Settings To prevent comment spam, the built-in discussion settings in WordPress act as your first line of defense. They allow you to control who can post, what kind of links are permitted, and how much control you have over the conversation. To configure these anti-spam controls, go to Settings » Discussion in your WordPress dashboard. The most useful tool on this screen is the comment moderation queue. This tool acts as a holding area that keeps submissions hidden from the public until you have a chance to look them over. Because nothing goes live automatically, spam never reaches your visitors, even if it manages to get past your other filters. To turn this on, scroll down to the ‘Before a comment appears’ section and check the box next to ‘Comment must be manually approved.’ If you want, you can also enable ‘Comment author must have a previously approved comment.’ This lets returning commenters post without waiting for approval. However, be sure to review your published comments regularly since they won’t appear in your moderation queue. After that, scroll to the ‘Comment Moderation’ box, where you’ll find a setting that limits links. Because spam comments almost always contain web addresses, WordPress can automatically hold any submission that includes too many links. The field labeled ‘Hold a comment in the queue if it contains [X] or more links’ is set to 2 by default. Lowering that number to 1 will help you catch even more junk. On the same screen, you can use the comment blocklist to automatically filter out unwanted content. This tool looks for specific words, names, email addresses, or web addresses and sends any matching comment straight to the trash. In the ‘Disallowed Comment Keys’ box, you can paste your own trigger words, putting one on each line, and then save your changes. Require a Name and Email, and Hold First-Time Commenters Healthy discussions start with real people. Requiring commenters to enter a name and email encourages more thoughtful conversations and discourages anonymous drive-by comments. Most genuine visitors won’t mind providing these details, and it helps create a more welcoming and trustworthy community around your website. To enable this, scroll to the ‘Other comment settings’ section and check the box next to ‘Comment author must fill out name and email.’ If you want to master the review process and manage your queue efficiently, our beginner’s guide to moderating comments in WordPress covers the full workflow. Disable Comments Where You Do Not Need Them Depending on the type of website you have, you may not need a comment section at all. If that’s the case, then you can simply disable comments entirely and that’ll get rid of the WordPress comment spam problem once and for all. The most thorough option is the code method, which disables comment support across your entire site at once. It’s safest to add the snippet with a free code snippets plugin like WPCode rather than editing your theme’s files directly, so a theme update can’t undo it. add_action(‘admin_init’, function () { // Redirect any user trying to access comments page global $pagenow; if ($pagenow === ‘edit-comments.php’) { wp_safe_redirect(admin_url()); exit; } // Remove comments metabox from dashboard remove_meta_box(‘dashboard_recent_comments’, ‘dashboard’, ‘normal’); // Disable support for comments and trackbacks in post types foreach (get_post_types() as $post_type) { if (post_type_supports($post_type, ‘comments’)) { remove_post_type_support($post_type, ‘comments’); remove_post_type_support($post_type, ‘trackbacks’); } } }); // Close comments on the front-end add_filter(‘comments_open’, ‘__return_false’, 20, 2); add_filter(‘pings_open’, ‘__return_false’, 20, 2); // Hide existing comments add_filter(‘comments_array’, ‘__return_empty_array’, 10, 2); // Remove comments page in menu add_action(‘admin_menu’, function () { remove_menu_page(‘edit-comments.php’); }); // Remove comments links from admin bar add_action(‘init’, function () { if (is_admin_bar_showing()) { remove_action(‘admin_bar_menu’, ‘wp_admin_bar_comments_menu’, 60); } }); Hosted with ❤️ by WPCode 1-click Use in WordPress Our guide on how to completely disable comments in WordPress walks through that snippet along with the other options. If you’d rather not go site-wide, you can also turn comments off on individual pages. This is handy when you only want them gone on specific pages, like your Contact or About pages, which rarely need a comment section. To do this, open the page in the WordPress content editor. Then click the ‘Discussion’ option in the right-hand sidebar and select ‘Closed.’ You can also stop spam from piling up on older content without touching your newer posts. If you don’t expect comments on old posts, then WordPress

Gutenberg Times: The post editor is going full iframe: what block developers need to know before WordPress 7.1

For years, the post editor has lived a double life. The Site Editor renders your blocks inside an iframe. The post editor — where most people actually spend their time — renders them directly in the admin page. That split ends with WordPress 7.1: the post editor canvas will always be an iframe, on every theme, no matter what apiVersion your blocks declare. The Gutenberg plugin has been enforcing exactly this for months. If you ship blocks, assume the iframe. If your block never touches the global document or window, you can probably stop reading after you’ve changed “apiVersion”: 2 to “apiVersion”: 3 in block.json. For everyone else — and especially anyone shipping blocks that wrap third-party libraries — the iframe changes where your code runs versus where your markup lives. That gap is where things break. Quick reference guide: Are your blocks ready? The timeline, in one table Release What happens June 21, 2021 The iframed editor was announced on make.wordpress.org WordPress 6.9 (Dec 2025) Console warning (with SCRIPT_DEBUG) when a block registers with apiVersion 2 or lower. The block.json schema now only validates apiVersion: 3. WordPress 7.0 (Apr 2026) The iframe decision now looks at blocks actually inserted in the post, not every registered block. All inserted blocks on v3+ → canvas is iframed. Insert a single v1/v2 block → the iframe is removed on the fly. Nothing is enforced yet. Gutenberg 22.6+ The iframe is enforced regardless of theme — this is the feedback-gathering phase. WordPress 7.1 (Aug 19, 2026) The iframe is enforced on every theme, regardless of apiVersion. The conditions are gone, not tightened. The WordPress 7.0 change is subtle but important: before 7.0, one apiVersion: 2 block registered by any active plugin — even one never used in the post — kept the entire editor out of the iframe for everyone. Now only inserted blocks count. Your v3 block gets the iframe until the user inserts a legacy one, at which point the editor quietly reloads the canvas without the iframe. The companion plugin ships a legacy-api-v2 block so you can watch this happen — insert it into an otherwise-v3 post and the iframe disappears. In 7.1, that escape hatch closes. Worth knowing, as an aside: the “every theme” decision landed in WordPress 7.1 Beta 1, and it’s deliberately being tested in public. Gutenberg merged “Post editor: always iframe” (#74042) on July 10, 2026, deleting the theme and apiVersion conditions outright. The 7.1 release lead signed off on that merge on the condition that the team could “move to the softer approach” if Beta 1 feedback surfaced real problems — the softer approach being enforcement on block themes only, with everything else staying on the 7.0 rules. No specific mechanism is committed to; the plan is to respond to what the beta actually turns up.Which is a reason to test harder, not to wait and see. If that rollback happens, the iframed and non-iframed editors both stay in the wild longer — and your block has to work in both regardless of which way it goes. It’s also worth noting that blocks that will break with the 7.1 changes are most likely already breaking in the Site Editor. Why the iframe is a good thing This isn’t change for change sake. Rendering the canvas in an iframe gives the editor a real document boundary: Admin CSS stops leaking into your content. No more #wpadminbar-adjacent style resets, no more admin styles subtly changing how blocks render in the editor versus the front end. Viewport units and media queries finally work. vw, vh, and @media rules resolve against the canvas, not the admin page — so tablet/mobile previews and zoomed-out views actually behave like the front end. What you see is much closer to what you get. The canvas document is built from your theme’s styles, not the admin’s. The issue this raises for block developers? Your editor JavaScript runs in the admin page, but your block’s DOM lives in a different document. Every assumption baked into document.querySelector(…) and window.addEventListener(…) just became wrong. What actually breaks (and how to fix it) Everything below is demonstrable with the companion plugin — each pattern ships as a broken/fixed pair of blocks: iframe-editor-examples on GitHub. 1. Global window and document references The classic: a block that reads the viewport or listens for resize. JavaScript // Broken in the iframed editor useEffect( () => { const update = () => setWidth( window.innerWidth ); update(); window.addEventListener( ‘resize’, update ); return () => window.removeEventListener( ‘resize’, update ); }, [] ); // ❌ Broken in the iframed editor useEffect( () => { const update = () => setWidth( window.innerWidth ); update(); window.addEventListener( ‘resize’, update ); return () => window.removeEventListener( ‘resize’, update ); }, [] ); Editor scripts load in the admin page, so window is the admin window. In the iframed editor this reports the wrong width and never reacts to the canvas resizing — switch to the Tablet preview and the number doesn’t move. The fix is to derive the document and window from your block’s own DOM element: JavaScript // Fixed — works iframed or not import { useRefEffect } from ‘@wordpress/compose’; const ref = useRefEffect( ( element ) => { const { defaultView } = element.ownerDocument; const update = () => setWidth( defaultView.innerWidth ); update(); defaultView.addEventListener( ‘resize’, update ); return () => defaultView.removeEventListener( ‘resize’, update ); }, [] ); const blockProps = useBlockProps( { ref } ); // ✅ Fixed — works iframed or not import { useRefEffect } from ‘@wordpress/compose’; const ref = useRefEffect( ( element ) => { const { defaultView } = element.ownerDocument; const update = () => setWidth( defaultView.innerWidth ); update(); defaultView.addEventListener( ‘resize’, update ); return () => defaultView.removeEventListener( ‘resize’, update ); }, [] ); const blockProps = useBlockProps( { ref } ); Two things to notice: element.ownerDocument is whatever document the block is rendered into — the iframe’s document when iframed, the admin document when not. ownerDocument.defaultView is that document’s window. Code written this