BookbagBookbag
Platform Guides

How to Set Up AI Customer Support on a Headless or Custom Store

Running a headless Shopify storefront, a custom Next.js or Nuxt build, or a fully bespoke commerce stack? AI customer support is still fully achievable. You skip the one-click app and connect the APIs yourself — here is the complete playbook.

The Bookbag Team·June 2026· 14 min read

What headless means for AI customer support

AI customer support works on a headless or custom store the same way it works anywhere else — the agent resolves WISMO questions, processes returns, looks up orders, and recommends products. The only thing that changes is the plumbing. There is no app store to click, so you connect your commerce APIs by hand and embed the chat widget in your own frontend code. That is the entire difference, and it is a one-time setup.

A headless architecture decouples the storefront customers see from the commerce backend that holds inventory, orders, and checkout. The frontend is usually a custom React, Next.js, Nuxt, Remix, or Astro app that calls a commerce API — Shopify's Storefront and Admin APIs, BigCommerce headless, Commercetools, Saleor, Medusa, or a fully proprietary backend. The backend stays the same; the head is yours.

For support automation this creates two practical differences from a plug-and-play platform. First, no plugin directory installs a widget for you, so you add the snippet to your layout component yourself. Second, you cannot lean on a managed integration that authenticates behind the scenes — you provide API credentials directly and configure what the agent is allowed to read and do.

Neither is a real barrier. If your team can ship a headless storefront, wiring up an AI agent is a smaller lift than the storefront itself. The work is deliberate rather than one-click, and the payoff is identical.

What stays the same

The ticket types worth automating (WISMO, returns, refunds, product questions) and the realistic automation ceiling (up to ~70% of tickets resolved autonomously) do not change on headless. The integration path is different; the outcome is not.

Data integration strategy for headless stores

Start by mapping where each piece of support-relevant data actually lives. On a monolithic Shopify store the answer is always Shopify. On a headless build, orders might be in Shopify while product content sits in Contentful and shipping events flow through ShipStation. The agent needs to reach the systems of record, not your storefront cache, so list the real source for each data type before you touch any code.

Bookbag connects to headless Shopify with a Shopify Admin API access token, to BigCommerce and other platforms via their REST or GraphQL APIs, and to fully custom backends through a configurable order-lookup endpoint you expose. The principle is the same across all of them: the agent reads live order and customer data at conversation time, so a status answer is accurate the moment a shopper asks rather than as of a nightly sync.

There is a real choice between live API reads and a synced copy of your data, and for support you almost always want live reads. A nightly export goes stale exactly when it hurts most — a customer asking where their order is at 9pm does not care that the data was fresh at midnight. Querying the system of record at conversation time costs a few hundred milliseconds and removes an entire class of wrong answers. The exception is product catalog content for very large stores, where a periodic bulk import of descriptions is fine because product copy changes slowly.

The table below is the mapping most headless teams end up with. Use it as a checklist — for every row, write down the exact API or document you will point the agent at.

Data typeCommon source on headless storesHow the agent reaches it
Orders + fulfillmentShopify Admin API, Commercetools, Medusa, custom DBREST or GraphQL credential / lookup endpoint
Customer profilesCommerce backend, or a separate CDP (Segment, Klaviyo)REST or GraphQL, or identify() from the frontend
Product catalogShopify Storefront API, Contentful, Sanity, custom PIMREST or GraphQL, or bulk import
Tracking / shippingShipStation, EasyPost, Shippo, AfterShipWebhooks or polling; surfaced in order data
Policies + FAQHeadless CMS (Contentful, Sanity, Prismic)Knowledge import (paste, URL crawl, or API)
Return / refund rulesYour own configuration, not an APIKnowledge document the agent reads
Decide read vs. write up front

Reads (order status, tracking) are low-risk and worth enabling everywhere. Writes (issuing a refund, creating a return) should run inside merchant-set rules and caps. Scope the agent's write permissions before launch so an automated refund can never exceed the limits you set.

