---
title: "Connect hosted translations"
description: "Upload your app's text, publish a translated language, and load it in the browser."
canonical_url: "https://docs.linguana.dev/docs/getting-started/connect-your-app"
markdown_url: "https://docs.linguana.dev/docs/getting-started/connect-your-app.md"
x_farming_labs_generated_preamble: true
agent:
  task: "Connect an installed Linguana SDK to hosted translations."
  outcome: "The application uploads a manifest and loads a manually published production language."
  prerequisites:
    - "Local installation builds successfully and extracts application text."
    - "Access to a Linguana dashboard and API."
  files:
    - "vite.config.ts"
    - ".env.local"
    - "The application entry point."
  verification:
    - "The dashboard shows the uploaded build and the app displays a published language."
  rollback:
    - "Set upload to false and remove the runtime's remote catalog options."
  failureModes:
    - symptom: "Upload or catalog loading is rejected."
      resolution: "Check the API URL, project ID, environment, and the matching credential."
---

# Connect hosted translations
URL: /docs/getting-started/connect-your-app
LLM index: /llms.txt
Description: Upload your app's text, publish a translated language, and load it in the browser.
Related: /docs/getting-started/install, /docs/use-linguana/choose-languages

<!-- farming-labs:agent-contract:start -->
## Agent Contract

Task: Connect an installed Linguana SDK to hosted translations.
Outcome: The application uploads a manifest and loads a manually published production language.

### Prerequisites

- Local installation builds successfully and extracts application text.
- Access to a Linguana dashboard and API.

### Files

- `vite.config.ts`
- `.env.local`
- `The application entry point.`

### Verification

- The dashboard shows the uploaded build and the app displays a published language.

### Rollback

- Set upload to false and remove the runtime's remote catalog options.

### Failure Modes

- Upload or catalog loading is rejected. — Recovery: Check the API URL, project ID, environment, and the matching credential.
<!-- farming-labs:agent-contract:end -->

# Connect hosted translations

Start here after [installation](/docs/getting-started/install). You should already have a working build and a `.linguana/manifest.json` containing your app's text.

## 1. Create a project

Open **Projects** in the Linguana dashboard and choose **New project**. Create an organization first if you do not have one. The dashboard currently creates projects with English (`en`) as the source language.

Copy the project ID and replace the local `my-app` identifier in both your build plugin and runtime. This guide uses `production` in both places so the dashboard’s production publish action serves a catalog built for the same environment. Uploading a production build does not publish it. See [Create a project](/docs/use-linguana/create-project) for permissions and project settings.

In **Tokens**, create a production project token and copy it when shown. Obtain your API URL and browser publishable key from **Integrations**. The project token authenticates builds; the publishable key loads catalogs in the browser. The Integrations templates use `VITE_LINGUANA_API` and `VITE_LINGUANA_KEY`; this guide names those values `VITE_LINGUANA_API_URL` and `VITE_LINGUANA_PUBLISHABLE_KEY`. Match the names you store to the names your runtime reads.

## 2. Upload your text

```dotenv title=".env.local — replace the placeholders"
LINGUANA_API_URL=https://your-linguana-api.example.com
LINGUANA_PROJECT_TOKEN=your-project-token
LINGUANA_UPLOAD=false
VITE_LINGUANA_API_URL=https://your-linguana-api.example.com
VITE_LINGUANA_PUBLISHABLE_KEY=your-publishable-key
```

Vite does not automatically populate `process.env` from `.env.local` while evaluating its config. Load those values explicitly when configuring authenticated builds:

```ts title="vite.config.ts"
import { defineConfig, loadEnv } from "vite";
import react from "@vitejs/plugin-react";
import { linguana } from "@linguanahq/vite";
import { react as linguanaReact } from "@linguanahq/vite/react";

export default defineConfig(({ mode }) => {
  const env = { ...loadEnv(mode, process.cwd(), ""), ...process.env };
  return {
    plugins: [
      linguana({
        adapter: linguanaReact(),
        projectId: "your-project-id",
        environment: "production",
        sourceLocale: "en",
        apiUrl: env.LINGUANA_API_URL,
        token: env.LINGUANA_PROJECT_TOKEN,
        upload: env.LINGUANA_UPLOAD === "true",
      }),
      react(),
    ],
  };
});
```

Reading unprefixed values here keeps them in the build process. Do not forward the entire environment through Vite's `define` or `envPrefix` options.

Set `LINGUANA_UPLOAD=true` in `.env.local`, then run your build:

```bash title="terminal"
npm run build
```

Confirm the new build appears in the dashboard. For Vue, Svelte, or Solid, keep the adapter and framework plugin from your installation and add the same environment options.

## 3. Translate and publish

1. In **Languages**, enable a target language such as French.
2. In **Jobs**, choose **Translate latest build**, review the estimate, and start the run for the uploaded production build.
3. Inspect the wording in **Strings** and resolve pending decisions in **Review**.
4. In **Releases**, inspect the ready catalog, choose **Publish ready catalog**, and confirm production.

Uploading text does not translate or publish it. For a separate development workflow with optional build-triggered publishing, use a development token and matching build/runtime environment; see [CI/CD](/docs/automate/ci-cd). Production publishing remains an explicit release action.

## 4. Load the published language

For React, update your existing provider and add a language selector:

```tsx title="src/main.tsx"
import { createRoot } from "react-dom/client";
import { LanguageSelector, LocaleProvider } from "@linguanahq/react";
import "@linguanahq/react/styles.css";
import { App } from "./app";

createRoot(document.getElementById("root")!).render(
  <LocaleProvider
    projectId="your-project-id"
    environment="production"
    initialLocale="en"
    fallbackLocale="en"
    catalogEndpoint={import.meta.env.VITE_LINGUANA_API_URL}
    publishableKey={import.meta.env.VITE_LINGUANA_PUBLISHABLE_KEY}
    availableLocales={[
      { code: "en", displayName: "English", nativeName: "English" },
      { code: "fr", displayName: "French", nativeName: "Français" },
    ]}
  >
    <LanguageSelector />
    <App />
  </LocaleProvider>,
);
```

Use your existing `App` import and root element. For other frameworks, pass `catalogEndpoint` and `publishableKey` to the [matching runtime](/docs/getting-started/frameworks). Server-rendered apps should use the [TanStack Start guide](/docs/getting-started/tanstack-start) to keep the initial language consistent.

Restart the app after changing environment values and select French. Text included in your published catalog should now appear in French; missing translations fall back to the original text.

If the language does not load, check that the project and environment match the published catalog, then follow [Catalog runtime troubleshooting](/docs/troubleshooting/catalog-runtime).

## Next

Use [Dynamic text and links](/docs/build-with-code/dynamic-text-and-links) for variables and rich text, or [Show translated content](/docs/build-with-code/show-translated-content) for embedded catalogs and custom language switching.

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
Docs-scoped sitemap: [/docs/sitemap.md](/docs/sitemap.md).
Well-known sitemap: [/.well-known/sitemap.md](/.well-known/sitemap.md).
