APP_URL serves). It is a platform-level
setting — only super_admins of the install can configure it.
Customers (workspace members) who want a chat widget on
their marketing site embed the standard install
snippet (see Install snippet)
on their own server — they don't need this toggle at all.
The Pitchbar install's public marketing site (home page + any
/marketing/* route) can host a real chat widget
pointed at one of the install's published agents — not just the
seeded demo sandbox. Configure it under
Settings → Marketing → Marketing-site widget
(super_admin only).
The blade gate in resources/views/app.blade.php
resolves the agent in this order:
marketing_widget_enabled = true AND
marketing_widget_agent_id resolves to a published
agent, that agent is mounted with no demo pill.
DEMO=true is set in
the environment, the seeded MarketingDemoAgent
mounts with the data-demo="true" attribute so
visitors see a "DEMO" pill.
The widget header label resolves with this fallback chain:
agent.persona.name — set in
Agent → Customize → Persona → Display name.
This is the visitor-facing persona; treat it as a stage
name.
agent.name — the internal label set in
Agent → Settings → Basics → Name. Used when
the persona display name is empty, so an agent created
through the dashboard ships with a sensible header without
needing to also touch the persona form.
AI assistant — last-resort
fallback when both fields are empty (legacy seed data).
Saving Marketing → Marketing-site widget flushes
the marketing.demo_agent_id cache (5-minute TTL) and
the per-id marketing.demo_agent_id.explicit_valid.*
cache (2-minute TTL) so the next marketing-page request reflects
the change. Without the flush, toggling off could leave the demo
widget visible for up to 5 minutes (client report 2026-05-23).
Open marketing tabs also pick up the change without a hard reload.
The widget mount payload ships as the marketingWidget
Inertia shared prop, and a small controller component
(resources/js/components/marketing-widget-mount.tsx)
reactively injects or tears down the widget <script>
tag whenever the prop changes. Two trigger paths cover the common
cases:
useEffect compares the new agent_id
to the live DOM and remounts or removes the widget as needed.
router.reload({ only: ['marketingWidget'] })
partial reload so an admin toggling the widget in a sibling
tab takes effect on the marketing tab without a manual
refresh. Client report 2026-05-25.
The agent you pick must have your marketing site's origin (the
APP_URL) in its allowed_origins. Saving
the marketing widget with the agent picked auto-appends the current
APP_URL to the agent's allowed_origins if
it isn't already there — so the widget works the moment you save.
Disabling the widget does not remove origins; you can
safely toggle the widget off and back on without losing CORS
configuration on the agent.