B BrandLeaf docs

Troubleshooting

Widget doesn't show

Widget isn't showing on your site, or shows only for logged-in users, or shows blank when you open it. This page is the symptom → cause → fix flowchart. Run the checks in order; most installs hit the first one and skip the rest.

Browser support — Chrome, Safari, Firefox, Edge

Every release is tested against Chromium (Chrome/Edge), WebKit (Safari) and Gecko (Firefox) by an automated cross-browser suite that mounts the widget, types a message and asserts a streamed reply in each engine — so the widget behaves identically across all of them, with no Chrome-only behaviour. It renders inside an isolated Shadow DOM and degrades gracefully on older engines: voice input, the Web-Audio chime, the async Clipboard API and ResizeObserver are all feature-detected and fall back rather than failing.

If the widget works in one browser but not another, the cause is almost always environmental rather than the widget itself — a Content-Security-Policy on your site blocking the script, an ad/tracker blocker, or a stale cached build. Hard-reload (Cmd/Ctrl+Shift+R) and open the browser console (F12) to check for a blocked-resource or CSP error.

Symptom: widget shows for logged-in users only

Cause: page cache. WordPress caching plugins (W3 Total Cache, WP Rocket, LiteSpeed Cache, WP Super Cache), hosting- level page cache (Hostinger, SiteGround, Cloudways, Kinsta), or Cloudflare APO all serve anonymous visitors a cached HTML snapshot taken BEFORE you installed Pitchbar. Logged-in users bypass page cache, so they always hit fresh PHP and see the widget.

Fix:

  1. WP admin → your caching plugin → click Purge All Cache.
  2. If you're on Hostinger / SiteGround / Cloudways / Kinsta: control panel → Page Cache → Purge.
  3. If Cloudflare is proxying your domain: Cloudflare dashboard → Caching → Configuration → Purge Everything.
  4. Open your site in incognito (new private window) → right-click → View Source → search for widget.js. Present = fixed.

Symptom: the custom launcher icon (or card images) don't show

Cause: the site's Content-Security-Policy. A site that sends a CSP — as a Content-Security-Policy header or a <meta http-equiv="content-security-policy"> tag — must allow your app's domain (the host of APP_URL) in img-src too, not only in script-src and connect-src. Without it the browser refuses the icon (the console says "does not appear in the img-src directive") and the widget shows the default orb.

Fix: the entries the widget needs, with your app's domain:

script-src  https://app.example.com
connect-src https://app.example.com
img-src     https://app.example.com
style-src   'unsafe-inline'

Product and pricing cards show images from the shop's own domain — add that host to img-src as well when the agent sends cards.

Symptom: widget doesn't show at all

Walkthrough:

  1. Confirm the Pitchbar WP plugin is configured. WP admin → Pitchbar (left sidebar). All three fields must be set: Base URL, API Token, Agent ID. Missing any one of them = the plugin's shouldRender() gate returns false and nothing renders.
  2. Confirm the widget is enabled. Same Pitchbar settings page → checkbox "Widget enabled". Default on, but worth confirming.
  3. Confirm post-type scoping. Settings page → "Show on these post types". Defaults to post + page. If your front page is a custom post type (e.g. landing, product) and you haven't ticked it, the widget skips that page. Tick the box.
  4. Open browser DevTools → Network tab on your front-end page. Search for widget.js:
    • Present + 200 OK: the script loaded. Check Console for JS errors.
    • Present + 404: your Base URL setting points at a host that doesn't serve widget.js. Should be your Pitchbar install root (e.g. https://pitchbar.your-domain.com).
    • Missing entirely: the plugin isn't emitting the tag. Confirm via View Source — look for <script async src=…widget.js…>. Missing tag = the shouldRender() gate failed; re-check the previous 3 items.

Symptom: widget shows but says "Sorry — something went wrong"

Widget retries the SSE stream 3 times then surfaces this generic bubble. The real error is logged server-side; the bubble is intentionally vague so visitors don't see raw provider errors.

Tail your Laravel logs while reproducing in the widget:

tail -f storage/logs/laravel.log

Common patterns and their fixes:

  • Workers AI 401: ... — Cloudflare API token rejected. See Cloudflare 401 troubleshooting.
  • Vectorize ... expected N dimensions, got M — embed model and index dim mismatch. See Vector dim recovery.
  • Workers AI timeout — Cloudflare flaky. Retry; if persistent, switch CLOUDFLARE_CHAT_MODEL to a smaller variant.
  • message_quota_exceeded — workspace plan cap reached. Upgrade workspace plan.
  • conversation_not_found — widget JWT is older than the conversations.cleared_at on its conversation row. Visitor needs to refresh the page so the widget reissues a fresh JWT via the next /api/v1/widget/init.

Symptom: widget shows but the launcher pill never appears

Theme conflict. Some themes set iframe { display: none !important } or use a global z-index reset. The Pitchbar widget renders inside a Shadow DOM but its mount point is a <div> on the host page.

Fix: add this CSS to your theme's Additional CSS:

#pitchbar-root,
#pitchbar-root * {
    display: revert !important;
    visibility: visible !important;
    z-index: 2147483647 !important;
}

Symptom: the microphone doesn't work

Hover the mic: its tooltip names the problem.

  • "Microphone blocked…" — the visitor (or their browser settings) refused microphone access for your site. They allow it from the lock icon in the address bar and click the mic again.
  • "Voice input failed…" in Brave, Arc, Dia or Firefox — these browsers have no working speech service, so the widget records the clip and your server transcribes it (Voice mic). Check storage/logs/laravel.log for widget.transcribe_failed (the provider returned an error) or widget.transcribe_unavailable (no provider can transcribe: an OpenRouter-only install needs Cloudflare or OpenAI credentials for voice).
  • Mic greyed out — usually a page served over plain http://. Browsers only allow the microphone on https:// pages.

Still stuck?

Reach out at support@pitchbar.app with:

  • One screenshot of the front-end page where the widget isn't showing.
  • Output of tail -200 storage/logs/laravel.log (or browser Console output if the script never reached your server).
  • The URL of an affected page (if public).