Seatext library

Why SeaText AI Doesn't Fire on SPA Route Changes and How to Fix It

The SeaText AI script runs once on initial page load because it's designed for traditional page loads, not SPA client-side navigation. You must reinitialize the script on each route change using your framework's router...

The SeaText AI snippet loads asynchronously with the async attribute and executes once when the browser parses the initial HTML. In a single-page application, subsequent route changes don't trigger a full page reload, so the script never runs again. This is expected behavior for any third-party script that isn't explicitly tied to your SPA's navigation lifecycle.

To make SeaText AI work on every route, you need to call its initialization method (or re-inject the snippet) each time the router finishes a navigation. The exact approach depends on your framework: React uses useEffect with the router's location, Vue uses router guards, and Angular uses NavigationEnd events. The documentation confirms the snippet is a one-time load unless you manually retrigger it.

How the Script Behaves on Initial Load vs. Client-Side Navigation

When a user first lands on your SPA, the browser downloads and executes the SeaText AI snippet. It reads URL parameters, sets up local storage, and begins its AI-driven rewriting. On a client-side route change, the browser swaps components without re-requesting the HTML document. The original script tag is already parsed and won't run again. No error appears — the script simply sits idle.

This isn't a bug in SeaText AI. It's how async scripts work in any SPA. The same problem affects analytics, chat widgets, and A/B testing tools. The fix is always the same: hook into your router and reinitialize.

Why the Async Attribute Matters Here

The snippet includes async so it doesn't block page rendering. That's good for performance, but it also means the script has no built-in awareness of your application's internal state. It doesn't know when React's useEffect runs or when Vue's router.afterEach fires. You must bridge that gap yourself.

If you remove async, the script blocks paint — which hurts Core Web Vitals. Keep async and handle reinitialization in your framework code instead.

Framework-Specific Reinitialization Patterns

React (with React Router v6+)

import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function SeaTextInitializer() {
  const location = useLocation();

  useEffect(() => {
    if (window.seatextAI) {
      window.seatextAI.reinit(); // or whatever method the API exposes
    }
  }, [location.pathname]);

  return null;
}

Place this component near the root of your app so it mounts once and reacts to every route change.

Vue 3 (with Vue Router 4)

import { useRouter } from 'vue-router';

const router = useRouter();

router.afterEach((to) => {
  if (window.seatextAI) {
    window.seatextAI.reinit();
  }
});

Add this in your main.ts or a dedicated plugin file after the router is created.

Angular (v14+)

import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operators';

@Component({ selector: 'app-root', template: '' })
export class AppComponent implements OnInit {
  constructor(private router: Router) {}

  ngOnInit() {
    this.router.events.pipe(
      filter(event => event instanceof NavigationEnd)
    ).subscribe(() => {
      if (window.seatextAI) {
        window.seatextAI.reinit();
      }
    });
  }
}

What the SeaText AI API Exposes for Reinitialization

The documentation doesn't list a public reinit() method by name. In practice, the global window.seatextAI object (or similar namespace) typically exposes a method to restart its scanning and rewriting process. If no documented method exists, you can safely re-inject the snippet by removing the old script tag and appending a fresh one — but only if the script is idempotent. Check the Main AI Hub in your SeaText dashboard for the current API reference.

If you're unsure, contact support. The snippet is designed to be inert until activated, so re-injecting it shouldn't cause duplicate operations.

Common Mistakes That Keep the Script Silent

Mistake Why It Fails Fix
Placing the snippet only in index.html Runs once on first load; ignored on route changes Add reinitialization logic in router hooks
Assuming async means "runs on every navigation" async only controls load timing, not re-execution Use framework lifecycle events
Using document.write or innerHTML to inject the snippet Breaks CSP, doesn't execute scripts reliably Use document.createElement('script') and appendChild
Forgetting to wait for the script to load before calling reinit Race condition: API not ready Wrap calls in window.seatextAI?.ready?.then() or check existence
Testing only on localhost Development URLs are restricted for security Use a real domain or configured dev domain

