Aetheris Chat
Integration guide

One snippet.
Every platform.

Aetheris Chat ships as a single async-loaded <script> tag. Paste it once, anywhere on your site, and the widget mounts itself in a Shadow DOM — no build step, no framework binding, no CSS collisions. Below, the exact spot to paste it on every common platform.

The universal snippet
HTML
<script
  src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
  async
></script>

Replace YOUR_PUBLIC_KEY with the key from your dashboard. The widget loads asynchronously — no impact on your page's first paint.

Pick your platform

Jump to your stack.

No-code platforms

Site builders & CMS.

All of these accept arbitrary script tags through a built-in panel — no plugins required (with one WordPress exception). If your platform isn't listed, look for "custom code," "header / footer scripts," or "tracking code."

WordPress

Easy60 sec

Use our official WordPress plugin. One-click install, settings page in wp-admin, knowledge base ingestion + analytics without leaving WordPress. The snippet path below works too — but the plugin gives you a much nicer admin experience and is what we recommend.

  1. 1

    Download the plugin zip from /wordpress (~80 KB). Then in wp-admin: Plugins → Add New → Upload Plugin → choose the zip → Install Now → Activate.

  2. 2

    Aetheris Chat → Settings (left sidebar) → paste your Public Key → Save. The widget appears on every page automatically — no theme edits, no code injection.

  3. 3

    Optional: paste your API key on the same Settings page to unlock the in-WordPress Knowledge Base + Dashboard tabs. Without it, the widget still works; you just can't manage the KB from inside WordPress.

NoteSubmission to wordpress.org is in progress. Once approved, you'll be able to install via Plugins → Add New → search “Aetheris AI Chat” and get auto-updates. Until then, the latest build is downloadable from /wordpress.

NoteIf you'd rather paste a script tag than install a plugin: drop the snippet at the top of this page into wp-admin via the WPCode plugin (or your hosting provider's “Custom HTML / Tracking code” field). Same widget, manual setup.

Shopify

Easy2 min

Edit the theme layout file directly. Works on every Shopify plan and every theme — including Online Store 2.0 themes.

  1. 1

    Online Store → Themes → click ⋯ next to your live theme → Edit code.

  2. 2

    Open Layout → theme.liquid.

  3. 3

    Find the closing </body> tag near the end. Paste the snippet on the line right before it, then Save.

    <script
      src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
      async
    ></script>

Wix

Easy3 min

Wix lets you inject custom code from Settings. Requires a paid plan (custom code is gated on Free).

  1. 1

    Wix Editor → Settings → Custom Code.

  2. 2

    Click + Add Custom Code.

  3. 3

    Paste the snippet, name it “Aetheris Chat”, set Add Code to → Body — end, Apply to → All pages, then Apply.

    <script
      src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
      async
    ></script>

Squarespace

Easy2 min

Squarespace ships with a Code Injection panel built for exactly this. Available on Business plans and above.

  1. 1

    Settings → Advanced → Code Injection.

  2. 2

    Paste the snippet into the Footer field (not Header — keeps the widget out of critical-path render).

    <script
      src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
      async
    ></script>
  3. 3

    Save and refresh your live site to verify the launcher appears.

Webflow

Easy2 min

Two paths: site-wide via project settings, or single-page via the page settings panel.

  1. 1

    Site Settings → Custom code → Footer code. (For one page only, use the gear icon on the page → Custom Code → Before </body>.)

  2. 2

    Paste the snippet, then Save Changes.

    <script
      src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
      async
    ></script>
  3. 3

    Re-publish the site to push the change to the live domain.

Framer

Easy2 min

Framer's Custom Code panel handles arbitrary script tags cleanly.

  1. 1

    Site Settings → General → Custom Code.

  2. 2

    Paste the snippet into End of <body> tag.

    <script
      src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
      async
    ></script>
  3. 3

    Publish.

Ghost

Easy2 min

Ghost's Code Injection lives in Settings — no theme editing required.

  1. 1

    Settings → Code injection.

  2. 2

    Paste the snippet into Site Footer (NOT Site Header), then Save.

    <script
      src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
      async
    ></script>

Adobe Experience Manager

AdvancedAsk IT

AEM is enterprise CMS — your platform team typically owns custom scripts. Hand them this section and the snippet.

  1. 1

    Recommended path: add the snippet via a clientlib associated with the site's root template. Create a clientlib at /apps/<your-site>/clientlibs/aetheris-chat with category aetheris.chat, embed an HTML fragment, and inject it via the page template's footer include.

  2. 2

    Faster path (non-prod / single-page): on the target page → Page Properties → Advanced → Configuration → External Style Sheets/Scripts. Paste the snippet there.

    <script
      src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
      async
    ></script>
  3. 3

    If your CSP is locked down, allowlist chat.aetherisinnovations.com in script-src and api.chat.aetherisinnovations.com in connect-src.

