Where to Insert the SeaText AI Script in a Single Page Application
Place the SeaText AI snippet in your main HTML file (typically index.html) before the closing </body> tag, or load it dynamically after your SPA framework finishes bootstrapping. Both approaches work for React, Vue, Angular,...
Single page applications load once and then swap views without full page reloads. Because SeaText AI needs to run on every virtual page view, the script must be present before the first render and stay available during client‑side navigation. The documentation recommends two equivalent patterns: embed the snippet directly in the entry HTML file, or inject it programmatically after the app initializes.
Why Script Placement Matters in SPAs
In a traditional multi‑page site the browser fetches a fresh HTML document for each URL, so a script placed in <head> or before </body> runs on every load. An SPA serves one HTML shell and then uses JavaScript routing to change content. If the SeaText snippet only exists in the initial shell, it will execute once and then stop listening to route changes unless the integration handles SPA navigation events. The official guide addresses this by ensuring the snippet loads early and remains active across route transitions.
Option 1: Embed in the Main HTML File
The simplest method is to paste the provided SeaText snippet inside the <body> of your index.html (or equivalent entry point) before the closing </body> tag. The snippet already includes the async attribute, so it will not block page rendering. This approach works for every framework because the HTML shell is the one file that always loads first.
- Open
public/index.html(Create React App, Vite),index.html(Vue CLI, Vite), orsrc/index.html(Angular CLI). - Paste the snippet just before
</body>. - Build and serve the app (
npm start,npm run serve,ng serve). - Open DevTools → Console and Network tabs to confirm the script loads without errors.
This static placement guarantees the script is present for the first paint and for all subsequent client‑side navigations.
Option 2: Dynamic Injection After Bootstrap
Some teams prefer to keep the HTML shell clean and inject third‑party scripts only after the application bootstrap completes. You can achieve this by creating the script element in your root component’s initialization logic (e.g., useEffect in React, mounted() in Vue, or ngOnInit in an Angular service).
// React example
useEffect(() => {
const script = document.createElement('script');
script.src = 'https://cdn.seatext.ai/your-account-id.js';
script.async = true;
document.body.appendChild(script);
}, []);
Dynamic injection gives you control over timing and lets you gate the script behind feature flags or consent banners. The trade‑off is a few extra milliseconds before SeaText becomes active on the very first view.
Framework‑Specific Guidance
React
Both the static index.html method and dynamic injection via useEffect in App.tsx are supported. If you use Next.js, place the snippet in pages/_document.js inside <Body> or use next/script with strategy="lazyOnload".
Vue.js
Add the snippet to public/index.html before </body>, or inject it in main.js after createApp(...).mount('#app'). Vue Router navigation guards are not required because the SeaText script automatically listens for popstate and pushState events.
Angular
Insert the snippet in src/index.html before </body>. Alternatively, use Renderer2 in AppComponent.ngOnInit() to append the script dynamically. Angular’s zone management does not interfere with the async SeaText loader.
Testing the Integration
After adding the snippet by either method, follow these verification steps:
- Build and serve the application using your framework’s standard command.
- Open the browser’s Developer Tools (F12).
- Check the Console tab for any SeaText‑related errors.
- Check the Network tab and filter for “seatext” to confirm the script downloads with a 200 status.
- Navigate between several routes in your SPA and verify that SeaText features (translations, variants, personalization) update without a full page reload.
If the script loads but features do not appear, ensure your application has permission to use localStorage (the script stores an ID there) and that no Content Security Policy blocks the SeaText domain.
Common Mistakes and How to Avoid Them
| Mistake | Why It Breaks | Fix |
|---|---|---|
| Placing the snippet inside a component template | Component templates render after the initial HTML; the script may load too late or be stripped by the framework’s sanitizer. | Use index.html or dynamic injection in the root component’s lifecycle hook. |
Adding defer instead of relying on the built‑in async |
defer waits for HTML parsing to finish, which in an SPA may be after the first virtual view renders. |
Keep the original snippet unchanged; it already uses async. |
Blocking localStorage via privacy settings or CSP |
The script writes an identifier to localStorage; blocking it prevents SeaText from initializing. |
Allow localStorage for your domain and whitelist the SeaText CDN in CSP script-src. |
Using a development domain like localhost without a valid account |
SeaText restricts development URLs for security; the script will not activate. | Use a real domain (or a tunnelled HTTPS URL) and create a SeaText account for that domain. |
Advanced Considerations
Asynchronous Loading
The snippet’s async attribute ensures the script downloads in parallel with page rendering. This keeps Lighthouse and Core Web Vitals scores high. Do not remove async or wrap the snippet in a synchronous loader.
Local Storage Usage
SeaText stores a session identifier in localStorage. If your SPA runs in an iframe or a privacy‑restricted context (e.g., Safari’s Intelligent Tracking Prevention), verify that localStorage is accessible. A fallback is to initialize SeaText after confirming window.localStorage exists.
Cross‑Origin and Multi‑Domain SPAs
If your application serves content from multiple subdomains or unrelated domains, each domain needs its own SeaText account and snippet. The script does not share state across origins. Configure the snippet on every domain that should run SeaText features.
Key Facts
| Aspect | Detail |
|---|---|
| Recommended static location | index.html before </body> |
| Dynamic injection point | Root component mount / bootstrap callback |
| Script attribute | async (included in provided snippet) |
| Storage requirement | localStorage access needed |
| Multi‑domain rule | One SeaText account per primary domain |
| Verification steps |
Limitations
- The guidance applies to client‑side rendered SPAs (React, Vue, Angular, Svelte, etc.). Server‑side rendered frameworks (Next.js, Nuxt, Astro) may need the snippet in a custom document or layout file instead of a static
index.html. - Development environments using
localhost,127.0.0.1, or dynamic tunnel URLs are restricted; a real domain is required for activation. - If your CSP blocks inline scripts or the SeaText CDN, you must adjust
script-srcandconnect-srcdirectives accordingly. - The article does not cover integration with micro‑frontend architectures where multiple independent apps share a page; each micro‑app should include its own snippet.
Frequently Asked Questions
Can I put the snippet in <head> instead of <body>?
Yes, but the documentation example shows <body> placement. Both work because the script is async; <body> is slightly safer for CSP policies that restrict head scripts.
Do I need to re‑initialize SeaText on every route change?
No. The script automatically listens for popstate and pushState events, so it detects SPA navigation without extra code.
What if my build tool (Vite, Webpack) strips the snippet from index.html?
Most tools copy public/index.html or index.html verbatim. If yours processes the file, add the snippet via an HTML plugin (e.g., html-webpack-plugin template or Vite’s transformIndexHtml hook).
Does SeaText work with React Server Components or Next.js App Router?
Yes. Place the snippet in app/layout.tsx inside the <body> tag, or use next/script with strategy="afterInteractive".
How do I know the script is actually running?
Open DevTools → Console; you should see a SeaText initialization log. In the Network tab, filter for “seatext” and confirm a 200 response. Then navigate a few routes and watch for variant/translation updates.
Can I load SeaText only after user consent (GDPR/CCPA)?
Yes. Use dynamic injection inside your consent callback so the script loads only after the user accepts marketing/analytics cookies.
What happens if I have multiple SPAs on subdomains?
Create a separate SeaText account for each subdomain. Each account gets its own snippet and configuration.
Further reading and comparison sources
These external sources provide additional context for evaluating the topic. Their inclusion is not an endorsement.
Learn more
Visit the website for more information.