Embedding the Bookbag widget in a custom frontend

The widget is a single JavaScript snippet — one script tag that loads the chat experience on any page. On a platform store an app injects it; on a headless store you add it to your root layout so it renders on every route. There is no build step and no npm dependency required for the basic embed.

Load it with a deferred or after-interactive strategy so it never blocks your first paint. Core Web Vitals matter for both conversion and SEO, and a support widget should sit downstream of your critical render path. The snippets below cover the frameworks most headless stores run on.

// Next.js App Router — app/layout.tsx
import Script from 'next/script'

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script
          src="https://cdn.bookbag.ai/widget.js"
          data-agent="bk_your_public_key"
          strategy="afterInteractive"
        />
      </body>
    </html>
  )
}

Next.js (Pages Router)

Add the same Script component inside your layout wrapper in pages/_app.tsx. The afterInteractive strategy is correct here too — it loads the widget once the app is hydrated.

Nuxt / Vue

Register the snippet in nuxt.config.ts under app.head.script with defer set, or mount it in your default layout's onMounted hook. Either way the widget loads on every route without a per-page tag.

Remix / Astro / plain SPA

Drop the script into your root document (root.tsx in Remix, the base layout in Astro) or just before the closing body tag in a static index.html. For any client-side-routed SPA, placing it in the app shell means a single load that persists across navigations.

Passing customer context to the agent

On a standard Shopify store the widget can read the logged-in customer from the session. On a headless store you control the session, so you tell the agent who the shopper is by calling the JavaScript API when they authenticate. Done right, a returning customer opens the chat and the agent already knows their last order — no email prompt, no friction.

Call window.bookbag.identify() with the customer's email (and optionally name and customer ID) at login and on any page load where an active session exists. This is usually a one-line addition to your auth callback or your customer-hydration logic. For security-sensitive actions like refunds, Bookbag supports a server-signed HMAC on the identify payload so the agent trusts that the email truly belongs to the logged-in user rather than something typed into the browser.

Guests matter just as much on headless stores, where plenty of shoppers check out without an account. The agent falls back to an order-number-plus-email lookup, so it can still resolve a WISMO question for someone who never registered.

Identity is also what turns generic support into personalization. With the customer known, the agent can greet them by name, reference their most recent order without making them dig for it, and tailor recommendations to what they have bought. Industry benchmarks consistently show that order-status and WISMO questions make up a large share of ecommerce support volume — frequently quoted in the 30-50% range — and most of that volume evaporates when the agent can answer instantly from a logged-in customer's order history.

  • Call window.bookbag.identify({ email }) on login and on page load when a session exists.
  • Pass at minimum the email; optionally add first name for personalized greetings and customer ID for faster lookups.
  • Use the server-signed HMAC option before enabling any write action (refunds, returns) so identity is verified, not self-asserted.
  • Call window.bookbag.reset() on logout to clear the session so a shared device does not leak the previous customer's data.
  • Keep the guest path enabled — order number plus email is the fallback for headless stores where account creation is optional.
Verify identity before write actions

A client-side identify() call is fine for personalization and read-only order lookups. The moment the agent can issue a refund or change an order, require the HMAC-signed payload from your server. It is the difference between convenient and exploitable.

Order lookup and automated actions

Order lookup is the workhorse of ecommerce support — it powers WISMO answers, return eligibility, and refund status. On a headless Shopify store the mechanics are identical to a native install: you supply an Admin API access token, and the agent queries orders, fulfillments, and tracking with it. The only change is that you paste the token into Bookbag's settings instead of approving an app.

For non-Shopify and proprietary backends, you expose a single order-lookup endpoint. Bookbag calls your URL with a customer identifier; your service returns order data in a small, standard JSON shape. This is the highest-leverage hour of engineering in the whole setup, because once the agent can read an order it can answer the majority of inbound questions on its own.

