Vad är i18n?

Internationalisering (i18n) är processen att designa programvara så att den kan anpassas till olika språk och regioner utan att ändra din kod. Smeknamnet ”i18n” kommer från det faktum att det finns 18 bokstäver mellan ”i” och ”n” inom internationalisering.

Tänk på i18n som grunden för:

  • Lokalisering (l10n): Översätta och anpassa ditt innehåll för en specifik marknad.
  • Globalisering (g11n): Samordning av produktberedskap och verksamhet över olika marknader.

I praktiken handlar i18n om att se till att din app kan hantera:

  • Text på valfritt språk
  • Datum, tider, siffror och valutor i rätt format
  • Pluraliseringsregler som matchar lokal grammatik
  • Layouter från höger till vänster (som arabiska eller hebreiska)

 

Varför i18n är viktigt

Att investera i i18n i förväg ger konkreta fördelar för era teknik- och produktteam:

  • Lägre lokaliseringskostnader: Det är enklare att extrahera och ersätta strängar när översättningslogik är inbyggd från början.
  • Snabbare utveckling: Delad infrastruktur för hantering av strängar minskar framtida omarbete.
  • Bättre användarupplevelse: Användare ser innehåll på sitt språk, formaterat på ett sätt som känns naturligt.
  • Skalbarhet: Appar kan lanseras på nya marknader med färre kodändringar.

 

i18n-implementeringsmönster i moderna appar

Nedan följer några vanliga mönster för att implementera i18n i appar i produktionsklass. Vi går igenom React (frontend), iOS och Android.

Oavsett plattform kommer översättningar vanligtvis från ett översättningshanteringssystem (TMS) som Smartling, som JSON eller resursfiler. Dessa filer laddas sedan av din app vid körning via ett i18n-ramverk eller ett nativt lokaliserings-API, vilket säkerställer att rätt strängar visas för användarens språk eller språkinställning.

 

Frontend (React)

Moderna React-appar använder vanligtvis ett dedikerat i18n-bibliotek. Två av de mest populära är i18next och FormatJS, som båda är ramverksoberoende. I React är deras respektive implementationer react-i18next (funktions- och hook-baserad) och react-intl (komponent- och hook-baserad, byggd på ICU MessageFormat). Båda integreras snyggt med företagspipelines och hanterar pluralisering, variabler och språkanpassad formatering.

 

1. Reagera med i18next + react-i18next

i18next är ett av de mest populära JavaScript i18n-biblioteken, och när det paras ihop med react-i18next- bindningarna ger det React-appar ett kraftfullt, hook-vänligt API för att ladda och rendera översättningar.

I exemplet nedan går vi igenom ett vanligt i18n-mönster för företag. Vi definierar översättningsfiler, initierar i18next vid appens startpunkt och renderar sedan översättningar i komponenter. Den här metoden fungerar över olika ramverk, integreras smidigt med de flesta översättningshanteringssystem (TMS) och skalas väl allt eftersom din app växer – oavsett om du visar statiska strängar eller dynamiska, variabeldrivna meddelanden som antal.

 

Exempel på i18n-mönster: i18next + reacti18next

Du kommer förmodligen att få innehåll som JSON-filer från ditt översättningshanteringssystem. JSON-filexemplet nedan visar hur översättningar lagras för engelska. Varje post har en unik nyckel, och pluralformer definieras separat så att biblioteket kan välja rätt baserat på antalet du skickar. Ditt TMS genererar en matchande fil för varje språk som stöds.

 

{

  "welcome": "Welcome",

  "visits_one": "Du har besökt sidan {{count}} gång.",

  "visits_other": "Du har besökt {{count}} gånger."

}

 

Härnäst ser du ett exempel på hur du konfigurerar i18next så att den vet vilka språk din app stöder, var översättningarna finns och vad man ska göra om en översättning saknas. Den här installationsfilen körs en gång när din app startar (ofta i startpunktsfilen som index.js eller main.tsx) så att översättningarna är klara innan något användargränssnitt renderas. Att centralisera konfigurationen på ett ställe håller din lokaliseringslogik konsekvent i hela appen.

 

importera i18next från 'i18next';

importera { initReactI18next } från 'react-i18next';

import en from './locales/en/translation.json';

importera fr från './locales/fr/translation.json';

 

