Enabled / disabled pages
The widget defaults to “every page” — once you install the snippet, it runs everywhere. Sometimes that’s wrong. Checkout pages, admin dashboards, legal documents, login flows — places where a surprise voice orb would be unwelcome.
Two configuration lists:
- Enabled pages — if set, the widget loads only on these URL patterns.
- Disabled pages — the widget loads everywhere except these.
You can use either. If you set both, the widget loads only on pages that match enabled_pages and do not match disabled_pages.
URL patterns
Patterns are glob-style, matched against window.location.pathname:
| Pattern | Matches |
|---|---|
/ | Only the homepage |
/products | Exact path /products |
/products/* | Any path starting with /products/ |
/products/** | Any path starting with /products/ (recursive — same as * here) |
/blog/**/draft | Any blog post ending in /draft |
!/checkout/** | Not the checkout flow (prefix ! to negate inside a list) |
Patterns are case-sensitive. Query strings (?foo=bar) and hash fragments (#top) are ignored.
Common scenarios
E-commerce
{ "enabled_pages": ["/", "/collections/**", "/products/**", "/blog/**"], "disabled_pages": ["/checkout/**", "/account/**"]}- Orb appears on shopping pages
- Orb hides on checkout (Shopify already blocks scripts there, but this is defense in depth)
- Orb hides on the logged-in customer account area
SaaS marketing site + app
{ "enabled_pages": ["/**"], "disabled_pages": ["/app/**", "/admin/**", "/api/**"]}- Widget on marketing pages
- Hidden in the logged-in app and admin
Blog only
{ "enabled_pages": ["/", "/blog/**"]}Where to configure
Dashboard → Appearance → Page visibility.
Pattern changes take effect on the next page load (after the cache TTL — usually seconds).
Programmatic control
For complex rules (e.g. “only for logged-in users,” “only on A/B test variant B”), don’t install the widget site-wide. Instead, conditionally load it from code. See the framework-specific install guides:
Automatic disables
The widget self-disables in these situations, regardless of your config:
- Inside an
<iframe>— voice in iframes has platform mic restrictions that make it unreliable - On
http://(non-local) — voice requires HTTPS - On Shopify checkout (
/checkouts/*) — Shopify prohibits third-party scripts there - When the browser is Safari in private mode and localStorage is unavailable
- When
prefers-reduced-datais set toreduce(we honor user-agent preferences)
Mobile vs. desktop
You can’t toggle the widget by viewport. If you want mobile-only or desktop-only, use your site’s CSS to hide the widget’s root:
/* Hide on mobile */@media (max-width: 767px) { spelo-widget { display: none !important; }}The widget’s custom element tag is <spelo-widget> — target it from your site’s CSS.
See also
- Restricted topics — control what the AI discusses, not where
- Privacy notice — the first-interaction disclosure
- Troubleshooting: orb not appearing