Files
SnapOtter/apps/docs/pl/guide/translations.md
T
SnapOtterandGitHub 4963ab3bbd feat(docs-i18n): translate all documentation into 20 languages
All 181 docs markdown files translated into 20 languages (apps/docs/<locale>/**). Companion to the i18n code PR; admin-merged because the file count exceeds GitHub's per-PR CI trigger limit. Validated by pnpm i18n:check (all surfaces, 0 stale/missing) and a clean all-locale docs build.
2026-07-11 13:52:47 +08:00

11 KiB

description, i18n_source_hash, i18n_provenance, i18n_output_hash
description i18n_source_hash i18n_provenance i18n_output_hash
21 obsługiwanych języków oraz sposób tworzenia i ulepszania tłumaczeń dla SnapOtter za pomocą systemu i18n wymuszanego przez TypeScript. 55837d9fdaef human 2f2ee690b721

Przewodnik po tłumaczeniach

SnapOtter dostarczany jest z 21 językami od razu po instalacji. System i18n korzysta z lekkiego, własnego środowiska uruchomieniowego z wymuszaną przez TypeScript kompletnością lokalizacji oraz dynamicznym dzieleniem kodu.

Obsługiwane języki

Code Language Native Name Direction
en angielski English LTR
zh-CN chiński (uproszczony) 简体中文 LTR
zh-TW chiński (tradycyjny) 繁體中文 LTR
ja japoński 日本語 LTR
ko koreański 한국어 LTR
es hiszpański Español LTR
fr francuski Français LTR
it włoski Italiano LTR
pt-BR portugalski (Brazylia) Português (Brasil) LTR
de niemiecki Deutsch LTR
nl niderlandzki Nederlands LTR
sv szwedzki Svenska LTR
ru rosyjski Русский LTR
pl polski Polski LTR
uk ukraiński Українська LTR
ar arabski العربية RTL
tr turecki Türkçe LTR
hi hindi हिन्दी LTR
vi wietnamski Tiếng Việt LTR
id indonezyjski Bahasa Indonesia LTR
th tajski ไทย LTR

Jak działa wykrywanie języka

SnapOtter stosuje trzypoziomową kolejność rozstrzygania:

  1. Preferencja użytkownika - przechowywana w localStorage("snapotter-locale") i synchronizowana z ustawieniami użytkownika po zalogowaniu
  2. Automatyczne wykrywanie przeglądarki - przechodzi przez tablicę navigator.languages z dopasowywaniem prefiksów BCP 47
  3. Domyślny język instancji - zmienna środowiskowa administratora DEFAULT_LOCALE (pobierana z GET /api/v1/config/locale)
  4. Awaryjny język angielski - zawsze dostępny

Użytkownicy mogą zmienić język w:

  • selektorze Globe w stopce (na komputerze, zawsze widoczny)
  • selektorze języka na stronie logowania (przed uwierzytelnieniem)
  • sekcji Ustawienia > Ogólne (preferencja dla danego użytkownika)
  • rozwijanej liście języków w mobilnym pasku bocznym
  • sekcji Ustawienia > System, która ustawia domyślny język dla całej instancji (tylko administrator)

Jak działają tłumaczenia

Wszystkie napisy interfejsu znajdują się w packages/shared/src/i18n/. Plikiem referencyjnym jest en.ts, który eksportuje typowany obiekt zawierający każdy napis używany przez aplikację (~1500 kluczy). Pozostałe języki to osobne pliki (np. de.ts, fr.ts), które eksportują ten sam kształt.

Typ TranslationKeys wykorzystuje DeepStringRecord, aby przyjmować dowolną wartość tekstową, wymuszając jednocześnie strukturę kluczy. TypeScript wychwytuje brakujące klucze w dowolnym pliku tłumaczenia na etapie kompilacji.

W czasie działania ładowana jest tylko aktywna lokalizacja poprzez dynamiczny import(), dzięki czemu główny pakiet pozostaje niewielki.

Używanie tłumaczeń w komponentach

import { useTranslation } from "@/contexts/i18n-context";
import { format, plural } from "@/lib/format";

function MyComponent() {
  const { t, locale, setLocale } = useTranslation();
  
  return (
    <div>
      <h1>{t.common.settings}</h1>
      <p>{format(t.settings.people.deleteConfirm, { username: "admin" })}</p>
      <p>{plural(count, t.automate.fileCount, t.automate.fileCountPlural)}</p>
    </div>
  );
}

Współtworzenie tłumaczenia

Chętnie przyjmujemy PR-y z tłumaczeniami bezpośrednio. Możesz ulepszyć istniejącą lokalizację lub dodać nową.

Aby zgłosić błędne tłumaczenie bez przesyłania kodu, otwórz zgłoszenie na GitHubie z podaniem języka, nieprawidłowego napisu oraz proponowanej poprawki.

::: tip PR-y z tłumaczeniami nie wymagają wcześniejszej akceptacji. Rozgałęź repozytorium, wprowadź zmiany i otwórz PR. Zajrzyj do przewodnika dla współtwórców, aby poznać pełny proces PR oraz wymóg CLA. :::

Jak utworzyć lub zaktualizować tłumaczenie

1. Rozgałęź i sklonuj

git clone https://github.com/<your-username>/snapotter.git
cd snapotter
pnpm install

2. Skopiuj plik referencyjny (tylko nowy język)

Pomiń ten krok, jeśli ulepszasz istniejące tłumaczenie.

cp packages/shared/src/i18n/en.ts packages/shared/src/i18n/XX.ts

3. Przetłumacz napisy

Otwórz swój nowy plik i przetłumacz każdą wartość tekstową. Zachowaj strukturę obiektu i klucze dokładnie takie same.

import type { TranslationKeys } from "./en.js";

export const xx: TranslationKeys = {
  common: {
    upload: "Your translation here",
    // ... translate all entries
  },
  // ... translate all sections
} as const;

Zasady:

  • Nie tłumacz kluczy obiektu, tylko wartości tekstowe
  • Zachowaj as const na końcu
  • Zaimportuj TranslationKeys z ./en.js i otypuj swój eksport
  • Zachowaj symbole zastępcze {variable} dokładnie w takiej samej postaci
  • Tablice (rotatingPhrases, progressMessages) muszą mieć tę samą liczbę wpisów
  • Nie tłumacz: SnapOtter, JPEG, PNG, WebP, EXIF, API oraz innych terminów technicznych

4. Zarejestruj lokalizację (tylko nowy język)

Dodaj swoją lokalizację do SUPPORTED_LOCALES w packages/shared/src/i18n/index.ts:

{ code: "xx", name: "Language Name", nativeName: "Native Name", dir: "ltr" },

5. Zweryfikuj

pnpm typecheck    # catches missing or mistyped keys
pnpm lint         # formatting check
pnpm dev          # manually verify strings appear correctly

6. Prześlij

Otwórz PR wobec main z tytułem w rodzaju feat(i18n): add Swedish translation lub fix(i18n): correct German typos. Bot CLA poprosi Cię o podpis przy pierwszym wkładzie.

Dodawanie nowych kluczy tłumaczeń

Dodając nową funkcję, która wymaga nowych napisów interfejsu:

  1. Najpierw dodaj nowe klucze do en.ts (plik referencyjny)
  2. Uruchom pnpm typecheck - każdy plik lokalizacji zgłosi błąd, jeśli brakuje w nim nowego klucza
  3. Dodaj nowy klucz do wszystkich plików lokalizacji (jako tymczasowego zastępstwa użyj języka angielskiego)

Konfiguracja

Ustaw domyślny język instancji za pomocą zmiennej środowiskowej:

DEFAULT_LOCALE: "de"  # German as the default for all new users

Zestawienie plików

File Purpose
packages/shared/src/i18n/en.ts napisy angielskie (lokalizacja referencyjna, ~1500 kluczy)
packages/shared/src/i18n/index.ts SUPPORTED_LOCALES, loadTranslations(), eksporty typów
packages/shared/src/i18n/<locale>.ts pliki tłumaczeń dla poszczególnych języków
apps/web/src/contexts/i18n-context.tsx I18nProvider, hook useTranslation()
apps/web/src/lib/format.ts pomocnicze format(), plural(), formatFileSize()
apps/api/src/routes/config.ts publiczny punkt końcowy GET /api/v1/config/locale

Tłumaczenie witryny, dokumentacji i dokumentacji API

Opisane powyżej wsparcie dla 21 języków obejmuje aplikację. Publiczna witryna (snapotter.com), ta strona z dokumentacją oraz dokumentacja REST API również są tłumaczone na wszystkie 21 języków przez osobny, sterowany hashem potok, który ponownie wykorzystuje te same nazwy i opisy narzędzi z packages/shared/src/i18n, dzięki czemu terminologia pozostaje spójna wszędzie.

Domyślnie tłumaczone maszynowo

Każda nieanglojęzyczna strona witryny i dokumentacji jest tłumaczona maszynowo przy pierwszym przejściu (przez sesję Claude Code, a nie usługę firm trzecich) i zawiera niewielki, możliwy do zamknięcia baner informujący o tym, wraz z odnośnikiem z powrotem tutaj. Jest to celowe: pozwala szybko i uczciwie dostarczyć wszystkie 21 języków, a następnie zaprasza społeczność do dopracowania stron, które mają największe znaczenie. Tłumaczenie maszynowe przekazuje sens; dopiero weryfikacja przez człowieka sprawia, że tekst czyta się naturalnie.

Jak potok decyduje, co przetłumaczyć

Każda tłumaczalna jednostka źródła angielskiego jest hashowana, a hash przechowywany jest obok jej tłumaczenia. Przy każdym uruchomieniu potok:

  • tłumaczy każdą jednostkę, która nie ma jeszcze tłumaczenia,
  • pomija każdą jednostkę, której przechowywany hash wciąż zgadza się ze źródłem angielskim,
  • ponownie tłumaczy jednostkę maszynową, gdy zmieni się jej źródło angielskie,
  • oraz oznacza jednostkę dopracowaną przez człowieka jako stale (wymaga weryfikacji), gdy jej źródło angielskie ulegnie zmianie, zamiast nadpisywać Twoją pracę.

Dopracowanie tłumaczenia strony internetowej przez PR

Tłumaczenie witryny, dokumentacji lub dokumentacji API ulepszasz w ten sam sposób, w jaki ulepszasz lokalizację aplikacji: edytując wygenerowany plik i otwierając PR.

  1. Znajdź wygenerowane tłumaczenie dla swojego języka:
    • napisy interfejsu witryny: apps/landing/src/i18n/<locale>.json
    • strona dokumentacji: apps/docs/<locale>/**.md
    • dokumentacja API: apps/api/src/openapi.<locale>.yaml
  2. Zredaguj tekst. Zachowaj kod, odnośniki, {placeholders} oraz wszelkie znaczniki ⸤I18N…⸥ dokładnie w takiej postaci, w jakiej są; walidator potoku odrzuca tłumaczenie, które pomija lub zmienia ich kolejność.
  3. Otwórz PR. Edycja jednostki zmienia jej pochodzenie z machine na human, dzięki czemu potok nigdy jej nie nadpisze przy późniejszym uruchomieniu. Jeśli źródło angielskie zmieni się później, Twoja jednostka zostanie oznaczona jako stale do weryfikacji, zamiast zostać po cichu zastąpiona.

Aby zgłosić błędne tłumaczenie bez przesyłania kodu, otwórz zgłoszenie na GitHubie z podaniem adresu URL strony, języka, nieprawidłowego tekstu oraz proponowanej poprawki.

::: tip Potok tłumaczeń uruchamiają opiekunowie projektu; do wniesienia wkładu nie potrzebujesz klucza API. Wystarczy, że zredagujesz wygenerowany plik i otworzysz PR. Zajrzyj do scripts/i18n/README.md, aby dowiedzieć się, jak działa potok. :::