স্কিপ করে মূল কন্টেন্ট এ যান

Host your own Playground

You can host the Playground on your own domain instead of playground.wordpress.net.

This is useful for having full control over its content and behavior, as well as removing dependency on a third-party server. It can provide a more customized user experience, for example: a playground with preinstalled plugins and themes, default site settings, or demo content.

Before you start

Self-hosting Playground gives you full control, but requires understanding a few key concepts:

What to expect

  • Initial setup complexity: Building and deploying Playground involves multiple steps. Allow time for troubleshooting during your first deployment.
  • Static file hosting: Playground is primarily static files (HTML, JS, WASM) with minimal server-side requirements.
  • Browser-based execution: All WordPress processing happens in the user's browser via WebAssembly—your server only delivers files.

Performance considerations

Loading times depend on several factors:

FactorImpactOptimization
Plugin sizeLarge plugins (e.g., WooCommerce) can take 30-60 seconds to installPre-install plugins in your WordPress build
Network speedWASM files are ~15-30MBUse CDN with proper caching headers
BrowserChrome/Edge perform best; Safari uses fallback mechanismsTest across browsers
DeviceMobile devices load slower than desktopWarn mobile users about longer load times

Browser compatibility

Playground works across modern browsers, but with some differences:

BrowserStatusNotes
Chrome/Edge✅ Best performanceFull support for all features
Firefox✅ GoodReliable performance
Safari✅ GoodRecent improvements significantly enhanced reliability
Mobile browsers⚠️ LimitedWorks, but with higher memory usage, and a 4G connection can impact the experience

Technical note: Safari uses MessagePorts instead of SharedArrayBuffer for streaming responses. This fallback works reliably but adds slight overhead compared to Chrome/Edge.

Usage

A self-hosted Playground can be embedded as an iframe.

<iframe src="https://my-playground.com"></iframe>

Or dynamically loaded by passing the remote URL to the Playground Client.

import { startPlaygroundWeb } from '@wp-playground/client';

const client = await startPlaygroundWeb({
iframe: document.getElementById('wp'),
remoteUrl: `https://my-playground.com/remote.html`,
});

Static assets

There are several ways to get the static assets necessary to host the Playground.

In order of convenience and ease:

  • Download pre-built package
  • Fork the repository and build with GitHub Action
  • Build locally

Download pre-built package

To host the Playground as is, without making changes, you can download the built artifact from the latest successful GitHub Action.

  • Click on Deploy Playground website.
  • In the section Artifacts at the bottom of the page, click playground-website.
  • It's a zip package with the same files deployed to the public site.

Fork the repository and build with GitHub Action

To customize the Playground, you can fork the Git repository.

Build it from the fork's GitHub page by going to: Actions -> Deploy Playground website -> Run workflow.

Build locally

The most flexible and customizable method is to build the site locally.

Create a shallow clone of the Playground repository, or your own fork.

git clone -b trunk --single-branch --depth 1 --recurse-submodules https://github.com/WordPress/wordpress-playground.git

Enter the wordpress-playground directory.

cd wordpress-playground

Install dependencies, and build the website.

npm install
npm run build:website

This command internally runs the nx task build:wasm-wordpress-net. It copies the built assets from packages remote and website into a new folder at the following path:

dist/packages/playground/wasm-wordpress-net

The entire service of the Playground consists of the content of this folder.

Summary of included files

The static assets include:

  • Data and WASM files for all available PHP and WordPress versions
  • remote.html - the core of Playground
  • index.html - the shell, or browser chrome
  • Web Worker script

You can deploy the content of the folder to your server using SSH, such as scp or rsync.

It is a static site, except for these dynamic aspects.

  • Apache server directive .htaccess file from the package remote

For these to work, you need a server environment with Apache and PHP installed.

NGINX configuration

As an alternative to Apache, here is an example of using NGINX to serve the Playground.

Refer to the source file

The example may be outdated. Please check the source file for the latest version.

The combined Apache .htaccess file looks like this.

AddType application/wasm .wasm

An equivalent in NGINX.

location ~* .wasm$ {
types {
application/wasm wasm;
}
}

You may need to adjust the above according to server specifics, particularly how to invoke PHP for the path /plugin-proxy.

Caddy web server doesn't require any special config to work.

Customize bundled data

The file wp.zip is a bundle of all the files for the virtual file system in Playground. There's a data file for each available WordPress version.

The package at packages/playground/wordpress-builds is responsible for building these data files.

Edit the build script in Dockerfile to create a custom bundle that includes preinstalled plugins or content.

To rebuild the WordPress builds after customizing the Dockerfile, run the following command:

npm run rebuild:wordpress-builds

To rebuild the website to include the custom WordPress builds, follow the instructions here.

Install plugins

Here's an example of installing plugins for the data bundle.

Before the section titled Strip whitespaces from PHP files.

# === Preinstall plugins ===

RUN cd wordpress/wp-content/mu-plugins && \
# Install plugins
for plugin_name in example-plugin-1 example-plugin-2; do \
curl -L https://downloads.wordpress.org/plugin/{$plugin_name}.latest-stable.zip -o {$plugin_name}.zip && \
unzip $plugin_file && \
rm $plugin_file && \
# Create entry file in mu-plugins root
echo "<?php require_once __DIR__.'/$plugin_name/$plugin_name.php';" > $plugin_name.php; \
done;

You can download plugins from URLs other than the WordPress plugin directory, or use Git to pull them from elsewhere.

It's also possible to copy from a local folder. For example, before RUN:

COPY ./build-assets/*.zip /root/

Then put the plugin zip files in build-assets. In this case, you may want to add their paths to .gitignore.

Import content

Here's an example of importing content.

# === Demo content ===

COPY ./build-assets/content.xml /root/
RUN cd wordpress ; \
echo "Importing content.."; \
../wp-cli.phar --allow-root import /root/content.xml --authors=create

This assumes that you have put a WXR export file named content.xml in the folder build-assets. You can add its path to .gitignore.

Production deployment checklist

Before going live, verify your self-hosted Playground meets these requirements:

Server configuration

  • MIME types: Ensure .wasm files are served with application/wasm content type
  • CORS headers: If embedding cross-origin, configure appropriate CORS headers
  • Caching: Set long cache times for WASM and static assets (they're versioned)
  • Compression: Enable gzip/brotli for faster file transfers
  • HTTPS: Required for service workers and some browser features

Performance optimization

  • CDN: Serve static assets from a CDN for faster global delivery
  • Pre-installed plugins: Bundle frequently-used plugins in your WordPress build
  • Limit additional downloads: Minimize runtime plugin installations (by blueprints, for example)

Troubleshooting

Common issues and solutions

Playground fails to load or shows blank screen

Possible causes:

  • Server doesn't serve WASM files with correct MIME type
  • Deployment missing required files
  • JavaScript errors in browser console

Solutions:

  1. Check browser console for errors (F12 → Console tab)
  2. Verify .wasm files return application/wasm content type
  3. Verify you deployed all build files

Slow initial loading (30+ seconds)

Possible causes:

  • Installing large plugins at runtime
  • Missing CDN or caching configuration
  • User on slow network connection

Solutions:

  1. Pre-install plugins in your WordPress build instead of runtime installation
  2. Configure CDN with proper caching headers
  3. Show loading indicators to set user expectations