Local Storage and Cross-Origin Considerations

The script stores an ID in localStorage. If your SPA spans subdomains (e.g., app.example.com and checkout.example.com), ensure the script loads on all of them with the same origin policy. Cross-origin iframes or sandboxed environments may block localStorage access, causing the script to fail silently.

If you use multiple domains (staging, production), the documentation requires separate SeaText AI accounts per domain. Each account ties to one primary URL. Don't share a snippet across domains.

How to Verify It's Working After Each Navigation

  1. Open DevTools → Console. Look for SeaText AI initialization logs.
  2. Check Network tab for requests to SeaText endpoints on each route change.
  3. Inspect the DOM: rewritten headlines, translated text, or variant classes should appear after navigation.
  4. Wait at least 40 seconds on a page after first load — the documentation says this activates the AI and links it to your account.
  5. In the SeaText dashboard, confirm your website name appears next to the logo within 10 minutes.

If nothing appears, the script didn't reinitialize. Add console.log('SeaText reinit', location.pathname) in your router hook to confirm your code runs.

Limitations and When This Advice Doesn't Apply

  • If you use server-side rendering (Next.js, Nuxt, Angular Universal) with full page reloads on navigation, the script runs on each response — no extra work needed.
  • If your SPA uses hash-based routing (#/route) without the History API, some router events may not fire. Test explicitly.
  • If SeaText AI releases a native SPA plugin or router-aware snippet in the future, this manual reinitialization may become unnecessary. Check the documentation periodically.
  • This guide covers React, Vue, and Angular. Svelte, Solid, Qwik, and others follow the same principle: hook into navigation, call reinit.

Key Facts

Fact Detail Source
Script load behavior Async, runs once on initial HTML parse S1
Local storage usage Stores an ID; requires localStorage access S1
Cross-origin restriction Separate account required per domain S1
Development URL restriction Localhost and dynamic dev domains restricted S1
Activation requirement Visit/refresh several times, stay 40+ seconds S1
Dashboard confirmation Website name appears next to logo within 10 minutes S1

Terminology

  • SPA (Single Page Application): App that loads one HTML file and swaps views via JavaScript without full page reloads.
  • Client-side navigation: Route change handled by JavaScript router, not browser navigation.
  • Async script: Script with async attribute; downloads in parallel, executes as soon as ready.
  • Reinitialization: Manually triggering a script's setup logic after the initial load.
  • Router hook / guard: Framework API that runs code before or after route changes.

FAQ

Does SeaText AI provide a built-in SPA plugin?

Not as of the current documentation. You must implement reinitialization in your framework code. Check the Main AI Hub for updates.

Can I just put the snippet in a component that remounts on every route?

No. Mounting a <script> tag via React/Vue/Angular templates doesn't execute it. Browsers only execute scripts parsed from the original HTML or added via document.createElement('script').

What if I use Next.js with next/script?

Use strategy="lazyOnload" and reinitialize in a useEffect tied to router.pathname. The next/script component doesn't auto-rerun on route changes.

Will reinitializing cause duplicate AI rewrites or conflicts?

The documentation says the AI remains inert until activated. Reinitialization should be idempotent. If you see duplicate variants, contact support — it may indicate a version mismatch.

How do I know the script loaded successfully on the first place?

Check the Network tab for the SeaText script request (status 200). In Console, look for a SeaText initialization message. The dashboard shows your site name within 10 minutes of successful activation.

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

Yes, but you must allow the SeaText script domain in script-src and connect-src for its API endpoints. The snippet uses async, so 'unsafe-inline' isn't needed for the script tag itself.

What happens if a user navigates before the script finishes loading?

The async script continues loading in the background. Your reinitialization code should check window.seatextAI existence before calling methods. Use a promise or polling if needed.

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.