How to add session replay to a WordPress site

Configure replay masking in the WordPress plugin. Record a synthetic visit and verify its content and analytics association.

  • WordPress 6.3+
  • Custom plugin
  • Browser SDK 2
  • CDN
  • 20 min

Chris Tam · Last updated 16 October 2026

WordPress themes and plugins can put private text beside the controls you want to inspect. Session replay records the interaction, while masking and blocking control the content captured from the page.

In this tutorial, I'll extend the existing replay registration, mark synthetic private regions, and compare a processed recording with its analytics activity.

What you'll build

A WordPress replay with synthetic form input and private text masked, an excluded container blocked, and the visit associated with analytics.

Prerequisites

  • A staging WordPress site with permission to upload a custom plugin and edit wp-config.php. This tutorial uses a plugin you control. On managed hosting, confirm that your plan permits those changes.
  • WordPress 6.3 or later and PHP 7.4 or later, plus a theme that calls wp_head() and wp_footer(). The executable example was tested on WordPress 6.9.10 and PHP 8.3.33.
  • An Amplitude project API key: Settings > Projects > your project > General > Manage next to API Key. Managers and Admins can view it. The browser key is public and limited to the minimum scope needed for ingestion. Keep secret keys out of this plugin.
  • The shared plugin and public Home and Pricing pages. Keep the shortcode form when following the product analytics tutorial.
  • Session replay access for the project and an Admin or Manager for capture settings.

A free Amplitude account covers this example within its product limits. Sign up for free to get your project API key.

1. Extend the existing replay registration

In analytics.js, change only the replay options. Keep the existing guard, loader, initializer, and server zone. The replay plugin reference documents these privacy options.

analytics.js: replace only the existing replayOptions declaration
// analytics.js: replace only the existing replayOptions declaration
const replayOptions = {
  sampleRate: 1,
  serverZone: config.serverZone,
  privacyConfig: {
    defaultMaskLevel: 'conservative',
    maskSelector: ['[data-replay-mask="true"]'],
    blockSelector: ['[data-replay-block="true"]']
  }
};

Do not add another replay plugin or reinitialize analytics. Remote privacy settings take precedence where they conflict. Use 100% sampling only on your synthetic test site, then lower it and inspect the effective setting before production.

2. Mark private content in WordPress

Add a Custom HTML block on Pricing, or apply the same attributes in your template. The shortcode's input already has the masking attribute. Keep data attributes intact when the editor saves the content.

Pricing page: Custom HTML block
<!-- Pricing page: Custom HTML block -->
<p data-replay-mask="true">FAKE_PRIVATE_TEXT_123</p>
<section data-replay-block="true">FAKE_PRIVATE_DOCUMENT_123</section>

Use a synthetic email such as replay-qa@example.invalid. Do not unmask inputs for this test. Masking applies to text and inputs, not HTML attribute values, URLs, or text inside images and videos. Keep sensitive data out of attributes and URLs; block sensitive media with an appropriate selector. Masking content is separate from deciding when consent permits the SDK to run.

3. Enable capture and make a test visit

In Settings > Organizational Settings > Session Replay Settings, select the test project and enable capture. Inspect sampling and privacy settings. If remote settings manage sampling, set the synthetic test rate there. Purge relevant WordPress and CDN caches after deploying the plugin changes.

Browser Console: record this device ID before the test sequence
// Browser Console: record this device ID before the test sequence
window.amplitude.getDeviceId();

Open Home, follow Pricing, click the CTA, type the synthetic email, and use the test form if it is installed. This gives the replay a known sequence.

4. Inspect processed playback and lower sampling

Inspect the plugin configuration and remote sampling and privacy settings. In Instrumentation Explorer, find [Amplitude] Session Replay ID on a Session Start or Session End event. Find the recording in Amplitude and play it. Replays are generally available about five minutes after the session begins. Confirm the sequence, identity association, masked text and input, and blocked container.

analytics.js: change only sampleRate inside the existing replayOptions
// analytics.js: change only sampleRate inside the existing replayOptions
sampleRate: 0.01,

Keep the privacy options. Update the remote test rate too when sampling is managed there, then verify the effective value. One uncaptured session at a low rate is not evidence that replay is broken.

MCP: Ask your coding agent to inspect the project's event taxonomy with the Amplitude MCP server before adding events. Reuse existing names when they describe the same action.

