Content Sync Pro Plugin for Strapi

Content Sync Pro Plugin for Strapi

By Ejaz Arain

Strapi v5 plugin to copy, migrate, and live-sync content, media, and data between multiple Strapi environments with bi-directional sync, field-level policies, scheduling, and alerts.

Latest version

v1.2.1

released August 14, 2026

npm install strapi-content-sync-pro

Content Sync Pro

Content Sync Pro for Strapi

Copy, migrate, and live-sync content, media, users, and relations
between any number of Strapi v5 environments.

npm version License: MIT Product page Strapi v5

Quick start · Screenshots · Full gallery · Video · Product page · Contact

Content Sync Pro — the Home hub inside the Strapi admin panel

The Home hub — connection status, deployment mode, and every section one click away.


Video

Watch the intro video on YouTube

Screenshots

Captured from a live 1.2.0 install — real profiles, real run history, real counts. Click any screen for its walkthrough, or open the full gallery for all fourteen.

Guided setup — connect to the remote server
Setup 1 · Connect
Remote URL, token, and deployment mode — validated before you save.
Guided setup — choose what to sync
Setup 2 · Choose scope
Toggle content types on; default profiles are generated for you.
Guided setup — run your first sync
Setup 3 · Run
Review the generated profiles and run your first sync.
Run profiles — ordering, dependencies, execution mode
Run profiles
Dependency-aware ordering, per-profile execution, run on demand.
Bulk transfer — chunked one-click transfer with progress
Bulk transfer
One-click full pull or push, chunked, pausable, resumable.
Media — sync profiles with live status and controls
Media
Files and DB rows, URL or rsync, with live status and controls.
Connection — remote URL, API token, deployment mode
Connection
Paired or single-side, with secrets masked in every response.
Content types — toggle what is in scope
Content types
Choose what is in scope, with direct dependencies pulled in.
Sync profiles — direction, conflict strategy, field policies
Sync profiles
Direction, conflict strategy, and field-level policies.
Advanced — enforcement policies and alerts
Advanced
Schema, version and clock checks, plus email/webhook alerts.
Stats — local vs remote counts and run reports
Stats
Local vs remote counts, newest side, and per-run snapshots.
Logs — searchable, filterable per-action sync log
Logs
Every action, with counters and messages, searchable.

→ See all 14 screens with a written walkthrough

Admin UI Navigation

The plugin mounts at /admin/plugins/strapi-content-sync-pro. Navigation is two-tier: a grouped primary bar, plus a secondary bar inside sections that have one. Every screen is a real, shareable URL.

Home hub with grouped navigation

GroupDestinationPathWhat it's for
StartHome/Connection status and entry points to every section
StartSetup/setup/connect, /setup/scope, /setup/runGuided first run: connect, choose scope, run your first sync
RunSync/sync · /sync/bulkRun profiles · Bulk transfer
RunMedia/mediaMedia sync profiles, live status and controls
Set upConfigure/configure/connection · /configure/content-types · /configure/profiles · /configure/advancedConnection · Content types · Sync profiles · Enforcement and alerts
MonitorHistory/history/stats · /history/logsStats and run reports · Detailed logs
MonitorHelp/helpStep-by-step guidance inside the admin panel

Old flat paths (/config, /content-types, /sync-profiles, /bulk-transfer, /stats, /logs) still resolve — they redirect to their new homes.