NoteAEM dispatcher must allow the static asset request to /widget.js on the publish tier — not usually a problem since it's loaded from a third-party domain, but worth a sanity check.

Code projects

Frameworks & codebases.

For framework-based projects, the rule is the same: get the snippet into the static entry HTML or use the framework's built-in script primitive. Avoid mounting via component lifecycle hooks — that can multi-mount in dev.

Plain HTML / static sites

Easy30 sec

The canonical method. Works on any handwritten HTML, GitHub Pages, S3 + CloudFront, Netlify, Cloudflare Pages — anywhere you control the HTML.

  1. 1

    Paste the snippet directly before the closing </body> tag of every page where you want the widget.

    <script
      src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
      async
    ></script>
  2. 2

    If you have a shared template / partial / include, put it there once and you're done.

React (Create React App)

Easy1 min

Add the script tag to the static index.html — not to a component. React Strict Mode mounts components twice in dev, which would load the widget twice.

  1. 1

    Open public/index.html.

  2. 2

    Paste the snippet right before </body>. That's it.

    public/index.htmlcode
    // public/index.html — add before </body>
    <script
      src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
      async
    ></script>

NoteDon't use react-helmet or a useEffect to inject the script — those run on every render and can multi-mount the widget. The static index.html is the right place.

Vite + React

Easy1 min

With Vite, the entry HTML is at the project root (not inside public/).

  1. 1

    Open index.html at the project root. Paste the snippet right before </body>.

    index.htmlcode
    <!-- index.html (project root) — add before </body> -->
    <script
      src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
      async
    ></script>

Next.js (App Router)

Easy1 min

Use next/script with strategy="afterInteractive" so the widget loads after hydration but doesn't block first paint.

  1. 1

    Edit your root layout.

    app/layout.tsxcode
    // app/layout.tsx
    import Script from "next/script";
    
    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang="en">
          <body>
            {children}
            <Script
              src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
              strategy="afterInteractive"
            />
          </body>
        </html>
      );
    }

NotePages Router users: drop the same <Script /> into pages/_document.tsx or pages/_app.tsx — same strategy.

NoteIf you want the widget on only specific routes, move the <Script /> into that route's layout instead of the root layout.

Vue 3 (Vite)

Easy1 min

Same pattern as Vite + React — the entry HTML is at the project root.

  1. 1

    Open index.html (project root). Paste the snippet right before </body>.

    index.htmlcode
    <!-- public/index.html (Vue 3 + Vite) — add before </body> -->
    <script
      src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
      async
    ></script>

Nuxt 3

Easy1 min

Configure the script in nuxt.config.ts so it ships with every page automatically.

  1. 1

    Add the script entry to your Nuxt config.

    nuxt.config.tscode
    // nuxt.config.ts
    export default defineNuxtConfig({
      app: {
        head: {
          script: [
            {
              src: "https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY",
              async: true,
            },
          ],
        },
      },
    });

Angular

Easy1 min

Edit the application's index.html. Angular's CLI bundles assets but leaves the entry HTML alone.

  1. 1

    Open src/index.html. Paste the snippet before </body>.

    src/index.htmlcode
    <!-- src/index.html — add before </body> -->
    <script
      src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
      async
    ></script>

SvelteKit

Easy1 min

Add to the SvelteKit app shell so it ships across SSR + client.

  1. 1

    Open src/app.html. Paste the snippet inside the <body> tag, right after %sveltekit.body%.

    src/app.htmlcode
    <!-- src/app.html (SvelteKit) — inside the <body> tag, after %sveltekit.body% -->
    <script
      src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
      async
    ></script>

Astro

Easy1 min

Add to the root layout component so every page inherits it.

  1. 1

    Edit your root layout (typically src/layouts/Layout.astro).

    src/layouts/Layout.astrocode
    ---
    // src/layouts/Layout.astro
    ---
    <html>
      <body>
        <slot />
        <script
          src="https://chat.aetherisinnovations.com/widget.js?client=YOUR_PUBLIC_KEY"
          async
        ></script>
      </body>
    </html>
Lead routing

From widget to your CRM.

Every captured lead lands in three places: the dashboard inbox (always), an optional notification email, and an optional outbound webhook. The webhook is the universal adapter — point it at Zapier or Make and you can pipe leads into HubSpot, Pipedrive, Salesforce, Attio, Close, Slack, Sheets, Notion, or anything else they support, without us having to build a native integration for each.

What we send

On every new lead, we POST a single JSON payload to your webhook. The widget auto-captures page URL, referrer, and UTM parameters; the LLM writes a one-line transcript summary and an intent tag (demo_request, pricing_inquiry, support_question, etc.) before delivery.

POST <your webhook URL>code
POST https://your-webhook-url
Content-Type: application/json
User-Agent: Aetheris-Webhook/1.0

