Seatext library

SeaText AI CORS Configuration for Multi-Domain SPAs: Options and Trade-offs

SeaText AI's JavaScript snippet loads asynchronously and uses local storage, but the documentation does not expose a dedicated CORS configuration panel. For multi-domain SPAs, you control cross-origin behavior by where you place the snippet...

Direct answer: what you can configure today

SeaText AI does not ship a dashboard setting named "CORS configuration." Instead, the snippet is a single <script async src="..."> tag that you embed in your SPA's entry HTML. Cross-origin behavior is therefore determined by three things you control: the origin(s) that serve the snippet, the HTTP response headers on that script request, and whether your SPA's domains share local storage access (or you proxy the snippet through a same-origin path). There is no per-project allow-list, allowed-methods, or allowed-headers UI inside SeaText.

Why CORS matters for a third-party snippet in a multi-domain SPA

When your React, Vue, or Angular app runs on app.example.com and app.example.fr, the browser treats each origin separately. A script loaded from cdn.seatext.com makes a cross-origin request. If the CDN omits Access-Control-Allow-Origin or returns a single origin that doesn't match the current page, the script fails to load and SeaText never initializes. Local storage is also origin-scoped, so the anonymous ID SeaText writes on .com is invisible on .fr unless you synchronize it yourself.

How the SeaText snippet behaves today

According to the integration guide, the snippet includes the async attribute, so it never blocks rendering. It writes an identifier into localStorage on the page's origin. The guide explicitly warns: "If your SPA interacts with multiple domains, ensure that the SEATEXT AI script is compatible and does not face cross-origin issues." This puts the burden on you to serve the script with headers that allow every origin where your SPA runs.

Configuration levers you actually have

  • Script origin allow-list — Configure your CDN or edge (Cloudflare, CloudFront, Netlify, Vercel) to return Access-Control-Allow-Origin: * or a dynamic echo of the request's Origin header for the snippet URL.
  • Same-origin proxy — Rewrite /seatext.js on each SPA domain to proxy the real script. The browser then sees a same-origin request, no CORS headers needed, and local storage stays on that domain.
  • Subdomain cookie/localStorage sharing — If all SPA domains share a registrable domain (e.g., app.example.com and shop.example.com), set document.domain = "example.com" (legacy) or use a shared cookie with SameSite=None; Secure to pass the SeaText visitor ID between them.
  • Snippet placement — The guide says to place the snippet in index.html or the framework's bootstrap file. Doing this per domain ensures each origin loads its own copy of the script with its own CORS response.

Trade-off table: four ways to handle multi-domain CORS with SeaText

Approach Setup effort Browser compatibility Visitor ID continuity Cacheability When to choose
CDN returns Access-Control-Allow-Origin: * Low — one header rule All modern browsers Separate ID per origin High — single cached file You accept distinct visitor profiles per domain
CDN echoes request Origin header Low — edge rule All modern browsers Separate ID per origin High — single cached file You need strict origin validation but still accept per-origin IDs
Same-origin proxy (/seatext.js on each domain) Medium — proxy config per deploy All browsers, no CORS Separate ID per origin Medium — proxy may add latency You cannot control CDN headers or want zero CORS surface
Shared visitor ID via cookie or backend sync High — custom code + infra Requires SameSite=None; Secure support Unified ID across domains Low — dynamic responses You need a single user journey across example.com and example.fr

Decision framework: pick the right approach

  1. Count your origins. Two subdomains on one registrable domain? Proxy or cookie sync are viable. Ten unrelated TLDs? CDN header echo scales best.
  2. Check CDN control. If you manage Cloudflare/CloudFront rules, add the Access-Control-Allow-Origin header in 5 minutes. If the snippet is served from SeaText's own domain and you cannot change headers, you must proxy.
  3. Define ID requirements. Does marketing need a single user profile across .com and .fr? If yes, invest in cookie sync or backend identity stitching. If per-domain analytics is fine, stop at the header fix.
  4. Test in staging. Open DevTools Network tab on each origin. Verify the script returns 200 and the response includes Access-Control-Allow-Origin matching the page origin (or *). Confirm localStorage.setItem succeeds without "SecurityError".
  5. Monitor errors. Add a window.onerror logger that posts script-load failures to your observability stack. CORS failures show as "Failed to load resource: net::ERR_FAILED" with no response body.

Practical scenarios

Scenario A: React app on app.site.com and app.site.de

Both share site.com. Easiest path: add a Cloudflare Workers rule that rewrites /seatext.js to fetch from SeaText and returns Access-Control-Allow-Origin: https://app.site.com, https://app.site.de (or echo). No code changes in React. Visitor IDs stay separate unless you add a shared cookie.

