Signal propagation
This page explains what happens between "you click Enrich" and "the live storefront shows the new signals". It's the part that most often surprises people, especially around what is automatic vs manual, what gets pushed where, and why JSON-LD sometimes seems to disappear.
The core loop
SYNC → ENRICH → PROPAGATE → VERIFY
- Sync brings the catalog from the platform (BC, Shopify) into Clione.
- Enrich generates the AI-driven signals — meta title, meta description, JSON-LD, bilingual keywords.
- Propagate writes those signals back to the platform.
- Verify fetches the live storefront HTML and confirms the signals landed.
This page focuses on the third step.
What signals are propagated
For every entity type, Clione has a SignalPropagationAdapter that knows how to write each signal to the platform's specific field:
| Signal | BC Products | BC Categories | BC Pages | Shopify Products | Shopify Collections | Shopify Pages |
|---|---|---|---|---|---|---|
| Meta title | Yes | Yes | Yes | Yes | Yes | Yes |
| Meta description | Yes | Yes | Yes | Yes | Yes | Yes |
meta_keywords | Yes (array) | Yes (array) | Yes (string!) | N/A | N/A | N/A |
search_keywords (BC internal) | Yes | Yes | Yes | N/A | N/A | N/A |
| Canonical URL | Yes | Read-only | Yes | Yes | Yes | Yes |
| JSON-LD | Yes (Schema Injector) | Planned | Planned | Yes (theme app block) | Planned | Planned |
| OG tags | Yes | Planned | Planned | Yes (via metafield) | Planned | Planned |
Note that meta_keywords on BigCommerce is an array for products + categories but a comma-separated string for pages. This is a BC API quirk and a frequent source of bugs in custom integrations.
Automatic propagation
After a successful enrichment, Clione automatically propagates the new signals. You don't need a separate "push" step. This applies to:
- Single-entity enrich (one-click) — auto-propagates immediately on completion.
- Bulk async enrich — each entity auto-propagates as it completes inside the bulk job.
The auto-propagation happens via autoPropagateEntity() (or autoPropagateProduct() for products), wired into all enrichment routes. If the auto-propagation fails (transient 5xx from the platform, etc.), the enrichment is still saved and you can re-push manually from the entity's Propagation tab.
Why JSON-LD is different
Meta title, meta description, canonical URL, and platform-native fields are written via the platform's catalog API. The platform stores them and renders them on every storefront page request.
JSON-LD is trickier — neither BC nor Shopify renders arbitrary JSON-LD by default. It needs a delivery mechanism:
BigCommerce — the Schema Injector
Clione registers a small script tag via BC's Scripts API. On every storefront page, the script:
- Detects the current entity from URL + OG tags.
- Fetches the enriched JSON-LD from
api.clione.ai. - Injects it into
<head>as<script type="application/ld+json">.
This means JSON-LD is JS-rendered (Googlebot runs JS, but old crawlers don't — see Stencil non-JS crawlers for the alternative).
Shopify — the theme app block
Clione's Theme App Extension provides a Liquid block called clione-jsonld. It:
- Reads the
clione.jsonldmetafield on the product / collection / page. - Renders it inline in
<head>as<script type="application/ld+json">.
This is server-rendered Liquid, so it works for every crawler immediately. But it only renders if the merchant has enabled the block in their theme editor.
If the block is not enabled, the metafield exists but is invisible. This is the most common reason "JSON-LD missing on Shopify" — see Schema Injector.
Order of operations during auto-propagate
- Enrichment completes; new fields are saved in Clione's DB.
- A snapshot is created in the entity's enrichment version history (3-version retention).
- The cache is invalidated (this fix landed in 2026-04-19 — earlier versions had stale UI bug).
autoPropagateEntity()resolves the store's credentials from the DB (or env vars in legacy single-tenant mode).- For each signal, the propagation adapter writes to the platform via its API. Errors are caught per-signal so a partial failure doesn't block the rest.
- A
PropagationRecordis written to Clione's DB capturing what was pushed, when, and the platform's response. - The verification subsystem schedules a follow-up live-fetch check (visible in the Verification page minutes later).
Manual re-push
From any entity's Propagation tab:
- Click Re-push to storefront to re-send every signal to the platform.
- Per-signal toggles let you push only the meta description, for example, leaving JSON-LD alone.
- The history pane shows every past push, with the platform's response code and any returned errors.
Use this when:
- Auto-propagation failed silently and verification flags a Fail.
- You manually edited a field in Clione and want to push it.
- The storefront CDN is showing a stale version and you want to force a write to bust the cache.
Manual override (keyword-only propagation for non-products)
Categories, collections, and pages have a keyword-only propagation endpoint that writes meta_keywords + search_keywords only, leaving title and description untouched. Useful for SEO teams who manage titles in the platform admin manually and only want Clione's keywords pushed.
Look for Push keywords only in the entity's Propagation tab.
Rollback
Restoring an older version from the entity's History tab triggers a re-propagation of THAT version's fields. So rolling back also rolls back the live storefront, not just the dashboard view.
Why a propagation can silently fail
Even when the platform returns 200 OK, the field may be dropped if:
- Shopify metafields of type
single_line_text_fieldreject values > 255 chars. The enriched description may be up to 320 chars; Clione truncates at a sentence boundary and flags a Warn in Verification. - BC
custom_urlrequires the canonical{ url, is_customized }object shape; a malformed string is rejected. - BC categories'
custom_urlis read-only via the public API. Clione doesn't try to rewrite category URLs. - The platform's webhook fires
product.updatedimmediately and our auto-sync follows up; if your platform'supdated_atis older than Clione's last enrichment timestamp, the next sync may not bring anything back, and a verification re-check is needed.
In all these cases, the Verification page is the canonical place to spot the discrepancy. See Verification.