Verify it worked

  1. WordPress output: Open the public staging page while logged out. Check that the project loader appears once and its inline initialization follows it. After deployment or configuration changes, purge the relevant page and CDN caches.
  2. Network: Confirm an event POST receives HTTP 200 from api2.amplitude.com for US projects or api.eu.amplitude.com for EU projects. Large batches can be compressed; use this check for delivery status.
  3. Instrumentation Explorer: Inspect event names, properties, counts, and device_id in the Chrome extension. Compare one action with one expected custom event.
  4. User Profiles: Search that device ID in Amplitude and inspect its event stream. The docs describe a delay of ten seconds to one minute. Data > Sources > Ingestion Debugger shows request and event counts, rather than individual event payloads.

Complete the playback and masking checks in step 4; upload acceptance alone is not processed replay verification.

Troubleshooting

Events arrive but replay does not

Check capture settings, effective sampling, quota, and replay requests. If required remote privacy configuration cannot load, replay capture stops rather than recording without it.

The plugin is active but no SDK loads

Check that AMP_BUILD_API_KEY is defined before wp-settings.php, then inspect the public page source. This plugin uses the front-end enqueue hook, so its SDK is absent from the WordPress login and administration pages.

The script order differs from the example

Check caching and script-optimization exclusions for amp-build-sdk and amp-build-engagement. The project loader and inline initialization must remain together. Check for an earlier installation in a theme, tag manager, or snippet plugin.

Requests are blocked

Check the key, region, browser extensions, and Console. Follow the relevant SDK's CSP and endpoint guidance while preserving your site's security policy.

Autocapture settings differ from the file

Review Data > Settings > Autocapture. When remote configuration is enabled, remote values take precedence for the features they specify.

FAQ

Does successful analytics ingestion prove replay works?

Check replay capture and processed playback separately. An event POST verifies analytics delivery.

Why do effective privacy settings differ from my file?

Inspect the project's remote privacy settings and verify masking in processed playback. Remote settings take precedence when they conflict with local settings.

Full code reference

Unchanged from earlier pages; keep your versions: amplitude-build.php, demo.php, events.js, engagement.php, experiment-consent.js. Merge the changes into existing files; preserve sibling additions named in the comments.

wp-content/plugins/amplitude-build/analytics.js
// wp-content/plugins/amplitude-build/analytics.js
// Keep sibling additions: replay privacyConfig (/build/wordpress-session-replay).
(() => {
  if (window.ampBuildReady) return;
  if (!window.amplitude || !window.sessionReplay) {
    console.warn('Amplitude did not load. Check the CDN request and site policy.');
    return;
  }
  const config = window.ampBuildConfig;
  const replayOptions = { sampleRate: 1, serverZone: config.serverZone,
    privacyConfig: {
      defaultMaskLevel: 'conservative',
      maskSelector: ['[data-replay-mask="true"]'],
      blockSelector: ['[data-replay-block="true"]']
    } };
  window.amplitude.add(window.sessionReplay.plugin(replayOptions));
  window.ampBuildReady = window.amplitude.init(config.apiKey, {
    serverZone: config.serverZone,
    remoteConfig: { fetchRemoteConfig: true },
    autocapture: {
      attribution: true,
      pageViews: { trackHistoryChanges: 'pathOnly' },
      sessions: true,
      formInteractions: true,
      fileDownloads: true,
      elementInteractions: false,
      frustrationInteractions: false,
      networkTracking: false,
      webVitals: false
    }
  }).promise;
})();

Hand it to your agent

Point your agent at https://amplitude.com/build/wordpress-session-replay.

Agent prompt
Agent task: WordPress session replay.
Merge conservative privacy into the existing replay options. Preserve analytics init, server zone, form handlers, guides, and experiment consent. Use synthetic text and input, inspect replay upload and decoded content, then open processed playback and verify association. Lower test sampling afterward. Separate the test runtime from hosted production verification.

What this unlocks

Product analytics measures the accepted-form outcome when Demo Form Accepted is installed.

Session replay shows the interaction around the test form after capture and masking are verified.

Web Experiment can use Demo Form Accepted as a conversion metric.

Guides and surveys can ask a visitor what they need on Pricing after targeting is configured.

Next steps

Add Amplitude to your WordPress site

Start with one shared plugin and follow the tutorials for each product.