Troubleshooting
Sharp edges in the landing-page builder — what causes them and how to check.
Style changes (buttons/profile/gate/etc.) do not show up on the published page
Symptom: You set buttons/profile/gate/layout/stack/etc. through bg/ui, publish,
and the live page still looks unchanged.
Cause: The domain's design is custom (an uploaded HTML design).
The exporter only bakes the ui key into the snapshot when the design is not custom — a
custom design owns its own look entirely, so the block-builder style is saved but never applied.
Check: BgConfig.design for the domain — if it's "custom", this is expected, not a bug.
The ui bake is gated in _bg_payload (backend/app/products/club/core/exporter.py:274):
if (design or 'classic') != 'custom': payload['ui'] = .... Switch the domain back to a
built-in design (classic or spotlight) to see block-builder styling again — your saved
settings are kept and reapply immediately.
Button font change does not apply to already-published labels
Symptom: You changed buttons.font and the response reported relabeled: N, but some
button labels on the live page are still in the old typeface.
Cause: Button labels are pre-rendered SVG images, and the re-render-on-font-change logic is
wired specifically into the POST /bg/ui handler — it isn't a general trigger on BgConfig
changes. Any path that writes BgConfig.ui_json directly (a script, a migration, a bulk import
outside this endpoint) changes the stored font but skips regenerating the label images.
Check: set_landing_ui's old_font/new_font comparison and relabel loop
(backend/app/api/admin/background_ui.py:151). If a label is stale, re-issuing the same
bg/ui buttons patch (even with an unchanged font) won't help — the comparison only
regenerates on an actual font change; toggle to a different font and back, or regenerate the
specific button's label through the normal button-edit path.
The notification banner click goes nowhere / is not attributed
Symptom: The push-style banner shows and gets clicks, but those clicks don't show up attributed to a source, or the destination looks wrong.
Cause: The banner's stored target_url is a dormant, same-origin /r deep-link — a bare
307 redirect straight to OnlyFans with no click id, so OnlyFans records zero clicks for it. The
exporter detects this and automatically re-points the baked banner to the domain's attributed
smart link instead, when one is available.
Check: notification_bake._is_r_deeplink and _attributed_notify_fallback
(backend/app/products/link/core/notification_bake.py:68 and :94), invoked from
_bg_payload in backend/app/products/club/core/exporter.py:514. If no segment on the domain
has a smart-link primary button, the fallback returns nothing and the stored (unattributed)
target_url is kept as-is — fix it by giving at least one segment a smart-link button, or by
setting the banner's own target_url to a real smart link directly.
An imported button keeps a temporary offer-handle URL
Symptom: A button created through bio-page import
carries a URL with an offer_id query parameter that looks like it shouldn't be public.
Cause: Some source pages expose a short-lived, per-visitor offer handle in their link URLs
(?_lp=1&offer_id=…). The importer has a guard that rejects such URLs before they're ever
persisted as a button — if a URL like this made it through, something upstream let it slip past
that guard.
Check: _safe_import_url (backend/app/core/importer/commit.py:107) — it raises when a URL
carries both _lp=1 and a numeric offer_id. Confirm the guard is still being called on the
commit path you used (persist_preview / persist_segmented_preview) rather than a button being
created some other way (direct API call, script) that bypasses the importer's commit path
entirely.
What's next
- Back to Landing-page builder
- Reference gaps