Skip to main content

Goal

Use approved Assets media in WordPress without putting account credentials or permanent private URLs in post content.

Prerequisites

  • WordPress 6.5 or newer, PHP 8.1 or newer, and HTTPS.
  • The complete built Stackshift Assets plugin bundle, WordPress administrator access for connection setup, and access to the intended Assets space.
  • Published, rights-valid media and a defined site channel/bucket/collection boundary.

Workflow

1
Build and install the complete plugin bundle.
2
Create a managed WordPress connection in Assets → Manage → Operations and verify it in WordPress Settings → Stackshift Assets.
3
Choose approved media or a published gallery in Gutenberg and publish the post.
4
Configure signed webhooks, reconciliation and no-cache exclusions.

Build and install the plugin

From the repository root, build the package assets and plugin. Copy the complete integrations/wordpress/stackshift-assets directory, including generated assets/, into wp-content/plugins/stackshift-assets and activate it. The WordPress server does not run npm. Do not deploy only the PHP files without the browser bundles.

Create a managed WordPress connection

In Stackshift, select the Assets space for this site and open Manage → Operations → Integrations. Under WordPress · Managed connections, enter Connection name and WordPress site origin. Use the exact HTTPS origin, for example https://www.example.com, without a page path. The www and non-www hosts are different origins. Leave Receive signed publication updates enabled if you want Stackshift to create the linked webhook. Choose Create WordPress connection. Copy the returned credential, Space ID and webhook signing secret before dismissing them. The credential is read-only within this space and expires in one year; it is a site connection credential rather than an editor’s browser token. In the WordPress administrator, open Settings → Stackshift Assets. Enter the integration credential, asset space ID and webhook secret, then connect. The plugin verifies that the credential belongs to this site origin and encrypts its stored settings using the WordPress authentication salt. Choose Test connection to confirm current access. The Stackshift connection list changes from Awaiting plugin verification to a verified timestamp after verification. Keep the WordPress site URL aligned with the registered HTTPS origin. For a site-domain change, create and verify a connection for the new origin. Back up your configuration before rotating WordPress salts: changing the authentication salt prevents decryption of stored credentials, so reconnect afterward.

Optional: infrastructure-managed configuration

For infrastructure-managed sites, the following wp-config.php constants take precedence over saved settings. If STACKSHIFT_ASSETS_TOKEN is defined, the token-entry form is not offered. Use the managed integration credential for the selected space, and keep values on the WordPress server. Bucket and collection restrictions further limit the site’s media boundary.
  • STACKSHIFT_ASSETS_TOKEN: the site integration credential. Never put it in block attributes or frontend JavaScript.
  • STACKSHIFT_ASSETS_SPACE: the exact Assets space UUID. STACKSHIFT_ASSETS_CHANNEL: the publication channel, such as web.
  • STACKSHIFT_ASSETS_BUCKETS and STACKSHIFT_ASSETS_COLLECTIONS: allowed bucket identifiers and collection UUIDs; configure the narrow site boundary.
  • STACKSHIFT_ASSETS_API_ORIGIN defaults to https://api.stackshift.cloud. Override only with the trusted HTTPS API origin, without /api/v1.
  • STACKSHIFT_ASSETS_WEBHOOK_SECRET: the secret returned for this site’s Assets webhook; it is separate from the account token.

Insert a media block

In Gutenberg, add Stackshift media. Choose approved media in the picker, enter alternate text and save/publish the post. The editor must have both media-upload and post-edit permission and a valid WordPress REST nonce. It receives a 15-minute picker capability, not the account credential. The block stores publication, asset and version identities with author-provided alternate text. Visitors resolve fresh media through the plugin’s backend, which checks that the reference is actually saved on the public post. Editing block JSON cannot authorize an arbitrary asset. Add Stackshift gallery, select a published gallery and save the post. The block stores its stable gallery ID and published revision. Gallery draft edits do not change the live block. After publishing a newer gallery revision in Assets, explicitly choose Use latest published revision in the WordPress block and update the post. Unavailable or withdrawn revisions fail closed; they do not fall back to an unapproved draft. AR requests retain the saved gallery boundary.

Public-post delivery requirements

Anonymous delivery is limited to references stored on public, published, password-free posts. Draft/private/password-protected posts are not supported public delivery containers. Reusable synced blocks are also outside this integration’s delivery-container support. Do not work around a denied resolve by copying a signed URL into post HTML or making the original asset public. If a post should be restricted, use an integration designed around that viewer authorization model.

Configure the webhook