Features

  • Deployment Modes - Paired mode (plugin on both servers) or Single-side mode (plugin only on local server).
  • Bi-directional Content Sync - Push, pull, or sync both ways (Local wins, Remote wins, or Latest wins) in paired mode.
  • Media Sync - Full media synchronization via HTTP (URL-based) or host-level file copy (rsync). Includes MIME type filtering and concurrency controls.
  • Sync Profiles - Define WHAT to sync with field-level control (Advanced mode) or preset modes.
  • Execution Modes - On-demand, Scheduled (interval, timeout, cron, or external scheduler), Live (real-time), with per-profile execution controls.
  • Pagination & Large Dataset Support - Built-in pagination ensures stable memory usage even when syncing thousands of records.
  • Dependency Analytics - Automatically detects and syncs related entities and components in the correct order.
  • Enforcement Checks - Pre-sync schema compatibility validation, version checks, and server time drift checks.
  • Alerts & Logging - Detailed sync logs. Receive success/failure alerts via Email (using Strapi's email provider) or Webhooks.
  • Stats & Run Reports - Local/remote counts and newest timestamps per content type, with before/after snapshots for each sync run.
  • Bulk Transfer - One-click full pull or full push across selectable scopes (content, media, Strapi users, admin users), under Sync → Bulk transfer. Expands into per-content-type and per-media-profile chunks with page-level progress, selectable chunks, optional deletion sync, and auto-continue or manual chunk-by-chunk stepping.
  • Pause / Resume / Cancel & Persisted History - Bulk Transfer jobs can be paused after the current page (cursor, page number, and counters preserved), cancelled without losing progress, and resumed later from the exact saved state. Every run is stored in a persistent history so you can inspect per-chunk results and restart or resume any previous run — even after a Strapi restart.
  • Retention Controls - Manual clear and automatic retention limits for logs and run reports.
  • Secure Communication - API token authentication combined with HMAC-SHA256 request signing using a shared secret.
  • Guided Setup & In-App Help - A three-step first-run wizard (connect → scope → run) and a Help section documenting every screen, both reachable from the Home hub.

Prerequisites

  • Strapi v5.0.0 or higher
  • Node.js 20.0.0 or higher

Installation

npm install strapi-content-sync-pro

Or with yarn:

yarn add strapi-content-sync-pro

Configuration

1. Enable the plugin

Add to your config/plugins.js (or config/plugins.ts):

module.exports = {
  'strapi-content-sync-pro': {
    enabled: true,
  },
};

2. Rebuild Strapi

npm run build
npm run develop

3. Configure via Admin UI

  1. Navigate to Content Sync Pro in the admin sidebar
  2. Go to Configure → Connection
  3. Enter your remote server details:
    • Server URL: The remote Strapi instance root (e.g., https://api.example.com) — not /admin or /api
    • API Token: Generate from the remote Strapi's Settings → API Tokens
    • Instance Name: Unique identifier for this instance
    • Shared Secret: Same secret on both instances for HMAC signing
    • Sync Mode: Paired or Single-side (see Deployment Modes)

Configure → Connection

Quick Start

New installs can follow the guided Setup wizard, which walks the same three steps below as deep-linkable URLs and hands off to the full screens afterwards.

Step 1: Choose Deployment Mode and Configure Connection

In Configure → Connection (or Setup → Connect), choose one mode:

  • Paired: install and enable plugin on both local and remote servers.
  • Single-side: install plugin only on local server (remote plugin routes not required).

Then configure Server URL, API Token, Instance Name, and Shared Secret, and press Test Connection before saving.

Setup step 1 — connect to the remote server

Step 2: Enable Content Types

In Configure → Content types (or Setup → Choose scope), toggle on the content types you want to sync. Default profiles (Full Push, Full Pull, Bidirectional) are auto-generated per type.

Configure → Content types

Step 3: Align Sync Settings on Both Servers

In Configure → Content types, enable matching content types on both servers. In Configure → Sync profiles, set compatible direction/conflict strategy and activate the profile you want to run. Then in Sync → Run profiles, configure execution mode and global page size.

Configure → Sync profiles

Step 4: Run Sync

In Sync → Run profiles (or Setup → Run), click Sync All Active or run individual profiles with Run Now. Profiles execute in the listed order, and the dependency badges show how many types each one depends on.

Sync → Run profiles

Bulk Transfer

Sync → Bulk transfer is a one-click full pull or full push across selected scopes, for first-time seeding and large migrations where per-profile runs are too granular.

Pick a Direction and Conflict Strategy, tick the Scope (user-generated content, media, Strapi users, admin users), then review the generated plan before starting. The transfer expands into chunks — one content type or media profile per chunk, split into entity and relation passes — which you can select individually, step through manually, or let auto-continue. Runs can be paused after the current page, cancelled, and resumed later from the exact saved cursor; Previous Runs keeps a persistent history you can inspect, restart, or resume even after a Strapi restart.

Sync → Bulk transfer

Sync Profiles

Sync Profiles define what to sync and how conflicts are resolved.

Simple Mode (Presets)

  • Full Push - Push all data to remote, local wins
  • Full Pull - Pull all data from remote, remote wins
  • Bidirectional - Two-way sync, latest wins

Advanced Mode

Configure individual field policies:

  • Both - Field syncs both directions
  • Push - Field only pushes to remote
  • Pull - Field only pulls from remote
  • Exclude - Field is never synced

Deployment Modes

Paired mode

  • Plugin installed on both local and remote servers.
  • Supports push, pull, and bidirectional profiles.
  • Supports on-demand, scheduled, and live execution modes.
  • Connection test validates remote plugin endpoints.

Single-side mode

  • Plugin installed on local server only.
  • Pull-only profiles are enforced.
  • Live execution is disabled (use on-demand or scheduled).
  • Connection test validates remote reachability and API token access without requiring remote plugin routes.
  • Media links (entity → file) are derived from the remote's standard content REST API, so the API token needs find on every content type that owns media fields, not just on Upload.

Execution Modes

Configure when sync runs in Sync → Run profiles, per profile via the gear icon:

ModeDescription
On DemandManual trigger only
ScheduledInterval, Timeout, Cron expression, or External scheduler
LiveReal-time sync on content changes via lifecycle hooks

Scheduled Sync Types

TypeDescription
Interval (setInterval)Fires every N minutes. Simple but can overlap.
Timeout (chained setTimeout)Waits for the previous run to finish. No overlap.
Cron (wall-clock)Standard cron expression via strapi.cron. Recommended for production.
ExternalNo in-process timer. Use system cron, Kubernetes CronJob, GitHub Actions, etc.

Media Sync

Full media synchronization between Strapi instances, managed from the Media tab:

Media sync profiles

  • URL Strategy (HTTP) — Works with any upload provider (local, S3, Cloudinary). Downloads and re-uploads via the Upload API.
  • rsync Strategy — Host-level file copy using the rsync binary. Fastest for local-provider setups with SSH access.
  • Profile-based — Create media sync profiles with direction, conflict strategy, MIME filters, filename patterns, and execution settings.
  • DB + File Sync — Syncs both the plugin::upload.file database rows and the actual file bytes.
  • Entity → File Links — Media links are written from the owning content type's media fields, in one direction, with set semantics: removing an image at the source removes it at the target. Files are matched by documentId, falling back to name + extension + size, because a URL-synced file is re-uploaded on the target and gets a fresh documentId. A field whose source list is non-empty but resolves to no local file is left untouched rather than cleared — that means the files have not been pulled yet, not that the link was removed.
    • In paired mode the links come from the peer's media-sync/entity-media-links endpoint (or media-sync/morph-links if the peer runs an older version).
    • In single-side mode the peer serves neither, so links are derived from its standard content REST API (/api/<plural>?populate=<media fields>). This requires the API token to have find on every content type that owns media fields.
  • Live Status + Pause/Resume/Stop — The Media tab polls status every 2 s while a profile is running or paused and shows live phase and counters (pushed, pulled, skipped, errors). Long runs can be paused, resumed, or stopped cooperatively from the UI or via POST /api/strapi-content-sync-pro/media-sync/profiles/:id/pause|resume|cancel (URL strategy; rsync runs cannot be paused mid-process).

Enforcement

Pre-sync validation (Configure → Advanced → Enforcement):

  • Schema Match - Verify content type schemas match (strict/compatible/none)
  • Version Check - Verify Strapi versions (exact/minor/major/none)
  • DateTime Sync - Verify server clocks are synchronized

Alerts

Get notified of sync events (Configure → Advanced → Alerts):

  • Strapi Logs - Logs to sync log and server console
  • Email - Requires Strapi email plugin configured
  • Webhook - POST to any HTTP endpoint

Configure → Advanced — enforcement and alerts

API Endpoints

Admin Routes (authenticated)

MethodPathDescription
GET/strapi-content-sync-pro/configGet connection config
POST/strapi-content-sync-pro/configUpdate connection config
POST/strapi-content-sync-pro/sync-nowTrigger manual sync
GET/strapi-content-sync-pro/sync-profilesList sync profiles
GET/strapi-content-sync-pro/logsView sync logs

Public Routes (HMAC signed)

MethodPathDescription
POST/strapi-content-sync-pro/receiveReceive data from remote

Security

  • API Tokens: Use Strapi's built-in API token system
  • HMAC-SHA256: All inter-instance requests are signed
  • Masked Secrets: Sensitive data is masked in API responses

Example: E-commerce Sync

Sync products from a central catalog to multiple storefronts:

  1. Central Catalog (source):

    • Create "Full Push" profile for api::product.product
    • Set execution mode to "Live"
  2. Storefront (target):

    • Create "Full Pull" profile for api::product.product
    • Set execution mode to "Scheduled" (every 5 minutes)

Stats & Data Management

History → Stats is split into two sub-tabs:

History → Stats

Current Snapshot — live local vs remote state per content type:

  • Local vs remote record count
  • Media files and media morph stats (local, plus remote where available)
  • Newest record timestamp on each side and which side is newest (local, remote, equal)
  • Search by UID, filter by type (content / media / media morph) or newest side, and paginate large result sets

Run Reports — before/after snapshots captured for each sync run:

  • Filter by status (all / success / failed) and paginate server-side
  • Expand any report to see the before and after row tables

A top action row (shared by both sub-tabs) provides:

  • Refresh Stats, Clear Logs, Clear Stats Reports
  • Max Logs / Max Reports retention limits with Save & Apply Retention (also enforced automatically after each sync run)

Troubleshooting

Common Issues

ErrorSolution
"Remote server not configured"Add Server URL and API Token in Configure → Connection
"401 Unauthorized / 403 Forbidden"Regenerate API token and verify required permissions for synced content types (and Upload permissions for media)
"HMAC verification failed"Ensure shared secret matches on both instances in paired mode
"Content type endpoint not found"In paired mode, ensure matching content-type definitions and enabled API routes on both instances
"Live mode not available"Switch to paired mode, or use on-demand/scheduled in single-side mode
"Schema mismatch"Sync content type schemas or set enforcement to "compatible"
Files pull but stay unlinked (mediaLinksApplied: 0)Grant the API token find on every content type that owns media fields — in single-side mode links are read from the remote's content REST API, not from a plugin route. Before 1.1.1 this failed unconditionally in single-side mode; upgrade.
"Remote morph-links fetch failed (404)"The remote does not run this plugin. Fixed in 1.1.1, which falls back to the remote's content REST API. On older versions, install the plugin on both instances (paired mode).

Viewing Logs

Check History → Logs for detailed sync history including:

  • Timestamp and duration
  • Content type and record ID
  • Direction (push/pull)
  • Status and error messages

Search by action, content type or message, and filter by status to isolate a failing run.

History → Logs

In-app documentation for every screen is available under Help.

Help tab

Security & Privacy

  • No usage tracking. This plugin does not collect, transmit, or store any analytics or telemetry data.
  • Credential handling. The optional "Generate Token" feature lets you authenticate to your own remote Strapi server to create an API token. Credentials are sent directly from your browser to your server via the plugin's backend proxy, used once, and never stored on disk, in the database, or in memory after the request completes.
  • API Tokens are encrypted at rest using Strapi's built-in store.
  • HMAC-SHA256 signatures protect all inter-instance requests from tampering.
  • Masked secrets — API tokens and shared secrets are masked (••••••••) in all API responses.

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

Support

License

MIT License - see LICENSE for details.

Author

Ejaz Husain ArainTech Style Ltd

Tech Style Ltd · Registered in England & Wales · Company No. 11101491

Submit your content

Share your work with the community and get it listed in the Strapi ecosystem for everyone to discover and use.

Submit
Submit your content