WordPress.org

WordPress Developer Blog

Introduction to Playground: running WordPress in the browser

Introduction to Playground: running WordPress in the browser

Have you heard about WordPress Alchemy? It’s a serverless version that runs inside the browser and goes by WordPress Playground.

Developed by Adam Zieliński in 2022, this groundbreaking project isn’t alchemy, it’s WebAssembly (WASM). The same technology used to drive browser-based IDEs is at the core of Playground, supporting Zieliński‘s vision to empower developers, users, learners, extenders, and contributors.

Zieliński’s motivation was to overcome the challenges of setting up a local development environment as a prerequisite to building a WordPress site. Playground relieves you from the typical hassle and invites you to step into a new world of bliss where nothing can go wrong—a fresh instance is just a quick refresh away.

You can use Playground to showcase, test, and build themes, plugins, blocks, even entire sites. It’s a single-click, zero-setup environment for development, code reviews, design experiments, handovers, onboarding, and education: you can also embed a live instance in any webpage using an <iframe> element, giving new life to WordPress tutorials.

The triple foundation

Playground is composed of three interchangeable APIs, which you can mix and match as needed:

  • The Query API – a no-code browser-based configuration that allows you to add parameters to the Playground URL.
  • The Blueprint API – a low-code JSON-based configuration file that serves as a build script for your WordPress installation.
  • The JavaScript API – an NPM package to import a Playground client into an app or website.

