
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.
released August 14, 2026
npm install strapi-content-sync-pro
Copy, migrate, and live-sync content, media, users, and relations
between any number of Strapi v5 environments.
Quick start · Screenshots · Full gallery · Video · Product page · Contact
The Home hub — connection status, deployment mode, and every section one click away.
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.
→ See all 14 screens with a written walkthrough
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.
| Group | Destination | Path | What it's for |
|---|---|---|---|
| Start | Home | / | Connection status and entry points to every section |
| Start | Setup | /setup/connect, /setup/scope, /setup/run | Guided first run: connect, choose scope, run your first sync |
| Run | Sync | /sync · /sync/bulk | Run profiles · Bulk transfer |
| Run | Media | /media | Media sync profiles, live status and controls |
| Set up | Configure | /configure/connection · /configure/content-types · /configure/profiles · /configure/advanced | Connection · Content types · Sync profiles · Enforcement and alerts |
| Monitor | History | /history/stats · /history/logs | Stats and run reports · Detailed logs |
| Monitor | Help | /help | Step-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.
rsync). Includes MIME type filtering and concurrency controls.npm install strapi-content-sync-proOr with yarn:
yarn add strapi-content-sync-proAdd to your config/plugins.js (or config/plugins.ts):
module.exports = {
'strapi-content-sync-pro': {
enabled: true,
},
};npm run build
npm run develophttps://api.example.com) — not /admin or /api
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.
In Configure → Connection (or Setup → Connect), choose one mode:
Then configure Server URL, API Token, Instance Name, and Shared Secret, and press Test Connection before saving.
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.
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.
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 → 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 Profiles define what to sync and how conflicts are resolved.
Configure individual field policies:
find on every content type that owns media
fields, not just on Upload.Configure when sync runs in Sync → Run profiles, per profile via the gear icon:
| Mode | Description |
|---|---|
| On Demand | Manual trigger only |
| Scheduled | Interval, Timeout, Cron expression, or External scheduler |
| Live | Real-time sync on content changes via lifecycle hooks |
| Type | Description |
|---|---|
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. |
| External | No in-process timer. Use system cron, Kubernetes CronJob, GitHub Actions, etc. |
Full media synchronization between Strapi instances, managed from the Media tab:
rsync binary. Fastest for local-provider setups with SSH access.plugin::upload.file database rows and the actual file bytes.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.
media-sync/entity-media-links endpoint (or media-sync/morph-links if the peer runs an older version)./api/<plural>?populate=<media fields>). This requires the API token to have find on every content type that owns media fields.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).Pre-sync validation (Configure → Advanced → Enforcement):
Get notified of sync events (Configure → Advanced → Alerts):
| Method | Path | Description |
|---|---|---|
GET | /strapi-content-sync-pro/config | Get connection config |
POST | /strapi-content-sync-pro/config | Update connection config |
POST | /strapi-content-sync-pro/sync-now | Trigger manual sync |
GET | /strapi-content-sync-pro/sync-profiles | List sync profiles |
GET | /strapi-content-sync-pro/logs | View sync logs |
| Method | Path | Description |
|---|---|---|
POST | /strapi-content-sync-pro/receive | Receive data from remote |
Sync products from a central catalog to multiple storefronts:
Central Catalog (source):
api::product.productStorefront (target):
api::product.productHistory → Stats is split into two sub-tabs:
Current Snapshot — live local vs remote state per content type:
Run Reports — before/after snapshots captured for each sync run:
A top action row (shared by both sub-tabs) provides:
| Error | Solution |
|---|---|
| "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). |
Check History → Logs for detailed sync history including:
Search by action, content type or message, and filter by status to isolate a failing run.
In-app documentation for every screen is available under Help.
••••••••) in all API responses.Contributions are welcome! Please open an issue or submit a pull request.
MIT License - see LICENSE for details.
Ejaz Husain Arain — Tech Style Ltd
Tech Style Ltd · Registered in England & Wales · Company No. 11101491
Share your work with the community and get it listed in the Strapi ecosystem for everyone to discover and use.
Submit