const locale = 'fr'; // i produktion, lösa dynamiskt

 

i18next

  .use(initReactI18next)

  .init({

    lng: locale,

    fallbackLng: 'en',

    resurser: {

      en: { translation: en },

      fr: { översättning: fr }

    },

    interpolering: { escapeValue: false }

  });

 

exportera standard i18next;

 

När i18next har initialiserats kan du använda det var som helst i din app. I exemplet nedan hämtar useTranslation- hooken t- funktionen, som tar en nyckel och valfria variabler för att rendera rätt sträng. När du skickar count som en variabel väljer i18next automatiskt rätt pluralform baserat på översättningsfilen.

 

importera { useTranslation } från 'react-i18next';

import './i18n';

 

exportera standardfunktionen App() {

  const { t } = useTranslation();

  konstant antal = 3;

 

  återvända (

    <>

      <h1>{t('welcome')}</h1>

      <p>{t('besök', { antal })}</p>

    </>

  );

}

 

2. Reagera med FORmatJS + react-intl

react-intl är en del av FormatJS- ekosystemet och tillhandahåller en komponentbaserad metod för i18n i React. Den är byggd på ICU MessageFormat-standarden, så du får inbyggd pluralisering, datum-/nummerformatering och språkalternativ.

I exemplet nedan konfigurerar vi översättningsfiler, lägger in appen i en IntlProvider och renderar lokaliserad text med hjälp av FormattedMessage. Denna metod passar väl för team som vill ha en deklarativ, komponentdriven stil för att hantera i18n i React.

 

Exempel på i18n-mönster: FormatJS + react-intl

JSON-filen nedan innehåller översättningar med ICU MessageFormat-syntax, vilket placerar plurallogik inuti själva strängen. Detta håller alla språkregler på ett ställe och låter översättare fullständig kontroll över grammatiken utan utvecklarintervention. Ditt TMS hanterar dessa filer per språk.

 

{

  "welcome": "Welcome",

{% raw %} "visits": "Du har besökt {count, plural, one {# time} other {# times}}." slut_raw %}

Härnäst ser du ett exempel på hur du paketerar din app i IntlProvider- komponenten. Detta är en engångsinstallation, vanligtvis gjord i en rotkomponent som Root.tsx eller index.jsx. Det gör den aktiva språkinställningen och dess meddelanden tillgängliga i hela din app så att alla komponenter kan använda dem utan extra importer.

 

importera { IntlProvider } från 'react-intl';

import en from './locales/en.json';

importera fr från './locales/fr.json';

 

const MESSAGES = { en, fr };

const locale = 'fr';

 

exportera standardfunktionen Root() {

  återvända (

    <IntlProvider locale={locale} messages={MESSAGES[locale]}>

      <App />

    </IntlProvider>

  );

}



Slutligen, läs nedan för att se hur FormattedMessage- komponenten söker upp en översättning efter dess ID och hanterar pluralisering automatiskt. Allt du behöver göra är att räkna, så tillämpar biblioteket korrekta språkregler från din JSON-fil.

 

importera { FormattedMessage } från 'react-intl';

 

exportera standardfunktionen App() {

  konstant antal = 3;

 

  återvända (

    <>

      <h1><FormattedMessage id="welcome" defaultMessage="Welcome" /></h1>

      <p><FormattedMessage id="visits" values={{ count }} /></p>

    </>

  );

}

 