Keep the schema lean to start. The fields below cover almost every WISMO and returns conversation; you can extend later once the basics are live.

FieldWhy the agent needs itPowers
order_number + statusIdentify the order and its lifecycle stageWISMO, cancellations
line_itemsKnow what was bought and how manyReturns, exchanges, product questions
tracking_number + carrierGive a live shipping answer with a linkWISMO, delivery ETAs
estimated_deliverySet expectations before the customer asks againProactive WISMO deflection
fulfillment + refund statusDistinguish shipped vs. refunded vs. pendingWISMR, refund status updates
For fully custom backends

If your commerce stack is proprietary, your team builds one lightweight read endpoint that returns the fields above. Most engineering teams ship this in one to two days. Refund and return writes can come in a second pass once read lookups are proven in production.

CSP and deployment gotchas to expect

The single most common reason a widget silently fails to appear on a custom store is a Content Security Policy. Headless teams tend to ship strict CSP headers, which is good security practice — but a CSP that does not allow the widget's domain will block the script with no visible error beyond a console warning. If the widget loads in a CodeSandbox but not on production, suspect the CSP first.

Add the widget's host to your script-src and connect-src directives (and, depending on the build, frame-src for the chat panel). Bookbag publishes the exact domains to allow in its developer docs. Test the header in production, not just locally, because many frameworks inject a different CSP at the edge or via a hosting layer than the one in your dev config.

Beyond CSP, a few framework-specific quirks trip people up. Server components and partial hydration can change when the script actually executes, single-page routing means you load the widget once rather than per navigation, and aggressive ad-blockers occasionally need a first-party proxy. None are dealbreakers; they are just things to verify rather than assume.

One more environment trap is preview and staging origins. Widget configuration is often tied to the domain it loads on, so a build that works on your production host can behave differently on a Vercel preview URL or a localhost tunnel. Test on a domain that matches production, and if you use multiple environments, confirm each origin is allowed rather than discovering it during a launch.

  • Allow the widget domain in script-src and connect-src; add frame-src if your CSP enumerates frames.
  • Test the CSP that ships to production — edge middleware and host platforms often rewrite it.
  • Load the script once in the app shell for client-routed SPAs, not inside a per-page component that remounts.
  • Confirm afterInteractive / defer placement so the widget never delays Largest Contentful Paint.
  • If a first-party proxy or custom domain is required for ad-blocker resilience, set it up before launch, not after.

Knowledge base for custom platform stores

An AI agent is only as good as what it can read. On a headless store your policies and FAQs usually live in a headless CMS — Contentful, Sanity, Prismic — rather than on platform-managed policy pages. Get that content into the agent's knowledge base so it answers returns, shipping, and warranty questions from your actual policy instead of guessing.

Three import paths cover almost every setup. You can paste or upload the documents directly, point the agent at your public policy and FAQ URLs and let it crawl them, or — for enterprise CMS setups — connect the CMS API so updates flow in on a schedule. A scheduled re-crawl matters more on headless stores because content changes ship continuously rather than through a platform admin.

For very large catalogs served by a PIM, you do not need every SKU in the knowledge base. Export the descriptions and key attributes of your top sellers, where the pre-sale questions concentrate, and let live catalog lookups handle the long tail. A focused knowledge base beats an exhaustive one the agent has to wade through.

Testing and monitoring on a custom store

Headless frontends vary more than platform stores — different build tools, CSPs, and JavaScript execution contexts — so test the widget deliberately before and after each major deploy. The goal is to confirm the agent loads, identifies customers, reads orders, and escalates cleanly across the page types and devices your customers actually use.

