WordPress 7.1: edytor wpisów w iframe
PL

WordPress 7.1: edytor wpisów w iframe

Ostatnio zweryfikowano: 9 sierpnia 2026
13 min czytania
Przewodnik
500+ projektów WP
Full-stack developer

Jeżeli wydajesz własne bloki albo utrzymujesz strony klientów, na których działają cudze, praca na ten tydzień sprowadza się do jednego grepa i jednej instalacji testowej. W WordPressie 7.1 edytor wpisów zawsze działa w iframe. Nota deweloperska Akiego Hamano z 3 sierpnia 2026 stawia sprawę bez asekuracji: “Starting in WordPress 7.1, the post editor is always iframed, regardless of the theme type, the block API versions of the registered blocks, or the block API versions of the blocks in the content.” Nie ma przełącznika i nie ma warstwy zgodności. Każdy fragment edytorowego JavaScriptu, który sięga po globalny document albo window, żeby dobrać się do treści bloku, celuje teraz w niewłaściwą stronę, a arkusz stylów zarejestrowany na enqueue_block_editor_assets z myślą o stylowaniu treści po prostu przestanie obowiązywać, po cichu. Premiera 7.1 wypada 19 sierpnia 2026, więc miejscem na tę weryfikację jest release candidate, a nie produkcja klienta.

#Dlaczego do tej pory wszystko wyglądało sprawnie

Zacznijmy od kalendarza, bo to on tłumaczy, dlaczego problem, który istnieje od lat, dopiero teraz stanie się widoczny na Twoich stronach. Iframe nie jest nowością. Nowością jest zniknięcie warunków, które go wcześniej blokowały.

WersjaZachowanie
5.8Edytor szablonów działa w iframe.
6.3Edytor wpisów działa w iframe tylko wtedy, gdy każdy zarejestrowany blok deklaruje Block API w wersji 3 lub wyższej. enqueue_block_assets zaczyna sięgać kanwy.
6.9Przy SCRIPT_DEBUG pojawiają się ostrzeżenia w konsoli dla apiVersion 2 i niższych. Schemat block.json dopuszcza dla nowych bloków wyłącznie wersję 3.
7.0Test zostaje zawężony do bloków faktycznie wstawionych we wpisie. Nota deweloperska do 7.0 autorstwa Elli Van Durpe mówi wprost, że w 7.0 iframe nie jest wymuszany.
7.1Zawsze w iframe.

To właśnie reguła z 6.3 odpowiada za większość nieporozumień w praktyce. Skoro jeden zarejestrowany blok z apiVersion 2, gdziekolwiek na stronie, przełączał cały edytor z powrotem na ścieżkę bez iframe, wtyczka mogła być kompletnie niesprawna wewnątrz iframe i nikt by tego nie zobaczył, dopóki jeden przestarzały blok na tej samej instalacji nie pozwalał iframe w ogóle wejść w grę. Ten warunek pełnił funkcję tłumika zgłoszeń błędów. Efekt uboczny jest taki, że brak awarii przez ostatnie trzy lata nie jest żadnym dowodem gotowości.

Edytor witryny działa w iframe zawsze i to wyjaśnia obserwację, którą pewnie znasz z obsługi klientów: ta sama wtyczka zachowuje się różnie w zależności od tego, na którym ekranie akurat pracuje redaktor.

#Co się zmienia pod spodem

Sedno mieści się w jednym zdaniu tej samej noty deweloperskiej: “the iframe has its own document and window, separate from the admin page where editor scripts run.”

Komponent edit Twojego bloku nadal renderuje React ze strony kokpitu na zewnątrz, ale węzły DOM, które ten komponent tworzy, żyją już w iframe. Komponent i markup, którym zarządza, przestały więc dzielić jeden document. Wywołanie document.querySelector() z wnętrza bloku odpytuje post.php, a nie kanwę. Nie rzuca wyjątkiem. Zwraca null albo, w gorszym wariancie, zwraca przypadkowy węzeł z obudowy edytora, a kod leci dalej na fałszywym założeniu.

W Reakcie nic się nie zmienia. W block.json nic się nie zmienia. Zmienia się to, że klasa założeń, które przez lata bywały prawdziwe najczęściej, jest teraz fałszywa zawsze.

#Dlaczego nie ma przełącznika

Uzasadnienie z Gutenberg PR #74042, scalonego 10 lipca 2026, warto przeczytać w całości, ale kluczowe zdanie brzmi: “far more breakage is caused by the inconsistency than blocks not functioning well with iframe.”