{
  "event": "lead.created",
  "client": {
    "id": "9b3e7f0a-…",
    "name": "Acme Coffee Roasters"
  },
  "lead": {
    "id": "fae12d8a-…",
    "name":     "Sam Rivera",
    "email":    "sam@example.com",
    "phone":    "+1 555 123 4567",
    "company":  "Globex",
    "message":  "Hi — looking for pricing on a 50-seat plan.",
    "intent":   "pricing_inquiry",
    "transcript_summary":
      "Visitor compared the Studio and Agency plans, then asked for volume pricing on 50 seats.",
    "page_url": "https://acme.example/pricing",
    "referrer": "https://google.com/",
    "utm_source":   "google",
    "utm_medium":   "cpc",
    "utm_campaign": "spring-launch",
    "utm_term":     null,
    "utm_content":  null,
    "created_at":   "2026-04-25T17:32:08Z",
    "conversation_id": "12cb4e5a-…"
  }
}

Delivery is at-least-once with up to 3 retries on 5xx (exponential backoff, 0.5s → 4s). 4xx is treated as terminal — return 4xx if the lead is malformed and you don't want a retry. Use lead.id as your idempotency key.

Dashboard

Always on. Read leads, expand for full context (summary, page, UTMs), or export to CSV.

Email

Optional. Set Notification email in Settings — we send a formatted summary on every lead.

Webhook

Optional. Set Webhook URL in Settings → Send test → wire to Zapier / Make / your own server.

Zapier (any CRM)

Easy3 min

The fastest path into HubSpot, Pipedrive, Salesforce, Attio, Close, Folk, Monday, Notion, Sheets, Airtable, Mailchimp — anything Zapier supports. One Aetheris webhook, any destination.

  1. 1

    In Zapier: Create Zap → Trigger → search “Webhooks by Zapier” → Catch Hook. Copy the URL Zapier gives you.

  2. 2

    In Aetheris: Settings → Lead routing → paste the URL into Webhook URL → Send test → Save.

  3. 3

    Back in Zapier, “Test trigger” will pick up the test event so you can map its fields to the next step (HubSpot Create Contact, Slack Send Message, Sheets Append Row, etc.).

  4. 4

    Field mapping for HubSpot specifically:

    // In Zapier, the HubSpot "Create or Update Contact" action.
    // Map these fields from the webhook payload:
    
    email        →  {{lead__email}}
    firstname    →  {{lead__name}}    // (Zap formatter: split on " ", first part)
    lastname     →  {{lead__name}}    // (Zap formatter: split on " ", remainder)
    phone        →  {{lead__phone}}
    company      →  {{lead__company}}
    website      →  {{lead__page_url}}
    hs_lead_status → "NEW"
    notes        →  {{lead__transcript_summary}}
    hs_analytics_source       → {{lead__utm_source}}
    hs_analytics_source_data_1 → {{lead__utm_campaign}}

NoteFree Zapier tier covers ~100 leads/month with single-step Zaps. The webhook fires per lead — no polling, no delay.

Make.com

Easy3 min

Like Zapier, with more powerful branching and lower per-task pricing. Useful when you want to fan out one lead to multiple destinations (CRM + Slack + Sheet) in a single scenario.

  1. 1

    In Make: + Create scenario → first module → search “Webhooks” → Custom webhook → Add. Copy the URL.

  2. 2

    In Aetheris: Settings → Lead routing → paste → Send test → Save. Make's “Determine data structure” auto-fills the schema from the test payload.

  3. 3

    Add downstream modules — HubSpot, Slack, Google Sheets, an iterator, a router — and map fields like in Zapier.

Slack (channel notifications)

Easy4 min

Drop new leads straight into a #leads channel so the whole team sees them in real time. Easiest path is Zapier with the Slack action — but if you've already got an Incoming Webhook, you'll need the proxy step below since the payload shape doesn't match Slack's.

  1. 1

    Recommended: Zapier route. Zap = Webhooks (Catch Hook) → Slack (Send Channel Message). Use this template:

    // In Zapier, choose the Slack "Send Channel Message" action.
    // Use Block Kit for a richer card, or this plain template:
    
    🟢 *New lead* · {{client__name}}
    *{{lead__name}}* · <mailto:{{lead__email}}|{{lead__email}}> · {{lead__company}}
    
    > {{lead__transcript_summary}}
    
    _Intent:_ `{{lead__intent}}`
    _From:_ <{{lead__page_url}}|{{lead__page_url}}>
    _UTMs:_ {{lead__utm_source}} / {{lead__utm_medium}} / {{lead__utm_campaign}}
  2. 2

    Direct path (no Zapier): point our webhook at a Cloudflare Worker / Vercel Edge Function / Make scenario that reshapes the payload into Slack's `{ text, blocks }` format and forwards it on. Slack's Incoming Webhook expects its own schema.

