glosa
Get started
Add the Vite plugin, set up the runtime for Vue, React or Svelte, and switch the locale.
pnpm add glosaglosa is in private preview and isn't on npm yet. Until it is, build it from the repository with pnpm install and pnpm build.
The Vite plugin
Section titled "The Vite plugin"Add glosa() next to your framework's plugin. It runs first either way, so it rewrites each component before the framework compiles it.
import vue from "@vitejs/plugin-vue";
import { glosa } from "glosa/vite";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [glosa(), vue()],
});import react from "@vitejs/plugin-react";
import { glosa } from "glosa/vite";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [glosa(), react()],
});import { svelte } from "@sveltejs/vite-plugin-svelte";
import { glosa } from "glosa/vite";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [glosa(), svelte()],
});It reads .vue, .jsx, .tsx and .svelte files. When the dev server or a build starts, it writes locales/en.json with every message, and in dev it updates the file on every save. Two options change where: sourceLocale, the language you write in ("en"), and dir, the catalog folder from the Vite root ("locales").
The runtime
Section titled "The runtime"virtual:glosa holds the source locale and a loader for each catalog in locales/. Pass it to createGlosa, then give the store to your app.
// main.ts
import config from "virtual:glosa";
import { createGlosa, glosaVue } from "glosa/vue";
import { createApp } from "vue";
import App from "./App.vue";
const glosa = createGlosa(config);
createApp(App).use(glosaVue(glosa)).mount("#app");// main.tsx
import config from "virtual:glosa";
import { createGlosa, GlosaProvider } from "glosa/react";
import { createRoot } from "react-dom/client";
import App from "./App.tsx";
export const glosa = createGlosa(config);
createRoot(document.getElementById("app")!).render(
<GlosaProvider glosa={glosa}>
<App />
</GlosaProvider>,
);<!-- App.svelte, the root component -->
<script lang="ts">
import config from "virtual:glosa";
import { createGlosa, setGlosa } from "glosa/svelte";
const glosa = setGlosa(createGlosa(config));
</script>Now start the dev server and open locales/en.json. Copy it to locales/es.json and translate the values. A message with no translation shows its source text.
Switch the locale
Section titled "Switch the locale"setLocale loads the locale's catalog the first time, then switches. Every message on the page re-renders, without a reload. glosa.locales lists every locale with a catalog, the source locale first.
<script setup lang="ts">
import type { Glosa } from "glosa/vue";
import { inject } from "vue";
const glosa = inject<Glosa>("glosa")!;
</script>
<template>
<button v-for="locale in glosa.locales" :key="locale" @click="glosa.setLocale(locale)">
{{ locale }}
</button>
</template>import { glosa } from "./main.tsx";
export function Locales() {
return glosa.locales.map((locale) => (
<button key={locale} onClick={() => glosa.setLocale(locale)}>
{locale}
</button>
));
}<!-- In App.svelte, under the setGlosa call -->
{#each glosa.locales as locale}
<button onclick={() => glosa.setLocale(locale)}>{locale}</button>
{/each}To start in another locale, pass it as locale. Its catalog loads right away, and await glosa.ready waits for it, which a server render should do.
TypeScript
Section titled "TypeScript"Add glosa's types for virtual:glosa to tsconfig.json:
{ "compilerOptions": { "types": ["glosa/client"] } }