Några ytterligare tips för produktionsanvändning:

  • Språkkälla: I riktiga appar, bestäm språket centralt (t.ex. från en URL som /fr/*, användarens profil eller en serverinställning) och skicka den till <IntlProvider>.
  • Meddelandeorganisation: För skala, dela upp meddelandefiler efter domän eller funktion (t.ex. auth.json, dashboard.json) och sammanfoga dem för den aktiva språkinställningen.
  • Reservalternativ: defaultMessage är ditt skyddsnät under utrullningen – håll det på ditt källspråk.
  • Asynkron inläsning (valfritt): För stora paket, importera meddelandefiler dynamiskt per språkinställning (koddelning) innan <IntlProvider> renderas.



iOS

iOS ger dig solida lokaliseringsverktyg direkt, men att skala till många språk kräver en genomtänkt implementering av bästa praxis för i18n. Annars, utan en tydlig struktur, kan du få dubbletter av nycklar, inkonsekvent formatering och översättningsfiler som blir besvärliga att underhålla. Nyckeln är att fatta några strukturella beslut tidigt så att din lokalisering förblir organiserad och enkel att utöka allt eftersom nya marknader läggs till.

 

Tips 1: Organisera resurser på ett skalbart sätt

Ett bra ställe att börja är med String Catalogs (.xcstrings) i Xcode 15 och senare, eller .strings/.stringsdict filer om du har en äldre installation. Dessa fungerar bra med ett TMS, som vanligtvis skickar översättningar i XLIFF-format. Du kan importera dem direkt till din katalog, så hanterar systemet det tunga arbetet med att sammanfoga och hantera dem.

Du kommer förmodligen att tycka att det är lättare att hålla ordning om du organiserar kataloger efter funktion eller modul. Mindre, riktade filer gör det enklare att hitta nycklar, granska ändringar och lämna över arbete till översättare. Här är ett exempel på hur du kanske vill organisera dem:

 

Resurser

  i18n/

    Autentiseringstexter

    Checkout.xcstrings

    Profil.xcstrings



Tips 2: Hantera pluralisering i katalogen, inte i koden

Pluralisering är ett annat område där struktur lönar sig. Det är bättre att definiera alla pluralregler i katalogen istället för i Swift, så att din kod bara skickar variabler och rätt fras väljs automatiskt för varje språk. Så här kan det se ut i katalogen:

 

Nyckel: olästa_meddelanden

Format: Plural

Ett: "%d oläst meddelande"

Annat: "%d olästa meddelanden"

 

Och så här kan du använda det i Swift:

 

låt antal olästa = 3

låt format = String(lokaliserad: "olästa_meddelanden")

låt meddelande = String.localizedStringWithFormat(format, olästaAntal)

// "3 olästa meddelanden"

 

På så sätt slipper du hårdkoda grammatiken i koden, och översättarna kan få detaljerna rätt för varje språk.

 

Tips 3: Centralisera formatering för siffror, datum och valutor

Du vill också centralisera formateringen av siffror, datum och valuta så att varje del av appen känns konsekvent. Ett delat verktyg eller en delad tjänst kan hjälpa till med det. Här är ett enkelt exempel med Swifts moderna FormatStyle API:

 

uthyrningspris = 19,99

låt display = price.formatted(.currency(kod: "EUR"))

// "19,99 €" eller "19,99 €" beroende på plats

 

Genom att hålla dina strängresurser organiserade, hantera pluralisering i katalogen och centralisera all din språkanpassade formatering, kan du ställa in din iOS-app för att växa utan att skapa extra underhållsarbete. När dessa rutiner är på plats blir processen för att lägga till nya språk mycket mer förutsägbar – och mycket mindre stressig. Nu ska vi titta på Android, som erbjuder sina egna inbyggda lokaliseringsverktyg.

 

Android

Androids resurssystem är redan utformat med lokalisering i åtanke, men att hålla det underhållbart på många språk kräver lite planering. Om du sparar allt i en stor fil eller sprider ut grammatikregler i koden kan det bli rörigt snabbt. Prioritera istället en segmenterad filorganisation, definiera alla grammatikregler i XML och se till att formatering och layout fungerar för alla skrivsystem du planerar att stödja.

 

Tips 1: Håll resurserna organiserade efter funktion

För de flesta team kommer översättningarna från ett TMS som XLIFF-filer. Du importerar dessa till res/values -katalogerna för varje språk, och Android tar hand om att matcha rätt strängar med användarens språk.

Att dela upp dina resurser i separata filer efter funktion är ett enkelt sätt att göra livet enklare. Mindre filer gör det snabbare att granska ändringar och hjälper till att undvika sammanslagningskonflikter.

 

app/src/main/res/

  values/strings_auth.xml

  values/strings_checkout.xml

  values/plurals_checkout.xml

 

Tips 2: Definiera grammatikregler i resurser, inte i kod

Precis som i iOS är pluralisering en av de saker som bäst hanteras i resurser så att översättare kan anpassa det per språk utan att du behöver ändra kod. Här är ett exempel på en pluralresurs på engelska:

 

<plurals name="checkout_cart_items_count">

    <item quantity="one">%1$d item</item>

    <item quantity="other">%1$d artiklar</item>

</plurals>

 

Och så här använder du det i Kotlin:

 

val msg = resources.getQuantityString(

    R.plurals.checkout_cart_items_count, räkna, räkna

)

 

På så sätt förblir vår kod ren, och Android väljer automatiskt rätt form baserat på språkinställningen.

 

Tips 3: Använd språkanpassad formatering 

För layouter är det en god vana att använda start och slut istället för vänster och höger så att de anpassar sig för höger-till-vänster-språk som arabiska eller hebreiska:

 

<LinearLayout

    android:paddingStart="16dp"

    android:paddingEnd="16dp"

    android:layout_width="match_parent"

    android:layout_height="wrap_content">

</LinearLayout>

 

Och när du formaterar siffror eller valutor, ange appens aktuella språkinställning så att allt ser konsekvent ut:

 

val appLocale = LocaleListCompat.getAdjustedDefault()[0] ?: Locale.getDefault()

val pris = NumberFormat.getCurrencyInstance(appLocale).format(1234.56)

// "1 234,56 dollar" eller "1 234,56 €"

 

I slutändan handlar det mesta om att låta plattformen göra det tunga arbetet att få Android i18n rätt. Genom att behålla all text i resurser, strukturera dessa resurser med språkspecifika mappar och bygga in RTL- och språkmedveten formatering från dag ett, undviker du de vanliga fällor som gör lokalisering spröd. Många av dessa principer återspeglar bästa praxis för iOS, men Androids resurskvalificeringssystem innebär att du ofta kan stödja nya språk genom att helt enkelt lägga till rätt filer. Om det görs väl blir skalning till nya platser en förutsägbar och ansträngningsfri process.

 

Vanliga fallgropar för i18n

Tyvärr stöter även välbyggda system ibland på problem som kunnat undvikas. Tabellen nedan beskriver några av de vanligaste misstagen, varför de orsakar problem och hur man förebygger dem. Se detta som en snabb referens som du kan använda för att kontrollera din egen installation innan du skickar.

 

Misstag

Hur man undviker det

Hårdkodade strängar

Extrahera all användarvänlig text till resursfiler eller översättningsnycklar.

Förutsatt att all text är från vänster till höger

Testa layouter med höger-till-vänster-språk som arabiska eller hebreiska.

Att försumma pluralisering

Använd bibliotek som stöder pluralregler (t.ex. ICU-format, i18next).

Olokaliserade enheter eller format

Använd språkanpassad formatering (t.ex. Intl.NumberFormat, Intl.DateTimeFormat).

Hoppa över textexpansionskontroller

Testa med pseudo-lokaler för att simulera längre översättningar.

Ofullständig strängextraktion

Använd pseudo-lokaler i mellanlagring för att avslöja saknade eller otaggade strängar.

 

 

Förberedelser för lokalisering i stor skala

När din app är konfigurerad för internationalisering är nästa steg att göra lokaliseringen så effektiv och underhållsfri som möjligt. Några automatiseringsverktyg och arbetsflöden kan ta dig från ”vi kan översätta” till ”vi kan lansera nya språk snabbt, utan extra utvecklingsbelastning”. Överväga:

  • Använda ett översättningshanteringssystem (TMS) med ett API i företagsklass, som Smartling, för att synkronisera översättningsfiler och hantera granskningsarbetsflöden.
  • Automatisera strängutvinning och leverans med hjälp av din CI/CD-pipeline.
  • Använda AI-verktyg (som Smartlings AI Hub) för snabba översättningar i första omgången med inbyggda kvalitetskontroller som reservhantering och hallucinationsreducering.

 

Sista tankar

Internationalisering är en grundläggande praxis för alla produkter som blir globala, och ju tidigare du implementerar det, desto färre huvudvärk kommer du att ha senare. Kombinera gedigna i18n-metoder med automatisering av översättningar och testningsarbetsflöden, så är ditt team väl rustat att leverera internationellt redo programvara snabbare och mer säkert.

Vill du gå djupare? Kolla in Smartlings Webbinarium om Global Ready-konferensen om i18n strategi i AI:s tidsålder.

Varför vänta med att översätta smartare?

Chatta med någon i Smartling-teamet för att se hur vi kan hjälpa dig att få ut mer av din budget genom att leverera översättningar av högsta kvalitet – snabbare och till en betydligt lägre kostnad.
Cta-Card-Side-Image