Google Sheets

Easy2 min

A live append-only log of every lead — useful as a backup of record, a quick-and-dirty CRM, or input to a BI tool.

  1. 1

    Create a sheet with header row: created_at, name, email, phone, company, intent, summary, page, utm_source, utm_campaign.

  2. 2

    Zapier: Webhooks (Catch Hook) → Google Sheets (Create Spreadsheet Row). Map each field to the matching column.

  3. 3

    Aetheris: paste Zapier's webhook URL into Settings → Lead routing → Send test → Save.

NoteSame flow works for Airtable — swap the Sheets action for the Airtable “Create Record” action.

Self-hosted (n8n, your own API)

Medium10 min

Skip Zapier and receive the webhook on your own server. Same payload shape, no per-task fees, you own the retry semantics. Good fit when you already run n8n or have an internal events service.

  1. 1

    Build any HTTPS endpoint that accepts JSON POSTs. Validate the User-Agent header equals `Aetheris-Webhook/1.0` (cheap sanity check) — full HMAC signing is on the roadmap.

  2. 2

    Verify your endpoint locally before pointing Aetheris at it:

    # Verify your webhook receiver from your laptop before flipping the switch
    curl -X POST https://your-webhook-url \
      -H 'Content-Type: application/json' \
      -H 'User-Agent: Aetheris-Webhook/1.0' \
      -d '{
        "event": "lead.test",
        "client": { "id": "test", "name": "test" },
        "lead": {
          "id": "00000000-0000-0000-0000-000000000000",
          "name": "Test Visitor",
          "email": "test@example.com",
          "company": "Acme",
          "message": "This is a test event.",
          "intent": "demo_request",
          "transcript_summary": "Visitor wanted a quick demo."
        }
      }'
  3. 3

    We retry up to 3 times on 5xx with exponential backoff (~0.5s, ~1s, ~2s). Treat 4xx as terminal — return 4xx for permanent rejection, 5xx if you want us to retry.

NoteIdempotency: each delivery includes the lead's UUID at `lead.id`. Use it as the key when upserting downstream so retries don't create duplicates.

Common questions

Before you
paste.

Where do I find my public key?
Dashboard → your chatbot → Embed tab. The key starts with ac_ and is safe to expose in client-side HTML — it's scoped to a single chatbot and read-only.
Can I run different chatbots on different pages?
Yes — load each one with its own public key. Each chatbot has its own knowledge base, branding, and lead inbox. Studio plan lets you run 3, Agency lets you run 20.
Will the widget slow down my site?
No measurable impact. The script is loaded async (it doesn't block parsing or first paint), the widget only mounts when a user clicks it open, and the bundle is ~80 KB gzipped. We use Vercel's edge network for global delivery.
Does it conflict with my site's CSS?
Never. The widget renders inside a Shadow DOM — your CSS can't reach into it and ours can't leak out. Tested against Bootstrap, Tailwind, vanilla CSS, and a dozen WordPress themes.
What if I have a Content Security Policy?
Add chat.aetherisinnovations.com to script-src, api.chat.aetherisinnovations.com to connect-src, and (if your widget logo loads from Supabase) your Supabase project domain to img-src.
How do I verify it's working?
Open your site, look for the launcher in the bottom-right corner. Click it. If you see the welcome message you configured, you're live. If nothing appears, open DevTools → Network and confirm widget.js loaded with status 200.
Can I hide the widget on specific pages?
Yes — only include the script on pages you want it on. For most platforms that means scoping the snippet to specific page templates rather than the global footer.
Do you have a native HubSpot / Salesforce / Pipedrive integration?
Not yet — by design. Native integrations have a long maintenance tail (OAuth refresh, field-mapping UI, per-vendor API drift), so for v1 we built one outbound webhook that covers all of them via Zapier or Make. Once a paying customer asks for a specific native integration we'll prioritize that one. The webhook is already in production — see Lead routing above.
Is the webhook signed? How do I verify it's really from Aetheris?
Today: requests carry the User-Agent header `Aetheris-Webhook/1.0` and originate from our backend's outbound IP, but there's no HMAC signature yet. For now, treat the webhook URL itself as a secret — it's per-client and rotatable from Settings. HMAC signing with a per-client secret is on the near-term roadmap.
What if my webhook is down when a lead comes in?
We retry up to 3 times with exponential backoff (~0.5s, ~1s, ~2s) on any 5xx response or transport error. After that the lead is still safely persisted in the dashboard inbox and the notification email (if configured) — only the webhook delivery is dropped. CSV export gives you a permanent backfill path.
Still stuck?

We'll wire it up
for you.

Email a link to your site and a sentence about what you want the assistant to know. We'll send back a working snippet, ingested knowledge base, and a 10-minute walkthrough video. No charge for paying customers.