EZ Page Sync
Documentation

EZ Page SyncUser Guide

Everything you need to install, connect, and run EZ Page Sync inside the WordPress dashboard — from first activation to rollback and troubleshooting.

Current as of v1.1.37

On this page

Introduction

EZ Page Sync pushes page and post edits from a staging WordPress site to a production site — safely, with cryptographically signed requests, automatic pre-sync snapshots, and rollback if anything goes wrong. No database migration, no full-site export, no manual copy/paste.

The plugin is installed on both sites, and each site is assigned a role:

RoleTypical siteWhat it does
SenderStagingCollects the page data, signs the request, and pushes it to the Receiver.
ReceiverProductionVerifies the request signature, validates the payload, and applies it to the database.

Sync payloads travel directly between your two sites over an HMAC-signed HTTPS connection. Your content never passes through EZ Page Sync's servers or any third party.

A single site can also run both roles at once Premium — useful for relay chains like staging → pre-prod → production.

Requirements

  • WordPress 6.9 or newer, on both sites
  • PHP 8.1 or newer
  • MySQL 5.7+ or MariaDB 10.3+
  • HTTPS on both sites — plain-HTTP sync requests are rejected
  • The same EZ Page Sync plugin installed and activated on both sites

Advanced Custom Fields is optional and detected automatically — if you sync ACF fields, ACF must be active on both ends. WordPress Multisite is not currently supported.

Installation

  1. Download the plugin zip (or grab your Premium copy from your Freemius account email).
  2. In wp-admin, go to Plugins → Add New → Upload Plugin, choose the zip, and click Install Now. Alternatively, unzip the ez-page-sync folder into /wp-content/plugins/.
  3. Click Activate.
  4. Repeat on the second site — the plugin must be active on both staging and production.

After activation, EZ Page Sync appears as its own item in the wp-admin sidebar menu. On first activation you'll see an optional opt-in screen for sharing basic diagnostic data — skipping it doesn't affect any functionality.

Quick Start: Connect Two Sites

EZ Page Sync uses one shared secret key between two sites. Follow these steps once and you're ready to sync.

  1. Install and activate EZ Page Sync on both the staging site and the production site.
  2. On the Settings tab of each site, set the Plugin Role: choose Sender on staging and Receiver on production.
  3. Generate an API Secret Key on one site (Settings tab →Regenerate Key), then copy that exact value into the API Secret Key field on the other site. Both sites must hold the identical key — it authenticates every sync request.
  4. On the Sender, go to Settings → Destinations and add a row with the Receiver's full site URL (e.g. https://example.com). Adding more than one destination is a Premium feature.
  5. Optionally, on the Receiver, restrict which IP addresses may send sync requests Premium, and list any trusted reverse-proxy IPs so client IPs are read correctly behind a load balancer.
  6. On the Sender's Settings tab, click Test Connection to confirm the two sites can communicate using the shared key.
  7. Go to the Sender's Sync Pages tab and use Preview or Sync on any page.
  8. To sync in the opposite direction, swap the Plugin Role on each site and add a Destination on the new Sender. The shared key already works both ways.

Regenerating the key invalidates existing connections immediately. If you click Regenerate Key later, update the other site right away or every sync will fail with an invalid-signature error.

The Admin Dashboard

The EZ Page Sync menu in wp-admin opens a tabbed dashboard. Which tabs you see depends on the site's role.

Sync Pages Sender

A searchable, filterable list of every syncable page and post. For each row you get a sync-status badge (In Sync, Pending, Sync Failed, or Never Synced), the last-synced time, and per-page Preview and Sync buttons. You can filter by post type, sort by modified/synced date or title, and select multiple pages for bulk sync Premium.

On the Free tier, pages built with Elementor show a Premium lock badge instead of sync controls — Elementor layouts live almost entirely in Elementor's own data, so syncing only the post content would publish a broken page.

