# vue: Developing with SPA translations
URL: https://generaltranslation.com/en-GB/docs/vue/guides/developing-spa-translations.mdx
---
title: Developing with SPA translations
description: How to preload a Vue SPA and translate static strings at module scope with t().
related:
links:
- /docs/vue/guides/translating-strings
- /docs/vue/guides/managing-locales
- /docs/vue/guides/storing-translations
- /docs/vue/guides/configuring
---
Browser-only single-page applications can preload the active catalogue before application modules run. This enables synchronous, module-level [`t()`](/docs/vue/reference/functions/t) calls for constants, navigation definitions, and other strings outside Vue components.
[`initializeGTSPA()`](/docs/vue/reference/functions/initialize-gt-spa) complements [`useGT()`](/docs/vue/reference/composables/use-gt); it does not replace it. Use the composable for normal component content and for Vue or server-rendered applications that require reactive locale switching.
## Choose the SPA runtime [#choose]
Use [`initializeGTSPA()`](/docs/vue/reference/functions/initialize-gt-spa) only when all of the following statements are true:
* The application runs entirely in the browser.
* Modules must translate strings while they are evaluated.
* Reloading the page when the locale changes is acceptable.
Use [`createGT()`](/docs/vue/reference/functions/create-gt) when the app renders on the server or should switch locales reactively without reloading the page.
## Bootstrap before importing the app [#bootstrap]
The initialisation boundary must run before any module that calls [`t()`](/docs/vue/reference/functions/t). A small async bootstrap works with the standard Vite 6 build target and does not require top-level `await` or `build.target: 'esnext'`.
### 1. Export a mount function
Change the standard Vite entry module to export a function that accepts the initialised [`GTPlugin`](/docs/vue/reference/types/gt-plugin):
```ts title="src/main.ts"
import { createApp } from 'vue';
import type { GTPlugin } from 'gt-vue';
import App from './App.vue';
export function mount(gt: GTPlugin) {
createApp(App).use(gt).mount('#app');
}
```
### 2. Initialise and dynamically import
Create a bootstrap module that awaits [`initializeGTSPA()`](/docs/vue/reference/functions/initialize-gt-spa), then imports the application and installs the exact plugin returned by initialisation:
```ts title="src/index.ts"
import { initializeGTSPA } from 'gt-vue';
import gtConfig from '../gt.config.json';
import loadTranslations from './loadTranslations';
async function bootstrap() {
const gt = await initializeGTSPA({
...gtConfig,
loadTranslations,
});
const { mount } = await import('./main');
mount(gt);
}
bootstrap().catch((error) => {
console.error('Failed to initialize translations', error);
});
```
The first call owns the page-wide SPA runtime. Concurrent calls share its initialisation, and subsequent calls return the same plugin. Do not call [`createGT()`](/docs/vue/reference/functions/create-gt) for the mounted app, as component and module-level lookups will use different state.
### 3. Point Vite at the bootstrap
Update the module script in `index.html` to load `src/index.ts` instead of `src/main.ts`:
```html title="index.html"
```
## Translate module-level strings [#translate]
Modules loaded by a dynamic application import can call [`t()`](/docs/vue/reference/functions/t) synchronously:
```ts title="src/navigation.ts"
import { t } from 'gt-vue';
export const message = t('Hello World');
export const navigation = [
{ label: t('Documentation', { $context: 'primary navigation' }), href: '/docs' },
{ label: t('Account settings'), href: '/settings' },
];
```
Calls must use a static source string and may pass a static `$context`. The extractor registers those strings, and the preloaded catalogue makes the lookup synchronous when the module runs.
[`t()`](/docs/vue/reference/functions/t) does not support tagged templates, ICU syntax, interpolation, `$format`, or `$maxChars`. Use [``](/docs/vue/reference/components/t) with [``](/docs/vue/reference/components/var) for content containing runtime values.
## Change locales in an initialised SPA [#locales]
Pass `defaultLocale` and `locales` from `gt.config.json` to [`initializeGTSPA()`](/docs/vue/reference/functions/initialize-gt-spa). An unsupported saved locale falls back to the default locale during the next initialisation.
When [`useSetLocale()`](/docs/vue/reference/composables/use-set-locale) changes the locale, the SPA runtime writes the locale cookie and reloads the document. It deliberately keeps the current page in its initialised locale until that reload. The bootstrap then preloads the new catalogue before module-level calls execute again.
This reload contract is what makes module-level constants safe. If locale changes must occur without navigation, use [`createGT()`](/docs/vue/reference/functions/create-gt) and call [`useGT()`](/docs/vue/reference/composables/use-gt) from a template or computed value instead.
## Next steps
- /docs/vue/guides/translating-strings
- /docs/vue/guides/managing-locales
- /docs/vue/guides/storing-translations
- /docs/vue/guides/configuring