Seatext library

How to Enable or Disable SeaText for Specific Vue.js Routes

Control SeaText on a per-route basis by adding a meta.seatextEnabled flag to your Vue Router configuration, reading that flag in a global navigation guard, and calling SeaText's show or hide methods (or conditionally mounting...

Quick answer

Add a meta.seatextEnabled flag to each Vue route. Read that flag in a global navigation guard. Call SeaText.show() or SeaText.hide() when the route changes. If you never want the SeaText script to load on a route, conditionally mount the widget instead.

Why route-level control matters

SeaText is loaded once through a JavaScript snippet. It translates every page, headline, button, and offer. On a single-page app, that snippet is active on every view. Some routes should not be translated.

Admin dashboards may contain internal labels. Legal pages must keep exact wording. Checkout buttons need to stay reliable. A mis-translated button can break a purchase flow. Route-level control stops that risk without removing SeaText from the whole app.

It also helps performance. The snippet already loads asynchronously, so it does not block the first paint. But routes that do not need translation can skip extra network and DOM work. You choose which pages use SeaText and which do not.

How SeaText loads in a Vue SPA

SeaText installs by inserting one snippet into your app. The integration guide says to put it in the index.html body or in the equivalent initialization section of your framework. In a Vue app, that is usually index.html or main.js.

The script tag uses the async attribute. This means it loads without slowing down the initial render. The script stores an ID in localStorage. Your app must allow local storage access.

If your SPA talks to multiple domains, check cross-origin behavior. The SeaText script must work across those domains without errors. These details matter when you add route-level toggling because the script is global from the start.

Set the route meta flag

Open your Vue Router configuration file. Add a meta object to each route. Use seatextEnabled to mark whether SeaText is allowed.

const routes = [
  { path: '/', component: Home, meta: { seatextEnabled: true } },
  { path: '/dashboard', component: Dashboard, meta: { seatextEnabled: false } },
  { path: '/checkout', component: Checkout, meta: { seatextEnabled: false } },
  { path: '/blog/:slug', component: BlogPost, meta: { seatextEnabled: true } }
]

Make the default behavior true. That means new routes stay translated unless you opt out. Only mark false on routes that need no translation.

For nested routes, use to.matched if you need to read a parent record. The example below checks all matched records:

const disabled = to.matched.some(record => record.meta.seatextEnabled === false)

Use a global navigation guard

Vue Router includes global guards. router.afterEach runs after every navigation. It is a stable place to toggle SeaText.

router.afterEach((to) => {
  const enabled = to.meta.seatextEnabled !== false
  if (enabled) {
    window.SeaText?.show?.()
  } else {
    window.SeaText?.hide?.()
  }
})

The optional chaining (?.) protects you before the snippet finishes loading. The snippet is async, so window.SeaText may not exist yet. The code then shows the widget on allowed routes and hides it on excluded routes.

Do not use beforeEach unless you call next(). A guard that forgets next() stops navigation. afterEach avoids that problem because it does not need to pass control forward.

Handle the first page load

The guard only runs during navigation. The first load is not a navigation. You must check the initial route separately.

In Vue 3, wait for router.isReady() before mounting. Then read the current route meta.

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

const app = createApp(App)
app.use(router)

router.isReady().then(() => {
  const enabled = router.currentRoute.value.meta.seatextEnabled !== false
  if (!enabled) window.SeaText?.hide?.()
  app.mount('#app')
})

This prevents the widget from flashing on excluded routes. If you use Vue 2, use router.onReady instead. The idea is the same: check before mount.

Choose between show/hide and conditional mounting

There are two practical patterns. The first calls show and hide on the existing widget. The second adds or removes the script tag itself.

CriterionShow/hide in guardConditional mounting
Implementation sizeSmallMedium
Script stays loadedYesNo
Stops network callsNoYes
Best forQuick route filteringStrict CSP or performance budgets

Use show/hide when you want a small change. The widget is already loaded, so toggling is fast. Use conditional mounting when the SeaText script must not exist on certain routes. That can satisfy a strict content security policy or reduce data usage.

Conditional mounting pattern

Conditional mounting means you control the script tag directly. You add the SeaText snippet when the route is allowed. You remove it when the route is not allowed.