Scenario B: Vue app on brand.io and brand.ai

Different registrable domains. You cannot share local storage. Configure your Netlify Edge Function to proxy /seatext.js on each site. Each origin gets a same-origin script, CORS disappears, SeaText initializes independently. Accept two visitor profiles or stitch them server-side via your user database.

Scenario C: Angular micro-frontends on shell.example.com, mfe1.example.com, mfe2.example.com

All subdomains of example.com. Place the snippet in the shell's index.html only. The shell loads SeaText once; micro-frontends inherit the same origin. No CORS work needed. One visitor ID for the whole ecosystem.

Limitations and what the docs don't cover

  • No SeaText dashboard toggle for "allowed origins" or "credentials mode."
  • No documented way to pass a pre-assigned visitor ID into the snippet before it writes to local storage.
  • The integration guide mentions "Cross-Origin Considerations" but gives no code examples for header configuration or proxying.
  • If SeaText later adds API calls from the snippet (e.g., variant fetch), those endpoints will need their own CORS headers — currently undocumented.
  • Enterprise SSO or GDPR consent flows that block third-party scripts until consent may delay SeaText load; the async attribute helps but doesn't solve consent gating.

Key facts from SeaText documentation

FactSource
Snippet includes async attribute for non-blocking loadS1
Script stores an ID in localStorage; app needs permission to access itS1
Explicit warning: multi-domain SPAs must ensure script compatibility and avoid cross-origin issuesS1
Integration step: place snippet in index.html body or framework bootstrap fileS1
No CORS configuration UI or API documented in current help centerS1

Terminology quick reference

CORS (Cross-Origin Resource Sharing)
Browser mechanism that lets a server declare which origins may load its resources via HTTP headers like Access-Control-Allow-Origin.
Preflight request
Automatic OPTIONS request the browser sends before a cross-origin request with custom headers or non-simple methods. The snippet's GET for a JS file usually avoids preflight.
Registrable domain
The highest-level domain you control in the Public Suffix List (e.g., example.com, not co.uk). Subdomains share this.
Same-origin policy
Browser rule: scripts can only read localStorage, cookies, and DOM of pages with identical scheme, host, and port.

FAQ

Does SeaText provide a CORS settings page in the dashboard?

No. The current documentation and UI show no per-project CORS configuration. You manage it at your CDN or edge layer.

Can I host the SeaText script on my own domain to avoid CORS?

Yes. Proxy /seatext.js through your own server or edge function. The browser then sees a same-origin script request. Keep the proxied file fresh by re-fetching from SeaText on each deploy or with a short TTL.

Will Access-Control-Allow-Origin: * work for all my SPA domains?

Yes, for the script load itself. The script runs in each page's origin, so localStorage remains separate per origin. The wildcard only affects whether the browser allows the script to download.

How do I keep a single visitor ID across example.com and example.fr?

You must implement cross-domain identity yourself: set a cookie with Domain=.example.com; SameSite=None; Secure on the registrable domain, read it on each SPA, and pass the value to SeaText if/when an API exists. Today the snippet writes its own ID to localStorage with no documented override.

What happens if the CORS header is missing on one domain?

The script fails to load. SeaText never initializes on that domain. You'll see a console error like "Cross-Origin Request Blocked" and no SeaText variants or translations will appear.

Does SeaText make additional API calls after the snippet loads?

The public docs don't list subsequent endpoints. If the snippet fetches variants or translations, those URLs will also need correct CORS headers. Monitor the Network tab after load to discover them.

Can I use a Content Security Policy (CSP) with SeaText?

Yes. Add script-src 'self' https://cdn.seatext.com (or your proxy origin) and connect-src for any API endpoints the snippet calls. The async attribute works fine under CSP.

Further reading and comparison sources

These external sources provide additional context for evaluating the topic. Their inclusion is not an endorsement.

How SeaText can help

SeaText AI's snippet is designed for drop-in simplicity: one async script tag, no build step, and automatic variant testing once it loads. For multi-domain SPAs, the integration guide flags cross-origin compatibility as your responsibility—meaning you control the headers and routing that let the script load everywhere your app runs. If you need a unified visitor identity across domains, plan for a shared cookie or backend stitching today; the snippet itself writes a separate localStorage ID per origin. When you're ready to test, add the snippet to each domain's entry HTML, verify the script returns 200 with an Access-Control-Allow-Origin header that matches the page origin, and watch the SeaText dashboard for variant activity.