To broniona decyzja inżynierska. Dwa środowiska renderowania z przełącznikiem między nimi w czasie działania to gorszy kontrakt niż jedno środowisko, które bywa nieprzyjazne. Oznacza to jednak również, że wyjścia awaryjne zostały zamknięte: pull request usuwa ścieżkę bez iframe, a recenzent zauważa, że switchToLegacyCanvas() “does nothing anymore.” Jeżeli planowałeś kupić sobie jeden cykl wydawniczy filtrem, nie ma po co sięgać.

Opór jest przy tym realny i udokumentowany. W zgłoszeniu śledzącym #70743 główny deweloper Meta Boksa napisał: “Switching to version 3 is impossible at the moment, as most of the JS the plugins use are using jQuery with DOM manipulation.” To nie jest problem jednej wtyczki. To opis sporej części komercyjnego ekosystemu metaboksów i pól niestandardowych, na którym stoi wiele stron budowanych przez agencje.

#Scenariusze awarii i naprawy

Punktem odniesienia jest strona podręcznika o migracji bloków pod kątem zgodności z iframe. Poniżej to, jak naprawy wyglądają w praktyce.

#Odwołania do globalnego document

Ta kategoria daje ciche, błędne odpowiedzi zamiast błędów. Zgłoszenie Gutenberga #55947 to czysty przykład: skrypt wpięty przez enqueue_block_editor_assets czyta document.body.classList i dostaje zewnętrzny dokument post.php, więc klasa, której szuka, nigdy tam nie występuje.

Przed:

import { useEffect } from '@wordpress/element';

export default function Edit( { attributes } ) {
	useEffect( () => {
		// `document` is the admin page. This finds nothing in 7.1.
		const heading = document.querySelector( '.wp-block-my-plugin-hero h2' );
		if ( heading && document.body.classList.contains( 'is-dark-theme' ) ) {
			heading.dataset.contrast = 'inverted';
		}
	}, [ attributes.style ] );

	return <div className="wp-block-my-plugin-hero">{ /* ... */ }</div>;
}

Po:

import { useRefEffect } from '@wordpress/compose';

export default function Edit( { attributes } ) {
	const ref = useRefEffect(
		( element ) => {
			// Resolve the canvas from a node that is already inside it.
			const canvas = element.ownerDocument;
			const heading = element.querySelector( 'h2' );
			if ( heading && canvas.body.classList.contains( 'is-dark-theme' ) ) {
				heading.dataset.contrast = 'inverted';
			}
		},
		[ attributes.style ]
	);

	return <div ref={ ref } className="wp-block-my-plugin-hero">{ /* ... */ }</div>;
}

Zmieniły się dwie rzeczy. element.ownerDocument zwraca dokument, który faktycznie zawiera dany węzeł, jakikolwiek by nie był, więc ten sam kod zadziała w edytorze wpisów, w edytorze witryny i na dowolnej przyszłej powierzchni. Poza tym wyszukiwanie nagłówka zostało ograniczone do elementu samego bloku zamiast przeczesywania całego dokumentu, co i tak było od początku poprawniejszym podejściem.

#Globalne window i nasłuchy podpięte do zewnętrznego dokumentu

Wszystko, co mierzysz na window, cierpi na tę samą przypadłość, tylko groźniej, bo window.innerWidth zwraca prawdziwą liczbę. Tyle że nie tę: zwraca szerokość okna przeglądarki, a nie kanwy, która w układzie dwupanelowym z otwartym panelem ustawień potrafi być o kilkaset pikseli węższa od obszaru, w którym renderuje się blok.

Przed:

import { useState, useEffect } from '@wordpress/element';

export default function Edit() {
	const [ width, setWidth ] = useState( 0 );

	useEffect( () => {
		const onResize = () => setWidth( window.innerWidth );
		onResize();
		window.addEventListener( 'resize', onResize );
		return () => window.removeEventListener( 'resize', onResize );
	}, [] );

	return <div>{ width }</div>;
}

Po:

import { useState } from '@wordpress/element';
import { useRefEffect } from '@wordpress/compose';

export default function Edit() {
	const [ width, setWidth ] = useState( 0 );

	const ref = useRefEffect( ( element ) => {
		const view = element.ownerDocument.defaultView;
		const onResize = () => setWidth( view.innerWidth );
		onResize();
		view.addEventListener( 'resize', onResize );
		return () => view.removeEventListener( 'resize', onResize );
	}, [] );

	return <div ref={ ref }>{ width }</div>;
}