You can combine the three APIs: Most of the attributes of the Query API map to the Blueprint API, which means you could write the structured data (Blueprint) as a URL fragment (Query). Add a pound sign (#) after the .net/ and paste your configuration (links open in new tabs): https://playground.wordpress.net/#{"preferredVersions": {"php":"7.4", "wp":"6.3"}}

Or use both formats, like so:

https://playground.wordpress.net/?mode=seamless#{"preferredVersions": {"php":"7.4", "wp":"6.3"}}

API mapping

When combined, Playground would ignore any Blueprint-supported parameters set via the Query API. So, mode and storage—only available via the Blueprint API—are always valid, but plugin, not necessarily. For example, running https://playground.wordpress.net/?mode=seamless&plugin=gutenberg#{"plugins": [gutenberg]}

Would result in https://playground.wordpress.net/?mode=seamless#{"plugins": [gutenberg]}.

If your Blueprint isn’t too complicated, you don’t even need to encode it—append the URL with supported attributes, and the browser will take care of the rest.

When it gets too wieldy, you can reference a JSON file in the URL, like this:

https://playground.wordpress.net/?blueprint-url=https://PATH/TO/YOUR/blueprint.json

Finally, you can write the Blueprint inside the code of a JavaScript API-based instance.

Click here for an example that creates and opens a new post:
<body>
	<iframe id="wp-playground" title="Demo Playground instance" style="width: 100%; height: 100dvh; border: 1px solid currentColor;"></iframe>
	<script type="module">
		import { startPlaygroundWeb } from 'https://unpkg.com/@wp-playground/client/index.js';
		const client = await startPlaygroundWeb({
			iframe: document.getElementById('wp-playground'),
			remoteUrl: `https://playground.wordpress.net/remote.html`,
			blueprint: {
				"landingPage": "/?p=3",
				"preferredVersions": {
					"php": "8.0",
					"wp": "latest"
				},
				"features": {
					"networking": true,
				},
				"steps": [
					{
						"step": "login"
					},
					{
						"step": "runPHP",
						"code": "<?php require_once('/wordpress/wp-load.php'); wp_insert_post(['ID' => 3, 'post_title' => 'Created by a Blueprint', 'post_content' => '<!-- wp:paragraph --><p>Hoora!</p><!-- /wp:paragraph -->', 'post_status' => 'publish']);"
					}
				]
			}
		});
		await client.isReady();
	</script>
</body>

Cross-platform development environment

Playground is perfect for quick prototyping, but it also supports local development via the WP-NOW package and the VS Code extension. A great perk of using the extension is having auto-complete and validation in the IDE. Declare the Blueprint JSON schema ("$schema": "https://playground.wordpress.net/blueprint-schema.json") at the top of your JSON file, and the editor will pop little hints as you type.

A local WordPress development environment isn’t new, of course; MAMP and XAMPP have been here forever, and more recent GUI and CLI tools like WP-Engine’s Local, Kinsta’s DevKinsta, and WordPress’s own WP-ENV simplify local installation.

However, none is as fast, seamless, and lightweight as WP-NOW, or portable as Playground’s VS Code extension. Furthermore, while all these platforms require a computer, Playground is as technically agnostic as browsers would allow it: Playground is cross-platform, partially works offline, and every new functionality is measured by its usability and accessibility, considering instrumental support for different devices and contexts, including smartphones and tablets.

Get to know the APIs

Learn how to take advantage of Playground’s layers of functionality to create interactive demos and share your work without ever leaving your browser.

No-code: the Query API

Playground is an excellent way to get familiar with WordPress. Type https://playground.wordpress.net (opens in new tab) in your browser address bar, hit Enter, and start exploring.

Want to test a specific theme from the WordPress theme directory? Add a question mark  (?) after the .net/, and type theme=the_theme_slug. How about a plugin? Locate it in the plugin directory, get the slug, and write plugin=the_plugin_slug.

You can also do both and add as many attributes as you’d like: just separate them with an ampersand (&). Here’s an example URL query that allows you to explore the latest beta version:

https://playground.wordpress.net/?plugin=gutenberg&theme=ollie&mode=seamless&wp=nightly (opens in a new tab)

Play around with the query to test out different variations: replace seamless with browser, nightly with 5.9, ollie with stacks, or remove &plugin=gutenberg to see the changes:

https://playground.wordpress.net/?mode=browser&wp=5.9&theme=stacks (opens in a new tab)

Enable local storage

Playground instances are temporary by design; once you refresh or close the tab, all your changes will be gone. To make it less ephemeral, enable the browser storage option: using the Query API, add storage=browser to the URL or click the Settings button on the top-right and select the storage type. After you refresh, you’ll see that the warning emoji (⚠️) disappeared.

You can chain as many plugins as you’d like (?plugin=jetpack&plugin=woocommerce), or open a specific page—in the admin or front end: (links open in new tabs)

Playground will download and install everything, log you in, activate the theme and plugin you chose, and spin up a fresh copy of your custom WordPress within seconds.


Build a site and share it

When you launch a standard Playground instance (not in seamless mode or via the JavaScript API), you’ll notice a new simulated browser chrome above the familiar WordPress admin bar.

Because Playground runs inside an <iframe>, interacting with the browser’s address bar and window control buttons has no effect on the WordPress instance that runs inside it. In fact, if you try to navigate to another page by manually typing something like https://playground.wordpress.net/wp-admin, you’ll get a 404 error page. Hence, the mockup toolbar.

Other than serving as an address bar, Playground’s top navigation bar includes the following:

  1. A green circle that expands and shrinks the instance’s window (effectively functioning as a UI-based mode changer).
  2. Settings button that indicates which PHP and WordPress versions you’re running and whether local storage is enabled. Click it to open the Customize Playground modal and configure your instance. When you hit the Apply changes button at the bottom, Playground appends them to the URL via the Query API and reloads the modified instance.
  3. An Additional actions menu button that features several extra tools and links to the documentation site.

One of these allows you to build and share a complete site: run a Playground instance, make changes, and go to Additional actions -> Download a .zip to save a zipped file of the project—changes included. You can either share the zipped project with others who will be able to load it manually (Additional actions -> Restore from .zip) or store it online and send them a custom link so they’ll hit the ground running:

https://playground.wordpress.net/?import-site=https://PATH/TO/YOUR/wordpress-playground.zip

The Database
The ZIP file includes a copy of the database, located in /wp-content/database/.ht.sqlite. It’s a hidden file, but if you’re using VS Code, you can install the SQLite Viewer extension to browse it.

Low-code: the Blueprint API

Using the address bar is fine, but what if you want to replicate this configuration, iterate, share it with clients, or allow people to test your plugin? That’s where the Blueprint API comes in.

Functioning as build scripts, these JSON files let you create a whole website, including content (posts, pages, taxonomy, and comments), settings (site name, users, permalinks, and more), and, as mentioned above, themes and plugins. You can generate a WooCommerce store complete with products, a magazine populated with articles, a corporate blog with multiple users, and more.

Blueprint helper: Use the Blueprint editor (a WIP) to validate your code in the browser.

The Blueprint API supports advanced use cases, like file system and database manipulation, and gives you fine-grained control over the instance you create. The WordPress Test Team has been using Playground in the 6.5 beta release cycle, creating a Blueprint that loads the latest version, several testing plugins, and dummy data.

It’s worth exploring the schema and the documentation to learn about the features and attributes Playground supports.

For example, even when you’re just looking to install a plugin or a theme, there are a few sources you can use (the official Plugins directory, any publicly accessible URL, or a file in your GitHub repository), and you can decide whether to activate them automatically or not. The same goes for content: you can import a WXR file, create content on the fly right in the Blueprint, or run a script in the plugin you’re showcasing, like this clever implementation.

Blueprint v2

The team is exploring ways to transition Blueprints from a TypeScript library to a PHP library. The proposed new specification is discussed on a separate GitHub repository, and you’re more than welcome to join (there or on the #meta-playground Slack channel) and help shape the next generation of Playground.

You can define PHP functions—WordPress or native—and run it as raw code or part of a custom Must-use (MU) plugin. You can do all sorts of file system operations: create, move, copy, or delete files and directories. You can run SQL queries (RunSqlStep), import WordPress directories (ImportWordPressFilesStep) that will replace Playground’s default wp-* directories, set up a multisite network (EnableMultisiteStep), and run WP CLI commands.

Say you wanted to share a plugin you’ve developed and notify users that they’re inside a Playground instance. One way to do that is by using the admin_notice hook to display a message on specific pages.

Click here to see what the Blueprint looks like:
{
 "landingPage": "/wp-admin/plugins.php",
 "features": {
   "networking": true
 },
 "steps": [
   {
     "step": "login"
   },
   {
     "step": "installPlugin",
     "pluginZipFile": {
       "resource": "url",
       "url": "https://raw.githubusercontent.com/{USER}/{REPO}/{BRANCH}/{PLUGINFILENAME}.zip"
     },
     "options": {
       "activate": true
     }
   },
   {
     "step": "writeFile",
     "path": "/wordpress/wp-content/mu-plugins/playground-notice.php",
     "data": "<?php add_action('admin_notices', function() {  echo '<div class=\"notice notice-info is-dismissible\"><p>Hello from WordPress Playground</p></div>'; });"
   }
 ]
}

Troubleshooting

Because it runs inside a browser, Playground has a few gotchas:

  • Require wp-load: to run a WordPress PHP function using the runPHP step, you’d need to require wp-load.php. So, the value of the "code" key should start with "<?php require_once('wordpress/wp-load.php'); REST_OF_YOUR_CODE".
  • Enable networking: to access wp.org assets (themes, plugins, blocks, or patterns), or load a stylesheet using add_editor_style() (say, when creating a custom block style), you’d need to enable the networking option: "features": {"networking": true}.

The JavaScript API

This developer-oriented API allows you to run Playground on your infrastructure, using it as a framework not just for WordPress websites but for entirely new apps.

A prime example of what can be achieved with the JavaScript API is the latest version of the WordPress Playground Block, a trippy, M. C. Escher-like way of running WordPress inside WordPress. The plugin supports all the standard Playground features, plus an interactive code editor to prototype plugins inside a post. In the demo, Zieliński loaded the plugin with a preconfigured Blueprint:

This API’s capability is particularly effective for creating handovers that go beyond textual documentation and provide a layer of interactivity. In the next part of this miniseries, we’ll cover that specific use case in detail.

Stay tuned.

From the Playground to the field

Playground is an experimental project that keeps evolving, but it’s not a rough beta. WordPress contributors use it to test Gutenberg and core PRs and transform their block tutorials into interactive demos. Developers can add a Preview button to their plugin submissions or Theme Trac tickets, and soon, it’ll alert contributors about new PRs.

What can you do with Playground? Check out the Blueprints examples and the various demos and apps in the docs to learn more about the (endless) possibilities. Hopefully, it’ll inspire you to add some new moves to your playbook.

Props to @bph, @zieladam, and @greenshady for reviewing this post.
Props to @zzap, @ndiego, @annezazu, and @flexseth for their feedback.

5 responses to “Introduction to Playground: running WordPress in the browser”

  1. NICHOLAS AMOL GOMES Avatar

    Thanks for article page

  2. Sarankumar Avatar

    Thank you for your article. We’re currently experimenting with blueprints for our plugin. It seems the playground is loading very slowly compared to another service like Tastewp. Our plugin is built for WooCommerce, so using some steps, we can activate WooCommerce and later activate our plugin. It works fine. However, importing sampleproducts.csv from a URL is not working. The blueprint we are trying is for WC Messaging: https://wordpress.org/plugins/wc-messaging.

  3. leg10narsk1 Avatar

    One more amazing thing related to WP. Just read it on mobile, now need to test it on desktop. At the moment I’m using InstaWP for testing if client host doesn’t offer staging space.

  4. Phil Johnston Avatar
    Phil Johnston

    So cool

  5. wibergsweb Avatar

    Hi. I have created a plugin that has functionality to import a file into wp-content/uploads and this seems to work, but it doesn’t seem to work to READ the file.
    The functionality works on my local server and other external sites and I guess the issue is somehow that it points to incorrect path because Playground uses some kind of scope. Please come back to back to me if you want more information or if you have any direct feedback on this one.

    Otherwise this is a fantastic tool for the WP Community!

Leave a Reply

Your email address will not be published. Required fields are marked *