The Sync Pages tab: a searchable list of pages and posts with In Sync, Pending, and Never Synced status badges, Sync Now buttons, and a status sidebar showing last sync time and connection state.
The Sync Pages tab on a Sender site — status badges per page, with the connection status sidebar on the right.

Sync Log

A paginated audit log of every sync event — success, failure, warnings, and rollbacks — filterable by status, date, and post type. The Free tier keeps the most recent 50 entries; extended retention and CSV export are Premium.

The Sync Log tab: filter controls for status, event, date range, and destination above a table of sync events, each showing page title, event type, status, destination details, and duration.
The Sync Log — every event with its destination, result, and duration, filterable and exportable to CSV.

Rollback Manager ReceiverPremium

Lists the pre-sync snapshots captured on this site, with a one-click Restore (with confirmation) for each. See Snapshots & Rollback for how snapshots work — automatic rollback on failure works on every tier; this tab adds manual, on-demand restores.

The Rollback Manager tab on a Receiver site: a content selector for choosing a post to view and restore its snapshots, next to the status sidebar.
The Rollback Manager on a Receiver — pick a post to list its stored snapshots and restore one.

Settings

All configuration in one place: role, destinations, the API Secret Key, Test Connection, and the sync toggles documented in the Settings Reference below.

Help & FAQ

A built-in copy of the connection walkthrough plus answers to common questions — handy when you're inside wp-admin and don't want to leave the dashboard.

Bonus: the editor metabox

You don't have to visit the dashboard to sync. Every syncable page and post gets an EZ Page Sync metabox in the editor sidebar showing its current sync status and last-synced time, with a sync-mode selector (Full Sync / Content Only) and Sync and Dry Run buttons. Edit, hit Sync, done.

Sync Modes

ModeWhat it doesWhen to use it
Full SyncSyncs everything covered in What Gets Synced — content, meta, media, taxonomies, integrations.The default. Publishing a finished page.
Content OnlyJust the post body, title, and slug.Copy tweaks where nothing structural changed.
PreviewShows the match confidence and any warnings (e.g. a title mismatch on production) without writing anything.Checking which production post a sync will hit before you commit.
Dry RunRuns the entire pipeline — validation, media, meta — without a single database write, and returns a diff summary.Verifying a risky sync end-to-end first.
Bulk SyncPremiumPushes multiple selected pages in one operation.Releasing a batch of changes at once.
Force SyncExplicitly overrides an ambiguous-match warning after you've reviewed it. Available on every tier.You've confirmed via Preview that the flagged target is correct.

Destructive status changes (for example, a sync that would unpublish a live production page) are held back with an explicit warning until you confirm them with a force sync.

What Gets Synced

  • Post content, title, slug, status, and dates
  • All custom post meta (custom fields) Premium
  • ACF fields, matched by key with a name-based fallback Premium
  • Elementor layouts, including images and Global Widget / Template references remapped to production IDs Premium
  • Astra theme meta Premium
  • Yoast SEO meta fields Premium
  • Taxonomy assignments across all registered taxonomies Premium
  • Featured images and inline media attachments Premium
  • URL rewriting — staging URLs found in content and meta are rewritten to production URLs on arrival

How media is handled

Media files are embedded in the sync payload itself (base64-encoded), so the production site never needs filesystem or FTP access to staging. On arrival, each file is matched against the production media library by filename: existing attachments are reused, and the Overwrite Existing Media setting decides whether a name collision replaces the file or keeps the production copy. After upload, attachment metadata and image sizes are regenerated and content URLs are rewritten to point at production.

What is never synced

WordPress housekeeping meta is excluded automatically:_edit_lock, _edit_last, _wp_old_slug, _wp_old_date, _pingme, _encloseme, and the plugin's own internal sync-tracking keys. You can add your own exclusion keys in Settings.

After a successful sync