element.ownerDocument.defaultView to window należące do kanwy. Podpinaj nasłuchy przez nie i rób to z wnętrza callbacku ref, a nie z efektu, który nie ma pojęcia, w którym dokumencie się wykonuje.

Przejście z useRef i useEffect na useRefEffect nie jest kosmetyką. Callback useEffect nie zostanie wywołany, gdy zmieni się ref, a w edytorze w iframe ref zmienia się naprawdę: węzeł kanwy powstaje, jest podmieniany i niszczony w trakcie jednej sesji edycyjnej. Efekt, który wykonał się raz na węźle już nieistniejącym, to prosta droga do nasłuchów na martwym dokumencie i sprzątania, które nigdy nie następuje. Gutenberg PR #52588 pokazuje ten przypadek zniszczenia namacalnie, z błędem Cannot read properties of null (reading 'getComputedStyle') rzucanym w momencie znikania iframe.

#jQuery, select2 i wszystko, co sięga po globala

To ta kategoria, którą opisywał komentarz z Meta Boksa, i to w niej siedzi większość kodu utrzymywanego przez agencje. Zgłoszenie #47924 dokumentuje psucie się select2 z ACF-a oraz datepickera z jQuery UI wewnątrz iframe.

Przed:

import { useEffect } from '@wordpress/element';

export default function Edit( { clientId } ) {
	useEffect( () => {
		jQuery( `#my-plugin-select-${ clientId }` ).select2( { width: '100%' } );
	}, [ clientId ] );

	return <select id={ `my-plugin-select-${ clientId }` }>{ /* ... */ }</select>;
}

Po:

import { useRefEffect } from '@wordpress/compose';

export default function Edit() {
	const ref = useRefEffect( ( element ) => {
		const $ = element.ownerDocument.defaultView.jQuery;
		if ( ! $ ) {
			return;
		}
		const $select = $( element );
		$select.select2( { width: '100%' } );
		return () => {
			$select.select2( 'destroy' );
		};
	}, [] );

	return <select ref={ ref }>{ /* ... */ }</select>;
}

Naprawę niosą trzy zmiany. Biblioteka jest pobierana z okna kanwy zamiast z globala, czyli wzorcem defaultView.jQuery(element). Element trafia do niej bezpośrednio, zamiast być odnajdywany selektorem po identyfikatorze, więc wyszukiwania międzydokumentowego nie ma tu w ogóle. I zwracane sprzątanie niszczy widżet w chwili, gdy węzeł znika, co jest tym fragmentem, który istniejący kod pomija najczęściej, bo przed iframe węzeł praktycznie nigdy nie znikał.

Jeżeli jQuery nie ma na oknie kanwy, to problem z kolejkowaniem, a nie z JavaScriptem, co prowadzi do ostatniej kategorii.

#Style i skrypty wpięte do niewłaściwej powierzchni

Reguła ze strony podręcznika o kolejkowaniu zasobów w edytorze to czysty podział. enqueue_block_editor_assets obsługuje interfejs edytora: panele boczne, paski narzędzi, panele wtyczek, przyciski formatowania. enqueue_block_assets obsługuje treść i sięga zarówno kanwy, jak i frontu.

Przed:

add_action( 'enqueue_block_editor_assets', function () {
	wp_enqueue_style(
		'my-plugin-blocks-editor',
		plugins_url( 'build/blocks.css', __FILE__ ),
		array(),
		'1.4.0'
	);
} );

Po:

// Editor interface only: panels, toolbars, sidebar controls.
add_action( 'enqueue_block_editor_assets', function () {
	wp_enqueue_style(
		'my-plugin-blocks-panels',
		plugins_url( 'build/panels.css', __FILE__ ),
		array(),
		'1.4.0'
	);
} );

// Content: applies inside the canvas and on the front end.
add_action( 'enqueue_block_assets', function () {
	wp_enqueue_style(
		'my-plugin-blocks-content',
		plugins_url( 'build/blocks.css', __FILE__ ),
		array(),
		'1.4.0'
	);
} );

Pomyłka w tym miejscu nie generuje żadnego błędu. Arkusz się ładuje, przeglądarka raportuje 200, a reguły nie trafiają w nic na kanwie, bo zostały wstrzyknięte do innego dokumentu. Zgłoszenie Gutenberga #53236 śledzi dokładnie ten objaw: arkusz wpięty dla edytora po cichu przestaje obejmować kanwę.