Managed connections create the linked webhook when Receive signed publication updates is selected. Paste the returned signing secret into the plugin. For a manually managed webhook, create an Assets webhook for asset.* targeting https://YOUR_SITE/wp-json/stackshift-assets/v1/webhook and configure its returned secret. The plugin requires X-StackShift-Signature-V2 and X-StackShift-Timestamp; the signature covers timestamp + ”.” + the exact raw request body using HMAC-SHA256. Deliveries older than five minutes are rejected and signed event IDs are deduplicated for seven days. Preserve the raw body and signature/timestamp headers through proxies; do not reserialize JSON before verification. The plugin performs verification rather than trusting a webhook merely because it reached the endpoint.

Reconciliation and caching

A valid webhook schedules reconciliation. An hourly job also examines 20 published posts per batch, advances its cursor, records unavailable references in _stackshift_assets_unavailable and clears WordPress post caches. On low-traffic sites, arrange a reliable invocation of WP-Cron so scheduled work actually runs. Exclude /wp-json/stackshift-assets/v1/* from reverse-proxy and CDN caching. The routes use private, no-store. Do not permanently cache or proxy the returned delivery URLs. A missed webhook never extends rights: resolve and media requests still enforce live policy.

Check the installation

After activation, verify that an authorized editor can select a publication, a public post can display it, and a draft/private/password-protected post cannot serve anonymous media through this integration. Publish a new gallery revision and verify that the block changes only after explicitly adopting it. Withdraw a test publication or expire its rights and verify the unavailable state and reconciliation behavior. Inspect WordPress/plugin errors without logging account credentials, capabilities or full signed URLs. Use View in your space on a supported device to open the published model in AR.

Disconnect, replace an expiring credential or move a site

Choose Disconnect in WordPress Settings → Stackshift Assets to stop local media access immediately and revoke the server credential. The plugin stops its scheduled delivery/reconciliation work. If the API is unavailable, local access remains stopped while server revocation retries for up to 24 attempts. Retry Disconnect or revoke the site in Stackshift if the pending state persists. You can also use Disconnect site in Assets → Manage → Operations. This revokes future media resolution for that connection. To renew an expiring connection, create a new connection for the same intended site and space, verify it in the plugin, then revoke the old connection after checking the public pages. Do not leave the old credential in a wp-config.php constant that overrides the replacement settings. Stable publication and gallery references remain in post content. Reconnecting is not a request to replace those references with newer media. To adopt a new publication, replace the block selection and update the post; to adopt a gallery revision, use Use latest published revision.

Common failures and recovery

  • Empty picker: verify site channel/scope restrictions, current token access and whether media is actually published with valid rights.
  • Capability endpoint denied: verify WordPress editor permissions and the REST nonce; do not disable nonce checks.
  • Media works in the editor but not the public post: confirm the post is published/public/password-free and the saved stable reference matches the selected publication.
  • Gallery remains on the old revision: use Use latest published revision and update the WordPress post; changing an Assets draft is insufficient.
  • Webhook rejected: compare the configured webhook secret, timestamp freshness and raw-body preservation.
  • Withdrawn media remains visible: exclude resolver routes from caches, verify scheduled reconciliation and distinguish a cached/downloaded browser copy from a newly authorized request.
In Assets, render a product photo, prepare a short video with captions, and publish a model or spin. Create a gallery from the approved publications, arrange their order and alternative text, and publish the gallery revision. In WordPress, add Stackshift gallery to a product post and select that published gallery. Save the post, view the public page and check image navigation, video playback, captions and the model/poster fallback. On a supported phone, test the AR action. When the next campaign revision is approved, publish the new gallery revision, explicitly adopt it in the block, and update the post.

Expected result

WordPress stores stable approved references and resolves them within the site’s scope while retaining publication withdrawal and rights enforcement.

Common failures

  • Copying only PHP files and omitting generated browser assets.
  • Storing service credentials or expiring delivery URLs in block attributes.
  • Using private posts or reusable synced blocks as anonymous delivery containers.
  • Caching plugin REST resolver responses.

Embed the headless asset picker

Add JavaScript or React media selection using expiring capabilities, save stable references, and resolve approved media from your backend.

Publications, review and usage rights

Select immutable renditions, capture metadata and rights, submit editorial review, publish by channel, and withdraw delivery.

Create and embed media galleries

Arrange published images, video, spins and models with locale, alternate text, approved fallbacks and stable published revisions.

Upload, validate and publish 3D models

Prepare supported GLB and supplied USDZ files, inspect validation reports, add posters, review the model and launch authorized device AR.