The plugin purges the synced page from common page caches automatically — WP Super Cache, W3 Total Cache, LiteSpeed Cache, and WP Rocket are all supported, with WordPress's own post-cache flush as the fallback. If a Notify Email is configured, a summary email is sent on completion (success or failure).

Settings Reference

The Settings tab: settings access role, plugin role checkboxes for Sender and Receiver, the destinations table, encrypted API secret key fields with regenerate and save buttons, test connection, sync post type checkboxes, and toggles for ACF fields, custom meta, media, dry run mode, and connection timeout.
The Settings tab on a Sender site — every option below lives here.
SettingApplies toDescription
Plugin RoleBothSender (staging) or Receiver (production). Running both roles at once is Premium.
DestinationsSenderThe Receiver site URL(s) to push to. More than one destination is Premium.
API Secret KeyBothAuto-generated shared secret that signs every request. Must be identical on both sites. Stored encrypted (AES-256-GCM).
Allowed Sender IPsReceiverComma-separated IP allowlist, CIDR supported (IPv4 + IPv6). Editing is Premium; a configured list keeps being enforced even if a license lapses.
Trusted Proxy IPsReceiverReverse proxies / load balancers whose forwarded-IP headers should be trusted when resolving the sender's real IP.
Sync Post TypesBothWhich post types are syncable. Free covers page andpost; custom post types are Premium.
Sync ACF FieldsBothInclude ACF field values in syncs. Premium
Sync Custom MetaBothInclude all other custom post meta. Premium
Sync MediaBothTransfer featured images and inline attachments. Premium
Overwrite Existing MediaBothOn filename collision, replace the production file instead of keeping it.
Auto Rollback on FailureReceiverRestore the pre-sync snapshot automatically if a sync fails. On by default.
Settings AccessBothRestrict who can open the plugin settings to a specific role or user. Premium
Max Log EntriesBothSync Log retention. Capped at 50 on Free; higher/unlimited is Premium.
Enable Dry Run ModeSenderExpose the Dry Run action on syncs.
Notify EmailBothAddress that receives the per-sync summary email.
Connection TimeoutSenderSeconds to wait for the Receiver before marking the sync failed. Default 30.

Snapshots & Rollback

Before every sync, the Receiver captures a snapshot of the target page's current state. Rollback then works two ways:

  • Automatic — if a sync fails partway through (a database write error, an invalid payload), the page is restored from the snapshot immediately, so production is never left half-updated. Controlled by theAuto Rollback on Failure setting, on by default, available on every tier.
  • ManualPremium — the Rollback Manager tab lists stored snapshots and restores any of them with one click, even days after a "successful" sync you've changed your mind about.

Up to 5 snapshots are kept per post. Snapshots expire after 30 days on the Free tier (extended retention is Premium). Rolling back never deletes media files — only post data is restored.

Security Model