Ten sam podział dotyczy skryptów. To, co ma działać na węzłach treści, musi być załadowane tam, gdzie te węzły żyją.

#Klasyczne metaboksy przestają trzymać edytor poza iframe

Rejestracja klasycznych metaboksów była jedną z tych ścieżek, które w praktyce utrzymywały edytor wpisów poza iframe. W 7.1 już nią nie jest. Field Guide do 7.1 z 5 sierpnia 2026 zamyka temat jednym zdaniem: “WordPress 7.1 completes the move to an iframe-based post editor, including for sites that register legacy meta boxes.” Po polsku: przejście na edytor w iframe obejmuje również witryny, które rejestrują stare metaboksy.

Dla agencji to zwykle najbardziej dotkliwa powierzchnia awarii, bo dotyczy nie własnych bloków, tylko istniejących stron klientów: własne metaboksy dopisane w motywie potomnym, grupy pól ACF renderowane po staremu, panele dokładane przez wtyczki sklepowe i branżowe. Ekrany, które przez lata otwierały się bez iframe i dlatego nigdy nie zostały w nim przetestowane, wymagają teraz osobnego przejścia.

#Test w dziesięć minut

Żeby ustalić, czy masz problem, nie potrzebujesz pełnego audytu. Potrzebujesz jednej instalacji.

  1. Wymuś iframe bez czekania na wydanie. Ta sama nota deweloperska odnotowuje: “since Gutenberg 22.6, when the plugin is active the post editor is forced to be iframed regardless of the theme type or the block API versions in use”, czyli od wersji 22.6 sama aktywna wtyczka Gutenberg wymusza iframe w edytorze wpisów, niezależnie od typu motywu i użytych wersji Block API. Wgraj ją na staging i masz docelowe zachowanie 7.1 na dzisiejszym rdzeniu. Wariant zapasowy to jednorazowa strona na WordPressie 7.1 RC, lokalny kontener albo tymczasowy staging w zupełności wystarczą.
  2. Włącz jedną wtyczkę rejestrującą blok z apiVersion 2. Może być dowolny przestarzały blok z Twojego katalogu albo z instalacji klienta.
  3. Otwórz edytor wpisów i wstaw ten blok.
  4. Otwórz konsolę przeglądarki i trzymaj ją otwartą podczas pracy z blokiem: wpisuj do niego treść, zmień ustawienie w panelu bocznym, przełącz się na inny blok i wróć, na koniec go usuń.
  5. Przeczytaj, co dostałeś. Odczyty właściwości z null przy niszczeniu węzła, selektory zwracające null, brakujące style na kanwie, które na froncie wyglądają poprawnie.

Dwie uwagi do czytania wyników. Włącz SCRIPT_DEBUG, bo ostrzeżenia o apiVersion dodane w 6.9 pojawiają się wyłącznie przy tej stałej. I sprawdź style wzrokowo, nie tylko w konsoli, bo opisane wyżej pomyłki w kolejkowaniu są całkowicie ciche.

Dziesięć minut daje odpowiedź tak lub nie dla jednej wtyczki. To wystarczy, żeby oszacować właściwą pracę.

#Co sprawdzić w portfelu stron klientów

