---
description: "21 språk som stöds och hur du skapar eller förbättrar översättningar för SnapOtter med det TypeScript-genomdrivna i18n-systemet."
i18n_source_hash: 55837d9fdaef
i18n_provenance: human
i18n_output_hash: 640b973cf4bc
---
# Översättningsguide {#translation-guide}
SnapOtter levereras med 21 språk direkt ur lådan. i18n-systemet använder en lättviktig egen körmiljö med TypeScript-genomdriven fullständighet för språkversioner och dynamisk koddelning.
## Språk som stöds {#supported-languages}
| Code | Language | Native Name | Direction |
|------|----------|-------------|-----------|
| `en` | Engelska | English | LTR |
| `zh-CN` | Kinesiska (förenklad) | 简体中文 | LTR |
| `zh-TW` | Kinesiska (traditionell) | 繁體中文 | LTR |
| `ja` | Japanska | 日本語 | LTR |
| `ko` | Koreanska | 한국어 | LTR |
| `es` | Spanska | Español | LTR |
| `fr` | Franska | Français | LTR |
| `it` | Italienska | Italiano | LTR |
| `pt-BR` | Portugisiska (Brasilien) | Português (Brasil) | LTR |
| `de` | Tyska | Deutsch | LTR |
| `nl` | Nederländska | Nederlands | LTR |
| `sv` | Svenska | Svenska | LTR |
| `ru` | Ryska | Русский | LTR |
| `pl` | Polska | Polski | LTR |
| `uk` | Ukrainska | Українська | LTR |
| `ar` | Arabiska | العربية | RTL |
| `tr` | Turkiska | Türkçe | LTR |
| `hi` | Hindi | हिन्दी | LTR |
| `vi` | Vietnamesiska | Tiếng Việt | LTR |
| `id` | Indonesiska | Bahasa Indonesia | LTR |
| `th` | Thailändska | ไทย | LTR |
## Så fungerar språkigenkänning {#how-language-detection-works}
SnapOtter använder en upplösningsordning i tre nivåer:
1. **Användarinställning** - lagras i `localStorage("snapotter-locale")` och synkas till användarinställningarna när du är inloggad
2. **Automatisk webbläsardetektering** - går igenom `navigator.languages`-arrayen med BCP 47-prefixmatchning
3. **Standard för instansen** - administratörens miljövariabel `DEFAULT_LOCALE` (hämtad från `GET /api/v1/config/locale`)
4. **Reservspråk engelska** - alltid tillgängligt
Användare kan byta språk från:
- **Jordglobsväljaren i sidfoten** (desktop, alltid synlig)
- Språkväljaren på **inloggningssidan** (före inloggning)
- Avsnittet **Inställningar > Allmänt** (inställning per användare)
- Språkrullgardinen i **mobilens sidopanel**
- Avsnittet **Inställningar > System** anger standardvärdet för hela instansen (endast administratör)
## Så fungerar översättningar {#how-translations-work}
Alla UI-strängar finns i `packages/shared/src/i18n/`. Referensfilen är `en.ts`, som exporterar ett typat objekt med varje sträng appen använder (~1500 nycklar). Övriga språk är separata filer (t.ex. `de.ts`, `fr.ts`) som exporterar samma form.
Typen `TranslationKeys` använder `DeepStringRecord` för att acceptera vilket strängvärde som helst samtidigt som nyckelstrukturen genomdrivs. TypeScript upptäcker saknade nycklar i vilken översättningsfil som helst vid kompileringstillfället.
Endast den aktiva språkversionen laddas vid körning via dynamisk `import()`, vilket håller huvudbunten liten.
## Använda översättningar i komponenter {#using-translations-in-components}
```tsx
import { useTranslation } from "@/contexts/i18n-context";
import { format, plural } from "@/lib/format";
function MyComponent() {
const { t, locale, setLocale } = useTranslation();
return (
{t.common.settings}
{format(t.settings.people.deleteConfirm, { username: "admin" })}
{plural(count, t.automate.fileCount, t.automate.fileCountPlural)}
);
}
```
## Bidra med en översättning {#contributing-a-translation}
Vi tar gärna emot översättnings-PR:er direkt. Du kan förbättra en befintlig språkversion eller lägga till en ny.
För att rapportera en felöversättning utan att skicka in kod kan du öppna ett [GitHub Issue](https://github.com/snapotter-hq/SnapOtter/issues) med språket, den felaktiga strängen och det föreslagna rättelsen.
::: tip
Översättnings-PR:er kräver inget godkännande i förväg. Forka repot, gör dina ändringar och öppna en PR. Se [Contributing Guide](/sv/guide/contributing) för hela PR-processen och CLA-kravet.
:::
## Så skapar eller uppdaterar du en översättning {#how-to-create-or-update-a-translation}
### 1. Forka och klona {#_1-fork-and-clone}
```bash
git clone https://github.com//snapotter.git
cd snapotter
pnpm install
```
### 2. Kopiera referensfilen (endast nytt språk) {#_2-copy-the-reference-file-new-language-only}
Hoppa över det här steget om du förbättrar en befintlig översättning.
```bash
cp packages/shared/src/i18n/en.ts packages/shared/src/i18n/XX.ts
```
### 3. Översätt strängarna {#_3-translate-the-strings}
Öppna din nya fil och översätt varje strängvärde. Behåll objektstrukturen och nycklarna exakt likadana.
```ts
import type { TranslationKeys } from "./en.js";
export const xx: TranslationKeys = {
common: {
upload: "Your translation here",
// ... translate all entries
},
// ... translate all sections
} as const;
```
Regler:
- Översätt inte objektnycklar, bara strängvärden
- Behåll `as const` i slutet
- Importera `TranslationKeys` från `./en.js` och typa din export
- Behåll `{variable}`-platshållare exakt som de är
- Arrayer (`rotatingPhrases`, `progressMessages`) måste ha samma antal poster
- Översätt inte: SnapOtter, JPEG, PNG, WebP, EXIF, API och andra tekniska termer
### 4. Registrera språkversionen (endast nytt språk) {#_4-register-the-locale-new-language-only}
Lägg till din språkversion i `SUPPORTED_LOCALES` i `packages/shared/src/i18n/index.ts`:
```ts
{ code: "xx", name: "Language Name", nativeName: "Native Name", dir: "ltr" },
```
### 5. Verifiera {#_5-verify}
```bash
pnpm typecheck # catches missing or mistyped keys
pnpm lint # formatting check
pnpm dev # manually verify strings appear correctly
```
### 6. Skicka in {#_6-submit}
Öppna en PR mot `main` med en titel som `feat(i18n): add Swedish translation` eller `fix(i18n): correct German typos`. CLA-boten ber dig signera vid ditt första bidrag.
## Lägga till nya översättningsnycklar {#adding-new-translation-keys}
När du lägger till en ny funktion som behöver nya UI-strängar:
1. Lägg till de nya nycklarna i `en.ts` först (referensfilen)
2. Kör `pnpm typecheck` - varje språkfil misslyckas om den nya nyckeln saknas
3. Lägg till den nya nyckeln i alla språkfiler (använd engelska som tillfälligt reservspråk)
## Konfiguration {#configuration}
Ange instansens standardspråk via en miljövariabel:
```yaml
DEFAULT_LOCALE: "de" # German as the default for all new users
```
## Filreferens {#file-reference}
| File | Purpose |
|------|---------|
| `packages/shared/src/i18n/en.ts` | Engelska strängar (referensspråk, ~1500 nycklar) |
| `packages/shared/src/i18n/index.ts` | `SUPPORTED_LOCALES`, `loadTranslations()`, typexporter |
| `packages/shared/src/i18n/.ts` | Översättningsfiler per språk |
| `apps/web/src/contexts/i18n-context.tsx` | `I18nProvider`, `useTranslation()`-hook |
| `apps/web/src/lib/format.ts` | `format()`-, `plural()`-, `formatFileSize()`-hjälpfunktioner |
| `apps/api/src/routes/config.ts` | `GET /api/v1/config/locale` publik ändpunkt |
## Översätta webbplatsen, dokumentationen och API-referensen {#translating-the-web-surfaces}
De 21 språk som stöds ovan gäller **appen**. Den publika webbplatsen
(snapotter.com), den här dokumentationssidan och REST-API-referensen är också
översatta till alla 21 språk, av en separat hash-styrd pipeline som återanvänder
samma verktygsnamn och beskrivningar från `packages/shared/src/i18n`, så att
terminologin förblir konsekvent överallt.
### Maskinöversatt som standard {#machine-translated-by-default}
Varje icke-engelsk sida på webbplatsen och i dokumentationen är **maskinöversatt** i
första omgången (av en Claude Code-session, inte en tredjepartstjänst) och bär
en liten, avfärdbar banner som talar om det, med en länk tillbaka hit. Det är ett
medvetet val: det levererar alla 21 språk snabbt och ärligt, och bjuder sedan in
gemenskapen att förfina de sidor som betyder mest. Maskinöversättning för fram
betydelsen; mänsklig granskning gör att den läses naturligt.
### Så avgör pipelinen vad som ska översättas {#how-the-web-pipeline-decides}
Varje översättningsbar enhet av den engelska källan hashas, och hashen lagras
intill sin översättning. Vid varje körning gör pipelinen följande:
- översätter varje enhet som ännu inte har någon översättning,
- hoppar över varje enhet vars lagrade hash fortfarande matchar den engelska källan,
- återöversätter en **maskin**-enhet när dess engelska källa ändras,
- och flaggar en **mänskligt** förfinad enhet som `stale` (behöver granskning) när dess
engelska källa ändras, i stället för att skriva över ditt arbete.
### Förfina en webböversättning via PR {#refining-a-web-translation-by-pr}
Du förbättrar en översättning av webbplatsen, dokumentationen eller API-referensen på samma sätt som du
förbättrar en språkversion i appen: genom att redigera den genererade filen och öppna en PR.
1. Hitta den genererade översättningen för ditt språk:
- UI-strängar för webbplatsen: `apps/landing/src/i18n/.json`
- en dokumentationssida: `apps/docs//**.md`
- API-referensen: `apps/api/src/openapi..yaml`
2. Redigera texten. Behåll kod, länkar, `{placeholders}` och alla `⸤I18N…⸥`-markeringar
exakt som de är; pipelinens validator avvisar en översättning som tar bort
eller kastar om dem.
3. Öppna en PR. Att redigera en enhet flippar dess ursprung från `machine` till `human`, så att
pipelinen **aldrig skriver över den** vid en senare körning. Om den engelska källan
ändras därefter flaggas din enhet som `stale` för granskning i stället för att
tyst ersättas.
För att rapportera en felöversättning utan att skicka in kod kan du öppna ett
[GitHub Issue](https://github.com/snapotter-hq/SnapOtter/issues) med sidans
URL, språket, den felaktiga texten och ditt föreslagna rättelse.
::: tip
Underhållarna kör översättningspipelinen; du behöver ingen API-nyckel för att
bidra. Redigera bara den genererade filen och öppna en PR. Se
[`scripts/i18n/README.md`](https://github.com/snapotter-hq/SnapOtter/blob/main/scripts/i18n/README.md)
för hur pipelinen körs.
:::