Embedding the PodSaid widget
The widget is a Web Component (<ask-pod-widget>) plus a single <script> tag from our CDN. It renders a floating chat launcher on your site; visitors click it to ask questions about your feed’s content, and every answer cites the exact moment in the sermon or episode. The widget’s UI lives inside a Shadow DOM, so your site’s CSS can’t reach it and its CSS can’t leak into your site — no theme conflicts, no CSS resets to write.
Want to see the finished product on a real customer’s site first? See it in action — three screenshots from Second Baptist Church Houston walking through launcher → question → citation-jumps-to-video.
The whole process, end to end
- Sign up at console.podsaid.com and create a feed for your podcast or church sermon library. Point it at your RSS feed or YouTube channel.
- Wait for ingest. We fetch, transcribe, and index every episode. Takes hours for a normal-sized library; you get an email when it’s ready. See How ingest works (and why it takes hours).
- Grab your embed code from Console → Settings → Embed Code. It’s two lines of HTML with your
feed-idandpk_live_*public key already substituted. - Paste it into your site. The right spot depends on your platform — pick your platform below, or use the universal fallback for any site.
- Add your domain to Allowed Origins. This locks the public key to your sites and no one else’s.
- (Optional) Match your brand with the widget’s CSS variables — accent color, font, spacing, launcher label.
About the security model — same as Stripe’s
The pk_live_* key in your embed code is public by design, exactly like Stripe’s pk_live_* publishable keys. It’s pasted into the page’s HTML in plain sight; every visitor’s browser can read it. That’s fine, because:
- Origin-locked. Every request the widget makes to our API carries the browser’s
Originheader. Our server checks it against your Allowed Origins list; anything else gets a 403 (origin_denied). Someone copying your key out of “view source” and pasting it on their own site sees nothing but denials. - No secret key exists. There is no
sk_live_*for the widget. Nothing to leak; nothing to guard. Sensitive operations — creating feeds, minting keys, viewing usage — happen behind your Console login, which is a separate credential entirely. - Rotate anytime. From Console → Settings → Embed Code you can revoke the current key and mint a new one. Same rotation UX as Stripe. Old embed pages start failing with
key_revoked; you update the paste and you’re back.
The Stripe parallel is intentional. Frontend developers already know the “public API key in the browser” model from years of Stripe Elements, Google Maps, Mapbox, and Turnstile. We haven’t invented anything new here.
Prefer to have an AI do it for you?
If your dev workflow includes Claude Code or any Claude Agent SDK app, skip the hand-written install. We ship a Claude Code install skill that auto-detects your framework, edits the right file, wires TypeScript types, and verifies the widget renders. One-line install — curl -sfL https://console.podsaid.com/install-skill.sh | bash (bash) or iwr -useb https://console.podsaid.com/install-skill.ps1 | iex (PowerShell).
Or read on for per-platform hand-written recipes below.
By platform
Universal fallback for hand-written HTML, static-site generators, and any server-side template (Rails ERB, Laravel Blade, Django, PHP).
Custom HTML block, page builders (Elementor, Divi, Beaver Builder, WPBakery), footer injection.
Code Block on 7.1 or 7.0, Code Injection for site-wide install.
Code block per page, Settings → Code → Header for site-wide. Watch for the keyboard-only paste.
HTML Content block per page, Site Page Header for site-wide. Watch the block cache.
Settings → Custom Code (site-wide, recommended). The per-page HTML Embed element sandboxes into an iframe.
Project Settings → Footer Code for site-wide, HTML Embed element for inline. Requires paid Basic plan.
Vite, Create React App, plain React SPA. The JSX kebab-case gotcha and TypeScript setup.
App Router + Pages Router, the SSR trap, TypeScript setup.
Coming soon
Queued as customers hit them. Email [email protected] to bump priority on any of these.
Publisher-focused CMS with a Code Injection surface.
Native custom-element support via compilerOptions.
Server-rendered by default — client-only pattern for the widget.
Islands architecture, client:only directive for the widget.
CUSTOM_ELEMENTS_SCHEMA and the standalone-component setup.
Cross-cutting reference
- See it in action — screenshots of the widget on a live customer site (Second Baptist Church Houston).
- Allowed origins — the security allowlist that makes your
pk_live_key safe to expose publicly. Every embed doc links here for the domain-management story. - Customization (CSS) — the CSS variables and Shadow Parts the widget exposes for matching your brand.
When you’re stuck
- Widget errors — every reason code, with a fix
- Support — human help if the errors index doesn’t unstick you