Jeżeli utrzymujesz strony, których nie budowałeś, pytaniem blokującym nie jest “czy nasz kod jest gotowy”, tylko “za który kod na tych stronach nie odpowiada już nikt”. Sporządzenie takiej inwentaryzacji to praca inżynierska i warto ją wykonać, zanim redaktorka zadzwoni, że układ się rozjechał.

  • Zbuduj spis bloków. Dla każdej strony wypisz, które wtyczki i motywy rejestrują bloki oraz jaką wersję apiVersion deklaruje każdy z nich. Podbicie numeru nie naprawi zachowania w 7.1, ale liczba bloków w wersji 2 mówi, gdzie zajrzeć najpierw.
  • Oddziel utrzymywane od porzuconych. Dla każdej dotkniętej wtyczki sprawdź datę ostatniego wydania i to, czy autor odniósł się do zgodności z iframe. Wtyczka utrzymywana oznacza, że czekasz i testujesz. Porzucona oznacza wybór między lokalną łatką, forkiem a zamiennikiem, a taka decyzja ma swój czas wyprzedzenia.
  • Zgrepuj własny kod. Przeszukaj każdą autorską wtyczkę i motyw w portfelu pod kątem document. i window. w bundle’ach edytora, a także jQuery( i każdej obsługi enqueue_block_editor_assets, która rejestruje style treści. To szybkie, mechaniczne przejście, które kończy się konkretną listą.
  • Osobno prześwietl warstwę metaboksów. ACF, Meta Box i narzędzia tej klasy siedzą w kategorii najwyższego ryzyka i zwykle stoją na stronach, na których redakcja zauważa awarię najszybciej.
  • Zrób drugie przejście po ekranach z metaboksami. Po teście bloków wróć na tę samą instalację i otwórz każdy typ treści, który rejestruje klasyczne metaboksy: wypełnij pola, zapisz wpis, odśwież i sprawdź, czy wartości wróciły. To odrębny przebieg, bo do 7.1 właśnie te ekrany otwierały się bez iframe.
  • Testuj proces edycji, nie samo wczytanie strony. Awarie przy niszczeniu węzłów ujawniają się dopiero wtedy, gdy bloki są wstawiane, przenoszone i usuwane. Test dymny, który otwiera wpis i mu się przygląda, przejdzie na zepsutej instalacji.
  • Ustaw kolejność według obciążenia redakcyjnego. Strona, której zespół publikuje codziennie, musi być czysta przed 19 sierpnia. Wizytówka edytowana dwa razy w roku nie musi.

Nic z tego nie jest egzotyczne. To inwentaryzacja, grep i macierz testów, czyli rzecz, której miejsce jest w zaplanowanym cyklu, a nie w trybie awaryjnym. Jeżeli wolisz mieć to załatwione w ramach stałej współpracy, mieści się to w programie utrzymania stron WordPress, gdzie testowanie wydań rdzenia jest już wpisane w kalendarz. Wycena takich prac jest zawsze indywidualna, bo zależy od liczby stron i od tego, ile z nich stoi na kodzie, którego nikt już nie rozwija.

#Źródła

Następny krok

Przekuj artykuł w realne wdrożenie

Pod tym wpisem dokładam linki, które domykają intencję użytkownika i prowadzą dalej w strukturze serwisu.

Chcesz wdrożyć ten temat na swojej stronie?

Jeśli chcesz przełożyć wiedzę z artykułu na działającą stronę, sklep albo przebudowę serwisu, przygotuję konkretny zakres prac.

Powiązany klaster

Sprawdź inne usługi WordPress i bazę wiedzy

Wzmocnij swój biznes dzięki profesjonalnemu wsparciu technicznemu w kluczowych obszarach ekosystemu WordPress.

FAQ do artykułu

Często zadawane pytania

Najważniejsze odpowiedzi, które pomagają wdrożyć temat w praktyce.

SEO-readyGEO-readyAEO-ready4 Q&A
Czy w WordPressie 7.1 da się wyłączyć iframe?#
Nie. Gutenberg PR 74042 usunął ścieżkę edytora bez iframe, a recenzent tego pull requesta odnotował, że switchToLegacyCanvas() nic już nie robi. Nie ma filtra wyłączającego ani warstwy zgodności.
Czy każdy blok musi przejść na Block API w wersji 3?#
W 7.1 wartość apiVersion nie decyduje już o tym, czy edytor działa w iframe, więc samo podbicie numeru niczego nie naprawi. Wersja 3 jest deklaracją, że blok działa wewnątrz iframe, a właściwa praca polega na usunięciu założeń o globalnym dokumencie i oknie.
Dlaczego arkusz stylów edytora przestał obejmować treść?#
Style zarejestrowane na enqueue_block_editor_assets ładują się w zewnętrznym dokumencie kokpitu, czyli tam, gdzie żyje interfejs edytora. Style, które mają dotyczyć samej treści, należą do enqueue_block_assets, bo tylko ten hook sięga kanwy. Ten dokładny objaw śledzi zgłoszenie Gutenberga 53236.
Która wersja WordPressa sprawiła, że edytor wpisów zawsze działa w iframe?#
WordPress 7.1. Nota deweloperska do 7.0 mówi wprost, że w 7.0 iframe nie jest wymuszany, a test został tam jedynie zawężony do bloków faktycznie wstawionych we wpisie.

Potrzebujesz FAQ dopasowanego do branży i rynku? Przygotujemy wersję pod Twoje cele biznesowe.

Porozmawiajmy

Polecane artykuły