Skip to content

Handle browser refresh in Playground iframe#3649

Draft
akirk wants to merge 1 commit into
WordPress:trunkfrom
akirk:fix/iframe-refresh-shortcut
Draft

Handle browser refresh in Playground iframe#3649
akirk wants to merge 1 commit into
WordPress:trunkfrom
akirk:fix/iframe-refresh-shortcut

Conversation

@akirk
Copy link
Copy Markdown
Member

@akirk akirk commented May 15, 2026

Motivation for the change, related issues

Pressing Cmd+R or Ctrl+R while using Playground currently reloads the entire shell. That is especially disruptive for temporary Playgrounds and Personal WP, where the expected browser behavior is to refresh the current WordPress page without tearing down the embedding app.

Implementation details

  • Add active viewport shortcut handling in both the regular website and Personal WP.
  • Reload the current WordPress page through PlaygroundClient.getCurrentURL() and goTo() so only the inner WordPress iframe refreshes.
  • Add a remote-wrapper listener for the case where focus is on the remote.html document itself.
  • Relay refresh shortcuts from WordPress pages back to the embedding shell via the Playground mu-plugin, including the PHP 5.2 variant.

The mu-plugin piece is needed because the focused document owns the keyboard event. In the normal usage path the frame tree is:

Playground shell -> remote.html -> WordPress iframe

When focus is inside wp-admin, the site editor, the login screen, or the front end, the browser dispatches Cmd+R or Ctrl+R to the WordPress document. That keydown event does not bubble out to remote.html or to the outer Playground shell, so listeners attached only in those wrappers would miss the shortcut exactly where users most often press refresh. Document-Isolation-Policy can also make it unreliable for the wrapper to reach into the WordPress frame and attach a listener from the outside.

The mu-plugin is the existing bridge for WordPress-page scripts. It listens inside the WordPress document, prevents the browser-level page reload, and relays a playground-refresh message back to the shell. Without it, iframe-only refresh would work when focus is in Playground chrome, but not when focus is inside WordPress.

Existing Personal WP sites receive this on the next runtime boot without mutating the persisted site files. The web-specific Playground mu-plugin is written to /internal/shared/mu-plugins/1-playground-web.php during boot, before the persisted /wordpress OPFS mount is applied. /internal/shared is runtime-owned storage, so updating this source file updates the bridge script for both new and existing Personal WP sites once they load the new Playground runtime.

Testing Instructions (or ideally a Blueprint)

  • NX_ISOLATE_PLUGINS=false NX_DAEMON=false NPM_CONFIG_CACHE=/tmp/npm-cache NX_CACHE_DIRECTORY=/tmp/nx-cache npm exec nx run playground-website:typecheck
  • NX_ISOLATE_PLUGINS=false NX_DAEMON=false NPM_CONFIG_CACHE=/tmp/npm-cache NX_CACHE_DIRECTORY=/tmp/nx-cache npm exec nx run playground-personal-wp:typecheck
  • NX_ISOLATE_PLUGINS=false NX_DAEMON=false NPM_CONFIG_CACHE=/tmp/npm-cache NX_CACHE_DIRECTORY=/tmp/nx-cache npm exec nx run playground-remote:typecheck
  • ESLINT_USE_FLAT_CONFIG=false ./node_modules/.bin/eslint packages/playground/website/src/lib/hooks/use-browser-refresh-shortcut.ts packages/playground/website/src/components/playground-viewport/index.tsx packages/playground/personal-wp/src/lib/hooks/use-browser-refresh-shortcut.ts packages/playground/personal-wp/src/components/playground-viewport/index.tsx packages/playground/remote/src/lib/boot-playground-remote.ts
  • php -l packages/playground/remote/src/lib/playground-mu-plugin/0-playground.php
  • php -l packages/playground/remote/src/lib/playground-mu-plugin/0-playground-php52.php

Manual smoke test:

  1. Open the Playground website or Personal WP app.
  2. Focus the outer Playground UI and press Cmd+R on macOS or Ctrl+R on Windows/Linux.
  3. Confirm only the WordPress iframe reloads and the outer shell stays loaded.
  4. Click inside the WordPress iframe, including wp-admin or the login page, and press the same shortcut.
  5. Confirm the same iframe-only reload happens from inside the focused WordPress document.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant