# Get started

> Add the Vite plugin, set up the runtime for Vue, React or Svelte, and switch the locale.

```sh
pnpm add glosa
```

glosa 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

Add `glosa()` next to your framework's plugin. It runs first either way, so it rewrites each component before the framework compiles it.

::code-group
```ts [Vue]
import vue from "@vitejs/plugin-vue";
import { glosa } from "glosa/vite";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [glosa(), vue()],
});
```

```ts [React]
import react from "@vitejs/plugin-react";
import { glosa } from "glosa/vite";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [glosa(), react()],
});
```

```ts [Svelte]
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

`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.

::code-group
```ts [Vue]
// 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");
```

```tsx [React]
// 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>,
);
```

```svelte [Svelte]
<!-- 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

`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.

::code-group
```vue [Vue]
<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>
```

```tsx [React]
import { glosa } from "./main.tsx";

export function Locales() {
  return glosa.locales.map((locale) => (
    <button key={locale} onClick={() => glosa.setLocale(locale)}>
      {locale}
    </button>
  ));
}
```

```svelte [Svelte]
<!-- 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

Add glosa's types for `virtual:glosa` to `tsconfig.json`:

```json
{ "compilerOptions": { "types": ["glosa/client"] } }
```

## Sitemap

See the full list of pages in [llms.txt](https://glosa.onmax.me/llms.txt).