Run this pass on a staging build that mirrors your production CSP and hosting layer, then spot-check the same flows once live. A widget that works in development but not in production is almost always a header or environment difference, and catching it on staging saves a support outage.

  1. 1Confirm the widget loads on every key page type: home, product detail, cart, and order confirmation.
  2. 2Log in as a test customer and verify the agent pulls their orders without asking for an email.
  3. 3Run a guest lookup with order number plus email and confirm the agent returns the correct order.
  4. 4Trigger an escalation and verify the handoff lands in your help desk or inbox with full conversation context.
  5. 5Inspect the production CSP and confirm the widget domain is allowed in script-src and connect-src.
  6. 6Test on iOS Safari and Android Chrome — mobile WebKit sometimes loads third-party scripts differently than desktop.
Watch resolution rate, not just uptime

Once live, track resolution rate, escalation rate, and CSAT in the analytics dashboard. A widget that loads everywhere but escalates 60% of chats usually has a knowledge gap, not a code bug — and the fix is content, not engineering.

End-to-end setup steps for a headless launch

Here is the full sequence from zero to a live agent on a headless or custom store. Most teams move through it in well under a day of focused work for read-only support, with refund and return writes following in a second pass once reads are proven.

The order matters: connect data first so you can test lookups, then embed the widget, then layer on identity and write actions. Launching the widget before the data is connected just produces an agent that apologizes a lot.

  1. 1Map your data sources using the table above — one real API or document per data type.
  2. 2Connect order data: paste a Shopify Admin API token, or stand up a single order-lookup endpoint for a custom backend.
  3. 3Import knowledge: paste, crawl, or API-connect your policies and FAQ from your CMS, and schedule a re-crawl.
  4. 4Embed the widget snippet in your root layout with an after-interactive or deferred load.
  5. 5Add window.bookbag.identify() to your auth flow, with HMAC signing before any write action.
  6. 6Allow the widget domain in your production CSP (script-src, connect-src, frame-src as needed).
  7. 7Run the full test pass on staging, then on production, and confirm escalation routing.
  8. 8Go live read-only, watch resolution and escalation rates for a week, then enable scoped refund and return actions.
Typical timeline

Headless Shopify with read-only support: often live the same day. Fully custom backend with a new lookup endpoint: usually one to two engineering days, plus a content pass on the knowledge base. Write actions add a short, scoped second phase.

Where Bookbag fits for headless and custom stores

Bookbag is an AI customer support agent built for ecommerce, and it was designed to be API-first rather than locked to one platform's app store. That is exactly what a headless or custom stack needs: native Shopify, WooCommerce, and BigCommerce connections when you want them, plus direct API credentials, a configurable order-lookup endpoint, an npm SDK, and a one-line widget when you are running your own head. The agent takes real actions — order tracking, returns, refunds within your rules, product recommendations — across chat, email, WhatsApp, Instagram, and Messenger from day one.

Pricing is flat monthly plans with message-credit allowances, not per-resolution. For an engineering-led store that is a meaningful difference: as the agent gets better and resolves more, your bill does not climb as a penalty for success. You can model the cost against your ticket volume on the pricing page rather than guessing at a per-ticket meter.

Bookbag is not the lightest-touch option if you want a no-code, zero-API install — a monolithic platform store with a one-click app is genuinely simpler. But if you have already chosen a headless or custom architecture, an agent that speaks API natively is the right shape, and the setup above is the whole job.

Key takeaways

  • Headless and custom stores get the same AI support outcomes as platform stores — only the integration is API-first instead of one-click.
  • Connect order data via a Shopify Admin API token or a single custom order-lookup endpoint; reads unlock most of the automation.
  • Embed the widget in your root layout with an after-interactive load, and pass customer email via window.bookbag.identify().
  • A strict Content Security Policy is the most common reason a widget silently fails — allow the domain in script-src and connect-src.
  • Require HMAC-signed identity before enabling refund or return write actions; client-side identify() alone is read-only safe.
  • Bookbag uses flat message-credit pricing, so resolving more tickets never raises your bill as a per-resolution penalty.

Frequently Asked Questions

Turn support into your competitive edge

Join the ecommerce teams resolving more tickets, answering 24/7, and turning support into a revenue channel with Bookbag.