Every sync request is authenticated and validated before a single byte touches the production database:

  • HMAC-SHA256 request signing — the signature covers the post ID, timestamp, nonce, and a hash of the full payload, so a request can't be forged or tampered with in transit.
  • Replay protection — each request carries a one-time nonce (10-minute TTL, rejected if reused) and its timestamp must fall within a ±5-minute window.
  • HTTPS enforced — plain-HTTP requests are rejected outright.
  • Rate limiting — the Receiver accepts at most 60 sync requests per hour per sender IP (health-check pings don't count).
  • IP allowlistPremium — restrict the Receiver to known sender IPs, with CIDR ranges, IPv4 and IPv6. Forwarded-IP headers are only trusted from your configured Trusted Proxy IPs.
  • Encrypted key storage — the API Secret Key is stored with AES-256-GCM authenticated encryption, not in plaintext.
  • WordPress capability checks — all admin actions require the appropriate capabilities and are nonce-protected.

And to repeat the most important property: sync traffic flows directly between your own two sites. There is no relay server, and no third party ever sees your content.

Free vs. Premium

The Free tier is not a trial. It's a permanently usable single-destination page/post sync tool with no time limits, quotas, or forced downgrades on anything it supports. Premium adds capacity and integrations on top.

FeatureFreePremium
Sync destinations1Unlimited
Plugin roleSender or ReceiverBoth simultaneously
Post typesPage, PostAny custom post type
ACF / custom meta / Yoast / taxonomy syncIncluded
Elementor syncIncluded
Astra theme meta syncIncluded
Media sideloadingIncluded
Bulk syncIncluded
IP whitelistIncluded
Settings access restrictionEditors & AdminsAny role / specific user
Rollback Manager UIIncluded
Log retention / CSV exportCapped at 50 rowsExtended, unlimited, CSV export

If a Premium license lapses, nothing is deleted: configuration beyond the Free caps simply goes inactive until the license is active again, then reactivates automatically.

Troubleshooting & Error Codes

Common issues

  • "Invalid HMAC signature" (EZ_PS_001) — the API Secret Key differs between the two sites. Copy the exact key from one Settings tab to the other. This is also what you'll see if one side regenerated the key and the other wasn't updated.
  • "Timestamp out of window" (EZ_PS_002) — the server clocks disagree by more than 5 minutes. Fix the system time (usually NTP) on the drifting host.
  • "Rate limit exceeded" (EZ_PS_005) — the Receiver allows 60 sync requests per hour per sender IP. Wait for the window shown in the error to reset, or space out bulk syncs.
  • "HTTPS required" (EZ_PS_013) — one of the sites is being reached over plain HTTP. Check the destination URL starts with https:// and that SSL is valid on both ends.
  • "Sync already in progress" (EZ_PS_CONCURRENT_SYNC, HTTP 429) — another sync for the same post is mid-flight on the Receiver. This is a transient lock; retry after a few seconds.
  • Sync button missing on a page — if the page was built with Elementor on the Free tier, it's Premium-locked (see Sync Pages). Otherwise check the post type is enabled under Sync Post Types in Settings.

Error code reference

Every failure is logged in the Sync Log with one of these codes:

CodeMeaning
EZ_PS_001Invalid HMAC signature — key mismatch or secret not configured
EZ_PS_002Timestamp out of window — server clock drift over ±5 minutes
EZ_PS_003Nonce already used — replayed request rejected
EZ_PS_004Sender IP could not be determined or is not whitelisted on the Receiver
EZ_PS_005Rate limit exceeded (60 requests/hour/IP)
EZ_PS_006Invalid payload — request body is not valid JSON or fails schema
EZ_PS_007Post not found on the Receiver
EZ_PS_008Internal receiver error — check the sync log for details
EZ_PS_009Media sync failed
EZ_PS_010Snapshot creation failed on the Receiver
EZ_PS_011Rollback failed — missing or invalid snapshot_key
EZ_PS_012Sync lock active — another sync is running for this page
EZ_PS_013HTTPS required — plain-HTTP request rejected
EZ_PS_014ACF not active on the Receiver — ACF sync skipped with a warning
EZ_PS_015Partial sync — content applied but media failed
EZ_PS_016Production post is linked to a different staging site
EZ_PS_018Destructive status change requires an explicit force sync
EZ_PS_019Post type missing from the payload
EZ_PS_020Post type not allowed or not registered on the Receiver
EZ_PS_022Concurrent edit detected on production during sync

Failed syncs never leave production half-updated: any database write failure triggers an automatic rollback to the pre-sync snapshot (when Auto Rollback is enabled, which is the default).

Deactivation & Uninstall

Deactivating the plugin is non-destructive: all settings, the sync log, and stored snapshots are preserved, so you can reactivate and pick up where you left off.

Deleting the plugin from the Plugins screen removes everything it created — its options, the sync log table, and its per-post sync metadata. No other WordPress data is touched, and no synced content is ever removed from production.

Ready to sync?

Install EZ Page Sync on your staging and production sites and push your first page in minutes.

Download Free