Seatext library

How to Configure SeaText for a Vue.js Single-Page Application

Add the SeaText snippet to your Vue app's entry point, then use Vue Router navigation guards to trigger re-translation on every route change. This ensures dynamic content and client-side routing work correctly with SeaText's...

To configure SeaText for a Vue.js SPA, paste the provided JavaScript snippet into your index.html (or the main bootstrap file) so it loads once when the app starts. Then hook into Vue Router's afterEach guard to call window.seatext?.retranslate() (or the equivalent API method) after every navigation. This two-step setup — one-time snippet load plus router-guard re-translation — handles client-side routing, lazy-loaded components, and any DOM mutations that happen after the initial render.

Prerequisites before you start

  • A working Vue 2 or Vue 3 project with Vue Router installed (v3 or v4).
  • Access to the SeaText dashboard to copy your unique integration snippet (the SEATEXTCODEINTEGRATION block).
  • Permission to edit index.html or the main entry file (main.js, main.ts, app.js).
  • Local storage enabled in the browser — SeaText stores an anonymous visitor ID there.

Step 1 — Add the snippet at the app entry point

  1. Open public/index.html (Vue CLI / Vite default) or the equivalent template file.
  2. Paste the SeaText snippet inside the <body> tag, preferably just before the closing </body> so it doesn't block rendering. The snippet loads asynchronously thanks to the async attribute, so page-load performance stays intact.
  3. Save and rebuild (npm run build or npm run serve).

Why the entry point? SeaText must initialise once per session. In an SPA the HTML shell loads only once; subsequent "pages" are virtual. Placing the snippet in index.html guarantees it runs before any route components mount.

Step 2 — Listen to Vue Router navigation guards

After the initial load, SeaText has no idea when the virtual URL changes. You must tell it. The pattern is identical for Vue Router 3 and 4; only the import path differs.

Vue Router 4 (Vue 3 default)

// src/router/index.js or .ts
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({ history: createWebHistory(), routes: [...] })
router.afterEach((to, from) => {
  // Give Vue a tick to finish DOM updates
  nextTick(() => {
    if (window.seatext && typeof window.seatext.retranslate === 'function') {
      window.seatext.retranslate()
    }
  })
})
export default router

Vue Router 3 (Vue 2)

// src/router.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const router = new Router({ mode: 'history', routes: [...] })
router.afterEach((to, from, next) => {
  Vue.nextTick(() => {
    if (window.seatext && typeof window.seatext.retranslate === 'function') {
      window.seatext.retranslate()
    }
    next()
  })
})
export default router

nextTick (or Vue.nextTick) ensures the new route's components have rendered before SeaText scans the DOM for translatable nodes.

Step 3 — Handle dynamic content that arrives after route load

Some Vue apps fetch data or render heavy components after the route hook fires (e.g., Suspense, async components, infinite scroll). Two practical options:

  • Call retranslate manually inside the component's onMounted or after the async data resolves: window.seatext?.retranslate().
  • Use a global event bus (mitt, Vue 3's emits, or a simple window.dispatchEvent) so any component can notify SeaText when new markup lands.

Pick the approach that matches your codebase — both keep SeaText in sync without polling.

Step 4 — Configure AI scope and selectors (optional but recommended)

In the SeaText dashboard under How to configure / AI scope you can limit which DOM nodes the AI touches. For a Vue SPA, add CSS selectors that match your main content containers (e.g., #app > .page-content, .vue-component-root). This prevents the AI from rewriting navigation bars, footers, or third-party widgets that should stay static.

Step 5 — Verify the integration end-to-end

  1. Run the dev server (npm run dev or npm run serve).
  2. Open Chrome DevTools → Console and Network tabs. Confirm the SeaText script loads with HTTP 200 and no CORS errors.
  3. Navigate between several routes. Watch the Console for SeaText: retranslate triggered (or similar log) after each navigation.
  4. Switch the SeaText dashboard language selector to a target language. The visible text on each route should update without a full page reload.
  5. Check localStorage in Application tab — a seatext_visitor_id key should exist.

If any step fails, see the Common pitfalls section below.

Common pitfalls and how to fix them

SymptomLikely causeFix
Translations work on first load but not after route changeMissing or mis-typed router.afterEach hookAdd the guard exactly as shown in Step 2; ensure nextTick wraps the call.
Console shows seatext is not definedSnippet not loaded or blocked by CSPVerify snippet in index.html; check Content-Security-Policy allows script-src from SeaText domain.
Only part of the page translatesAI scope selectors too narrow or Vue component root not matchedAdjust selectors in dashboard to include the dynamic wrapper (e.g., .router-view-wrapper).
Cross-origin errors in multi-domain SPASeaText script served from different origin than API callsHost the snippet on your CDN or configure Access-Control-Allow-Origin headers per SeaText docs.
Local storage quota exceededOther scripts filling storageClear storage in dev tools; SeaText only stores a tiny ID string.

Key facts at a glance

ItemDetail
Snippet loadingAsync script tag; non-blocking
Initialisation pointindex.html or main bootstrap file
Router integrationrouter.afterEach + nextTick + window.seatext.retranslate()
Dynamic content handlingManual retranslate() call or global event bus
AI scope controlDashboard CSS selectors
Storage requirementLocal storage for anonymous visitor ID
Cross-origin noteEnsure snippet domain allowed in CSP / CORS
Verification stepsDevTools Console/Network, language switch test, localStorage check

Limitations and when this guide does not apply

  • Nuxt.js, Quasar, or other meta-frameworks — they have their own plugin/entry systems; adapt the snippet placement accordingly.
  • Server-side rendered (SSR) pages — SeaText runs in the browser only; SSR HTML will not be translated until hydration.
  • Apps that disable local storage or run in strict privacy modes (e.g., Safari ITP) — SeaText may fall back to session storage or cookie, but behaviour can differ.
  • Non-Vue SPAs (React, Angular, Svelte) — the router guard concept is the same, but the API differs; see SeaText docs for framework-specific examples.

Frequently asked questions

Do I need to re-initialise SeaText on every route?

No. The snippet initialises once. You only need to call retranslate() (or the current API equivalent) after the DOM updates.

Can I use SeaText with Vue 2 Options API?

Yes. The router guard lives in the router file, independent of component API style. Call this.$nextTick(() => window.seatext?.retranslate()) inside a component if you prefer component-level control.

What if my app uses hash mode (#/route) instead of history mode?

The same afterEach guard works; hash changes still fire navigation guards.

Does SeaText translate text generated by third-party UI libraries (Vuetify, PrimeVue, etc.)?

Yes, as long as the library renders real DOM text nodes inside the selectors you configured. Shadow DOM or canvas-rendered text is not reachable.

How do I exclude a specific component from translation?

Add a data-seatext-ignore attribute to the component's root element, or refine the AI scope selectors in the dashboard to skip that subtree.

Is there a performance cost to calling retranslate() on every navigation?

SeaText debounces and batches DOM scans. In typical Vue apps the overhead is negligible (< 10 ms). If you have thousands of nodes, narrow the AI scope selectors.

Where do I find my unique integration snippet?

Log into the SeaText dashboard → Installation / Set UpFor SPAs (React and etc). Copy the block labelled SEATEXTCODEINTEGRATION.

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.