Voxel Crossposter
The {CODICTS} Voxel Crossposter plugin synchronizes Voxel Theme posts across multiple WordPress/Voxel sites. When a post is created, updated, or trashed on one site, the plugin automatically replicates it — including all Voxel fields, images, taxonomies, post relations, and author data — to one or more target sites via the WordPress REST API.
Installation & Activation
Start by downloading the plugin from the Downloads page on your dashboard on the CoDicts website.
Install and activate the plugin on both the source site and every target site:
1. Navigate to “Plugins” > “Add New” > “Upload Plugin” and select the downloaded zip file. Click “Install Now” and then “Activate”.
2. Repeat on every site involved in the sync.
Important: The plugin must be installed and activated on both the source site (where posts are created) and the target site (where posts are received). The source site sends data; the target site receives it via a REST API endpoint that the plugin exposes.
Source Site vs. Target Site
| Role | What It Does | Configuration Needed |
|---|---|---|
| Source Site | The site where posts are created/edited. Sends sync data to target sites. | Full settings configuration: target URLs, credentials, post types, roles. |
| Target Site | Receives synced posts via REST API. Processes incoming data. | Only needs the plugin activated and enabled — no target site settings needed. |
A single site can be both a source and a target at the same time, enabling two-way synchronization. The plugin includes built-in loop prevention (see Loop Prevention).
Setting Up a Target Site
On each target site, complete these steps:
Step 1: Activate and Enable the Plugin
After installing and activating the plugin, navigate to “Crossposter” in the admin sidebar and turn on the “Enable Crossposter” toggle. Save settings.
Step 2: Create an Application Password
1. Go to Users → Profile (or edit the user account you want to use for syncing).
2. Scroll to the “Application Passwords” section.
3. Enter a name (e.g., “Crossposter”) and click “Add New Application Password”.
4. Copy the generated password immediately — it will not be shown again. You’ll enter this on the source site.
Step 3: Ensure Matching Field Keys
The target site’s Voxel post types must have matching field keys to the source site. The plugin maps data by field key — if a field key exists on the source but not the target, that field’s data will be skipped.
Configuring the Source Site
On the source site, navigate to “Crossposter” in the admin sidebar.
Step 1: Enable the Plugin
Turn on the “Enable Crossposter” toggle.
Step 2: Configure Deferred Sync (Optional)
Turn on “Enable Deferred Sync” if you want sync operations to run in the background via WP-Cron instead of during the page request. This prevents the sync from slowing down the user experience, especially when syncing large posts with many images to multiple sites.
Step 3: Add Target Sites
Click “Add A Website” to add a target site. You can add multiple target sites. For each site, configure:
| Setting | Description |
|---|---|
| Target Site URL | The full URL of the target WordPress site (e.g., https://target-site.com/). |
| User Name | The WordPress username on the target site. |
| Application Password | The Application Password you generated on the target site. |
| Post Types | Check which Voxel post types should be synced to this target. |
| Roles Allowed | Check which user roles can trigger syncs. Only posts created/edited by users with these roles will be synced. |
| Require a Switcher to Sync | Optional — requires a Voxel switcher field to be enabled on the post before syncing (see Switcher Gating). |
Step 4: Test the Connection
Click the “Test Connection” button for each target site to verify the URL and credentials are correct before saving. You’ll see a success or error message.
Step 5: Save
Click “Save”. The source site is now configured to sync posts to the target site(s).
What Gets Synced
When a post is synced, the plugin transfers all of the following:
| Data | How It’s Handled |
|---|---|
| Post title, content, slug, status, dates | Copied directly. |
| All Voxel fields | Text, number, switcher, and similar fields are copied by value. Mapped by field key. |
| Images & files | Downloaded from the source and re-attached on the target. Cached to avoid re-downloading on updates. |
| Taxonomies & terms | Created on the target if they don’t exist, including parent–child hierarchies. |
| Post relations | Matched on the target by post slug and type. Related posts must already exist on the target. |
| Author | Matched by login + email. If the author doesn’t exist on the target, a new account is created with the same roles and profile data. |
| Verified status | Voxel’s post verification status is synced. |
When Sync Triggers
The plugin automatically syncs posts when any of these events occur:
| Event | When It Fires |
|---|---|
| Post submitted | A new post is created via Voxel’s frontend form. |
| Post updated | An existing post is edited via Voxel’s frontend form. |
| Admin save | A post is saved from the Voxel admin panel. |
| Status change | A post’s status changes (e.g., published → trashed, pending → published). |
Auto-draft posts are always ignored. The sync only fires when a logged-in user with an allowed role triggers one of these events on a post type that’s enabled for the target site.
Switcher-Based Sync Control
The plugin includes a custom Voxel field type called “{C} Crossposter” — a switcher toggle that gives content creators per-post control over whether a post should be cross-posted.
Setting It Up
1. In the Voxel Post Type Editor, add a new field and select “{C} Crossposter” as the field type. Set a field key (e.g., enable_crosspost).
2. In the Crossposter settings on the source site, enable “Require a Switcher to Sync” for the target site and enter the field key you chose.
3. When creating or editing a post, users will see a toggle switch. The post will only be synced if the toggle is turned on.
Re-syncing All Posts
The Re-sync Posts feature lets you bulk re-synchronize all existing posts to your target sites. This is useful after initial setup, after changing configuration, or to recover from sync failures.
1. On the settings page, click “Re-sync Posts” and confirm.
2. Posts are synced one at a time. A progress bar shows how many have been completed.
3. Click “Cancel Sync” at any time to stop. Posts already synced will remain on the target sites.
Note: Re-sync uses your current admin account’s roles for validation. Make sure your roles are included in the “Roles Allowed” setting for each target site.
Two-Way Sync & Loop Prevention
If two sites are configured to cross-post to each other (Site A → Site B and Site B → Site A), the plugin prevents infinite sync loops automatically.
When a post is received from another site, the plugin records which site sent it. If the target site later tries to sync that same post back to the site it came from, the sync is blocked.
However, if the post is edited locally on the target site after being received, the origin marker is cleared and it can be synced back. This means genuine edits propagate correctly, while automatic round-trips are prevented.
Important: Post Relation Sync Order
Post relations (fields that link to other posts) are matched by slug on the target site. This means the related posts must already exist on the target before the referencing post is synced. If a related post hasn’t been synced yet, that relation is silently skipped.
Recommendation: When first setting up cross-posting, sync the posts that are referenced by other posts first. For example, if “Events” link to “Venues,” sync all Venues before syncing Events. The Re-sync feature processes posts sequentially, so consider the order of your post types.
Developer Hooks
Skip Sync Filter
Conditionally skip syncing specific posts:
add_filter('codicts-voxel-crossposter::skip_sync', function($skip, $post) {
// Don't sync private events
if ($post->post_type->get_key() === 'event'
&& has_term('private-event', 'event-category', $post->get_id())) {
return true; // Skip this post
}
return $skip;
}, 10, 2);
Force Sync
Programmatically trigger a sync for any post, bypassing the skip filter:
do_action('codicts-voxel-crossposter::force_sync', $post_id);
Force Delete
Programmatically trash a post on all target sites:
do_action('codicts-voxel-crossposter::force_delete', $post_id);
Note: Force sync and force delete bypass the
skip_syncfilter, but all other validations (post type, user role, origin check) still apply.
Troubleshooting
“Voxel Theme Not Detected” Error
Ensure the Voxel Theme is installed and set as the active theme on the site showing the error. This applies to both source and target sites.
Posts Not Syncing
| Cause | Solution |
|---|---|
| Plugin not enabled | Turn on the “Enable Crossposter” toggle on both the source and target sites. |
| Post type not checked | Ensure the post type is checked in the target site’s “Post Types” setting. |
| User role not allowed | Ensure the post author’s role is checked in the target site’s “Roles Allowed” setting. |
| Switcher not toggled on | If “Require a Switcher to Sync” is enabled, the switcher field must be turned on for the post. |
| Skip sync filter blocking | Check if any custom skip_sync filter is returning true. |
| Same-origin block | A post received from Site B can’t be synced back to Site B (loop prevention). Edit the post locally to clear the origin marker. |
| User not logged in | Sync requires a logged-in user. If using deferred sync, ensure WP-Cron has proper user context. |
Test Connection Fails
| Cause | Solution |
|---|---|
| Wrong URL | Ensure the target URL is correct and includes the protocol (https://). |
| Wrong credentials | Verify the username and Application Password on the target site. Passwords are only shown once when created. |
| Application Passwords not supported | Requires WordPress 5.6+. Some security plugins may disable Application Passwords. |
| SSL issues | Ensure HTTPS is properly configured on the target site. |
| Plugin not active on target | The Crossposter plugin must be installed and activated on the target site. |
Images Not Appearing on Target Site
Ensure the source site’s images are publicly accessible (not behind authentication or a CDN that blocks external requests). Check that the target site’s wp-content/uploads directory is writable. Very large images may time out during download — check your server’s timeout settings.
Taxonomies or Terms Missing on Target
Taxonomy creation is deferred to after the main post sync. If the taxonomy data in the sync payload is incomplete or the term slug is invalid, creation may fail silently. Verify the taxonomy structures match between source and target, and check the PHP error log.
Post Relations Not Linking
Related posts must already exist on the target site, matched by slug and post type. Sync the referenced posts first, then sync the posts that contain relations. See the sync order note above.
Deferred Sync Not Firing
| Cause | Solution |
|---|---|
| WP-Cron disabled | Ensure WP-Cron is functional, or set up a server-side cron job. |
| Transient expired | The deferred sync payload has a 1-hour TTL. If WP-Cron is significantly delayed, the data may be lost. Reduce cron delay or disable deferred sync. |
Re-sync Stops or Fails Partway Through
Check the browser console for JavaScript errors. Ensure the AJAX security token hasn’t expired — refresh the settings page and try again. Individual posts may fail silently; the re-sync continues to the next post automatically.
Duplicate Posts on Target Site
Posts are matched on the target by a unique identifier stored in post meta. If the identifier was lost (e.g., the meta was manually deleted), the plugin falls back to matching by slug. If neither matches, a new post is created. Avoid manually deleting the codicts-voxel-crossposter_unique_identifier post meta on target site posts.
For further support, visit codicts.com or contact us at support@codicts.com.