Here is a small component that does this:

import { computed, watch, onBeforeUnmount } from 'vue'
import { useRoute } from 'vue-router'

const route = useRoute()
const enabled = computed(() => route.meta.seatextEnabled !== false)
let scriptTag = null

function loadSeaText() {
  if (scriptTag) return
  scriptTag = document.createElement('script')
  scriptTag.src = 'SEATEXT_SNIPPET_URL'
  scriptTag.async = true
  document.body.appendChild(scriptTag)
}

function removeSeaText() {
  if (scriptTag) {
    scriptTag.remove()
    scriptTag = null
  }
}

watch(enabled, (value) => {
  if (value) loadSeaText()
  else removeSeaText()
}, { immediate: true })

onBeforeUnmount(removeSeaText)

Replace SEATEXT_SNIPPET_URL with the URL from your SeaText dashboard. Check with the vendor if you need the exact URL format.

This pattern fully unloads the script on excluded routes. It also stops the script from making background requests on those routes. The downside is more code and manual lifecycle handling.

Common mistakes to avoid

  • Forgetting the first load check. The guard never fires on initial load. The widget may appear on an excluded route.
  • Using beforeEach without next(). This freezes navigation. Use afterEach for show/hide actions.
  • Not defaulting to true. If the flag is missing, the widget hides. New routes then need an explicit true flag.
  • Calling hide once. Each navigation to an excluded route must hide again. Route state does not persist by itself.
  • Assuming hide stops network calls. It hides the widget UI. The script may still run. Conditional mounting is the reliable way to stop network activity.
  • Ignoring nested route meta. A child route may inherit a parent flag. Test with real navigation.
  • Testing only one browser. The snippet depends on local storage and cross-origin rules. Check the Console and Network tabs in at least two browsers.

Testing checklist

  1. Start your app with npm run dev or your normal command.
  2. Open Developer Tools. Go to the Console and Network tabs.
  3. Navigate to a route with seatextEnabled: true. Confirm SeaText loads and the widget appears.
  4. Navigate to a route with seatextEnabled: false. Confirm the widget hides.
  5. Hard reload on an excluded route. Confirm no widget flash.
  6. Test a lazy-loaded route. The guard still runs, but check if the widget re-appears after the component mounts.
  7. Check local storage permission and cross-origin behavior if your SPA uses multiple domains.

Limitations of this approach

The show/hide method cannot remove the SeaText script. The script stays in the bundle and in memory. That is fine for most apps.

Conditional mounting is more complete, but it adds complexity. You must handle script loading races. If the user navigates quickly, two script tags can be created. The example above guards against that with a simple variable.

SeaText does not expose a built-in route filter in the snippet. You build the route logic yourself. The good news is that Vue Router provides clean hooks for this.

Language selection is global per session. You cannot make one route English-only and another Spanish-only using the snippet alone. You would need custom language logic.

If you need to unload the script completely, remove the script tag. There is no documented destroy method in the integration guide. Removing the tag is the safest known method. For lifecycle methods beyond show/hide, check with the vendor.

FAQ

Does SeaText have a built-in route filter?

No. The SeaText snippet translates visible text globally. Route control is your responsibility in Vue Router.

Can I use a composable instead of a global guard?

Yes. Create a composable that watches route.meta.seatextEnabled. Call show or hide when it changes. Place it in a layout component that wraps your pages.

Does hiding the widget stop translation API calls?

Not necessarily. Hide stops the widget UI. The script may still fetch data. Use conditional mounting if you need to stop network calls.

Can I set per-language routing rules?

The snippet uses one language selection per session. You cannot set different languages per route with the snippet alone. Build a custom language switcher for that.

Is afterEach better than beforeEach for this?

Yes for show/hide. afterEach runs after the route is confirmed. It does not require next(), so it cannot stall navigation.

What should I do if the widget reappears on a lazy-loaded route?

Use conditional mounting. Removing the script tag is more reliable than calling hide after a lazy component mounts.

Further reading and comparison sources

These sources provide additional context for SeaText integration and SPA behavior. Their inclusion is not an endorsement.

Check with the vendor for product details not covered here.

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.