SĂ„ bygger du en modern AI-driven webbapp med i18n 2026
Komplett guide till att bygga flersprÄkiga webbappar med Lingui + AI-översÀttning. Stöd 17 sprÄk automatiskt med Next.js, Claude och T3 Turbo.

Hörni, vi mÄste snacka om i18n Är 2026.
De flesta tutorials kommer sÀga Ät dig att översÀtta strÀngar manuellt, anlita översÀttare eller anvÀnda nÄgot svajigt Google Translate-API. Men grejen Àr den: du lever i Claude Sonnet 4.5-eran. Varför översÀtter du som om det vore 2019?
Jag tÀnker visa hur vi byggde en produktions-webapp som talar 17 sprÄk flytande, med hjÀlp av en tvÄdelad i18n-arkitektur som faktiskt Àr logisk:
- Lingui för extrahering, kompilering och runtime-magi
- Ett skrÀddarsytt i18n-paket drivet av LLM:er för automatiserade, kontextmedvetna översÀttningar
VÄr stack? Create T3 Turbo med Next.js, tRPC, Drizzle, Postgres, Tailwind och AI SDK. Om du inte anvÀnder detta 2026 behöver vi ta ett helt annat snack.
DÄ kör vi.
Problemet med traditionell i18n
Traditionella arbetsflöden för i18n ser ut sÄ hÀr:
# Extrahera strÀngar
$ lingui extract
# ??? FÄ tag pÄ översÀttningar pÄ nÄgot sÀtt ???
# (anlita översÀttare, anvÀnd skumma tjÀnster, grÄt en skvÀtt)
# Kompilera
$ lingui compile
Det dÀr mellansteg? Det Àr en mardröm. Antingen:
- Betalar du $$$ för mÀnskliga översÀttare (lÄngsamt, dyrt)
- AnvÀnder grundlÀggande översÀttnings-API:er (blinda för kontext, lÄter robotaktigt)
- ĂversĂ€tter manuellt (skalar inte)
Vi gör det bÀttre.
Den tvÄdelade arkitekturen
HÀr Àr vÄr setup:
âââââââââââââââââââââââââââââââââââââââââââââââ
â Next.js App (Lingui Integration) â
â ââ Extrahera strĂ€ngar med makron â
â ââ Trans/t-komponenter i din kod â
â ââ Runtime i18n med kompilerade kataloger â
âââââââââââââââââââââââââââââââââââââââââââââââ
â genererar .po-filer
âââââââââââââââââââââââââââââââââââââââââââââââ
â @acme/i18n Package (LLM-översĂ€ttning) â
â ââ LĂ€ser .po-filer â
â ââ Batch-översĂ€tter med Claude/GPT-5 â
â ââ Kontextmedveten, produktspecifik â
â ââ Skriver översatta .po-filer â
âââââââââââââââââââââââââââââââââââââââââââââââ
â kompilerar till TypeScript
âââââââââââââââââââââââââââââââââââââââââââââââ
â Compiled Message Catalogs â
â ââ Snabb, typsĂ€ker runtime-översĂ€ttning â
âââââââââââââââââââââââââââââââââââââââââââââââ
Del 1 (Lingui) hanterar utvecklarupplevelsen (DX). Del 2 (SkrÀddarsytt i18n-paket) hanterar översÀttningsmagin.
LÄt oss dyka ner i detaljerna.

Del 1: SĂ€tta upp Lingui i Next.js
Installation
I ditt T3 Turbo-monorepo:
# I apps/nextjs
pnpm add @lingui/core @lingui/react @lingui/macro
pnpm add -D @lingui/cli @lingui/swc-plugin
Lingui Config
Skapa apps/nextjs/lingui.config.ts:
import type { LinguiConfig } from "@lingui/conf";
const config: LinguiConfig = {
locales: [
"en", "zh_CN", "zh_TW", "ja", "ko",
"de", "fr", "es", "pt", "ar", "it",
"ru", "tr", "th", "id", "vi", "hi"
],
sourceLocale: "en",
fallbackLocales: {
default: "en"
},
catalogs: [
{
path: "<rootDir>/src/locales/{locale}/messages",
include: ["src"],
},
],
};
export default config;
17 sprÄk direkt ur lÄdan. För varför inte?
Next.js Integration
Uppdatera next.config.js för att anvÀnda Linguis SWC-plugin:
const linguiConfig = require("./lingui.config");
module.exports = {
experimental: {
swcPlugins: [
[
"@lingui/swc-plugin",
{
// Detta gör dina byggen snabbare
},
],
],
},
// ... resten av din config
};
Server-Side Setup
Skapa src/utils/i18n/appRouterI18n.ts:
import { setupI18n } from "@lingui/core";
import { allMessages } from "./initLingui";
const locales = ["en", "zh_CN", "zh_TW", /* ... */] as const;
const instances = new Map<string, ReturnType<typeof setupI18n>>();
// För-skapa i18n-instanser för alla sprÄk
locales.forEach((locale) => {
const i18n = setupI18n({
locale,
messages: { [locale]: allMessages[locale] },
});
instances.set(locale, i18n);
});
export function getI18nInstance(locale: string) {
return instances.get(locale) ?? instances.get("en")!;
}
Varför? Server Components har inte React Context. Detta ger dig översÀttningar pÄ serversidan.
Client-Side Provider
Skapa src/providers/LinguiClientProvider.tsx:
"use client";
import { I18nProvider } from "@lingui/react";
import { setupI18n } from "@lingui/core";
import { useEffect, useState } from "react";
export function LinguiClientProvider({
children,
locale,
messages
}: {
children: React.ReactNode;
locale: string;
messages: any;
}) {
const [i18n] = useState(() =>
setupI18n({
locale,
messages: { [locale]: messages },
})
);
useEffect(() => {
i18n.load(locale, messages);
i18n.activate(locale);
}, [locale, messages, i18n]);
return <I18nProvider i18n={i18n}>{children}</I18nProvider>;
}
Wrappa din app i layout.tsx:
import { LinguiClientProvider } from "@/providers/LinguiClientProvider";
import { getLocale } from "@/utils/i18n/localeDetection";
import { allMessages } from "@/utils/i18n/initLingui";
export default function RootLayout({ children }: { children: React.ReactNode }) {
const locale = getLocale();
return (
<html lang={locale}>
<body>
<LinguiClientProvider locale={locale} messages={allMessages[locale]}>
{children}
</LinguiClientProvider>
</body>
</html>
);
}
AnvÀnda översÀttningar i din kod
I Server Components:
import { msg } from "@lingui/core/macro";
import { getI18nInstance } from "@/utils/i18n/appRouterI18n";
export async function generateMetadata({ params }) {
const locale = getLocale();
const i18n = getI18nInstance(locale);
return {
title: i18n._(msg`Pricing Plans | acme`),
description: i18n._(msg`Choose the perfect plan for you`),
};
}
I Client Components:
"use client";
import { Trans, useLingui } from "@lingui/react/macro";
export function PricingCard() {
const { t } = useLingui();
return (
<div>
<h1><Trans>Pricing Plans</Trans></h1>
<p>{t`Ultimate entertainment experience`}</p>
{/* Med variabler */}
<p>{t`${credits} credits remaining`}</p>
</div>
);
}
Makro-syntaxen Àr NYCKELN. Lingui extraherar dessa vid byggtid (build time).
Del 2: Det AI-drivna översÀttningspaketet
HÀr börjar det bli riktigt intressant.
Paketstruktur
Skapa packages/i18n/:
packages/i18n/
âââ package.json
âââ src/
â âââ translateWithLLM.ts # KĂ€rnan för LLM-översĂ€ttning
â âââ enhanceTranslations.ts # Batch-processor
â âââ utils.ts # HjĂ€lpfunktioner
package.json
{
"name": "@acme/i18n",
"version": "0.1.0",
"dependencies": {
"@acme/ai": "workspace:*",
"openai": "^4.77.3",
"pofile": "^1.1.4",
"zod": "^3.23.8"
}
}
LLM-översÀttningsmotorn
HĂ€r Ă€r den hemliga sĂ„sen â translateWithLLM.ts:
import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
import { z } from "zod";
const translationSchema = z.object({
translations: z.array(
z.object({
msgid: z.string(),
msgstr: z.string(),
})
),
});
export async function translateWithLLM(
messages: Array<{ msgid: string; msgstr: string }>,
targetLocale: string,
options?: { model?: string }
) {
const prompt = `You are a professional translator for acme, an AI-powered creative platform.
Translate the following strings from English to ${getLanguageName(targetLocale)}.
CONTEXT:
- acme is a platform for AI chat, image generation, and creative content
- Keep brand names unchanged (acme, Claude, etc.)
- Preserve HTML tags, variables like {count}, and placeholders
- Adapt culturally where appropriate
- Maintain tone: friendly, creative, engaging
STRINGS TO TRANSLATE:
${JSON.stringify(messages, null, 2)}
Return a JSON object with this structure:
{
"translations": [
{ "msgid": "original", "msgstr": "translation" },
...
]
}`;
const result = await generateText({
model: openai(options?.model ?? "gpt-4o"),
prompt,
temperature: 0.3, // LĂ€gre = mer konsekvent
});
const parsed = translationSchema.parse(JSON.parse(result.text));
return parsed.translations;
}
function getLanguageName(locale: string): string {
const names: Record<string, string> = {
zh_CN: "Simplified Chinese",
zh_TW: "Traditional Chinese",
ja: "Japanese",
ko: "Korean",
de: "German",
fr: "French",
es: "Spanish",
pt: "Portuguese",
ar: "Arabic",
// ... osv
};
return names[locale] ?? locale;
}
Varför detta fungerar:
- Kontextmedveten: LLM:en vet vad "acme" Àr.
- Strukturerad output: Zod-schemat garanterar giltig JSON.
- LÄg temperatur: Konsekventa översÀttningar.
- Bevarar formatering: HTML och variabler förblir intakta.
Batch-översÀttningsprocessor
Skapa enhanceTranslations.ts:
import fs from "fs";
import path from "path";
import pofile from "pofile";
import { translateWithLLM } from "./translateWithLLM";
const BATCH_SIZE = 30; // ĂversĂ€tt 30 strĂ€ngar Ă„t gĂ„ngen
const DELAY_MS = 1000; // Rate limiting
export async function enhanceTranslations(
locale: string,
catalogPath: string
) {
const poPath = path.join(catalogPath, locale, "messages.po");
const po = pofile.parse(fs.readFileSync(poPath, "utf-8"));
// Hitta oöversatta objekt
const untranslated = po.items.filter(
(item) => item.msgid && (!item.msgstr || item.msgstr[0] === "")
);
if (untranslated.length === 0) {
console.log(`â ${locale}: All strings translated`);
return;
}
console.log(`Translating ${untranslated.length} strings for ${locale}...`);
// Processa i batcher
for (let i = 0; i < untranslated.length; i += BATCH_SIZE) {
const batch = untranslated.slice(i, i + BATCH_SIZE);
const messages = batch.map((item) => ({
msgid: item.msgid,
msgstr: item.msgstr?.[0] ?? "",
}));
try {
const translations = await translateWithLLM(messages, locale);
// Uppdatera PO-filen
translations.forEach((translation, index) => {
const item = batch[index];
if (item) {
item.msgstr = [translation.msgstr];
}
});
console.log(` ${i + batch.length}/${untranslated.length} translated`);
// Spara framsteg
fs.writeFileSync(poPath, po.toString());
// Rate limiting
if (i + BATCH_SIZE < untranslated.length) {
await new Promise((resolve) => setTimeout(resolve, DELAY_MS));
}
} catch (error) {
console.error(` Error translating batch: ${error}`);
// FortsÀtt med nÀsta batch
}
}
console.log(`â ${locale}: Translation complete!`);
}
Batch-processering förhindrar att vi slÄr i taket för tokens och sparar kostnader.
ĂversĂ€ttningsskriptet
Skapa apps/nextjs/script/i18n.ts:
import { enhanceTranslations } from "@acme/i18n";
import { exec } from "child_process";
import { promisify } from "util";
const execAsync = promisify(exec);
const LOCALES = [
"zh_CN", "zh_TW", "ja", "ko", "de",
"fr", "es", "pt", "ar", "it", "ru"
];
async function main() {
// Steg 1: Extrahera strÀngar frÄn kod
console.log("đ Extracting strings...");
await execAsync("pnpm run lingui:extract --clean");
// Steg 2: Auto-översÀtt saknade strÀngar
console.log("\nđ€ Translating with AI...");
const catalogPath = "./src/locales";
for (const locale of LOCALES) {
await enhanceTranslations(locale, catalogPath);
}
// Steg 3: Kompilera till TypeScript
console.log("\n⥠Compiling catalogs...");
await execAsync("npx lingui compile --typescript");
console.log("\nâ
Done! All translations updated.");
}
main().catch(console.error);
LĂ€gg till i package.json:
{
"scripts": {
"i18n": "tsx script/i18n.ts",
"lingui:extract": "lingui extract",
"lingui:compile": "lingui compile --typescript"
}
}
Köra din i18n-pipeline
# Ett kommando för att styra dem alla
$ pnpm run i18n
đ Extracting strings...
Catalog statistics for src/locales/{locale}/messages:
ââââââââââââŹââââââââââââââŹââââââââââ
â Language â Total count â Missing â
ââââââââââââŒââââââââââââââŒââââââââââ€
â en â 847 â 0 â
â zh_CN â 847 â 123 â
â ja â 847 â 89 â
ââââââââââââŽââââââââââââââŽââââââââââ
đ€ Translating with AI...
Translating 123 strings for zh_CN...
30/123 translated
60/123 translated
90/123 translated
123/123 translated
â zh_CN: Translation complete!
⥠Compiling catalogs...
â
Done! All translations updated.
SĂ„ enkelt Ă€r det. LĂ€gg till en ny strĂ€ng i din kod, kör pnpm i18n, boom â översatt till 17 sprĂ„k.

Byta sprÄk (Locale Switching)
Glöm inte UX-biten. HÀr Àr en sprÄkvÀljare:
"use client";
import { useLocaleSwitcher } from "@/hooks/useLocaleSwitcher";
import { useLocale } from "@/hooks/useLocale";
const LOCALES = {
en: "English",
zh_CN: "çźäœäžæ",
zh_TW: "çčé«äžæ",
ja: "æ„æŹèȘ",
ko: "íê”ìŽ",
// ... osv
};
export function LocaleSelector() {
const currentLocale = useLocale();
const { switchLocale } = useLocaleSwitcher();
return (
<select
value={currentLocale}
onChange={(e) => switchLocale(e.target.value)}
>
{Object.entries(LOCALES).map(([code, name]) => (
<option key={code} value={code}>
{name}
</option>
))}
</select>
);
}
Hook-implementationen:
// hooks/useLocaleSwitcher.tsx
"use client";
import { setUserLocale } from "@/utils/i18n/localeDetection";
export function useLocaleSwitcher() {
const switchLocale = (locale: string) => {
setUserLocale(locale);
window.location.reload(); // Tvinga omladdning för att applicera sprÄk
};
return { switchLocale };
}
Spara preferensen i en cookie:
// utils/i18n/localeDetection.ts
import { cookies } from "next/headers";
export function setUserLocale(locale: string) {
cookies().set("NEXT_LOCALE", locale, {
maxAge: 365 * 24 * 60 * 60, // 1 Är
});
}
export function getLocale(): string {
const cookieStore = cookies();
return cookieStore.get("NEXT_LOCALE")?.value ?? "en";
}
Avancerat: TypsÀkra översÀttningar
Vill du ha typsÀkerhet? Lingui löser det:
// IstÀllet för detta:
t`Hello ${name}`
// AnvÀnd msg descriptor:
import { msg } from "@lingui/core/macro";
const greeting = msg`Hello ${name}`;
const translated = i18n._(greeting);
Din IDE kommer att autokomplettera översÀttningsnycklar. Vackert.
PrestandaövervÀganden
1. Kompilera vid byggtid (Build Time)
Lingui kompilerar översÀttningar till minifierad JSON. Ingen overhead för parsing vid runtime.
// Kompilerad output (minifierad):
export const messages = JSON.parse('{"ICt8/V":["è§éą"],"..."}');
2. Förladda server-kataloger
Ladda alla kataloger en gÄng vid uppstart (se appRouterI18n.ts ovan). Ingen fil-I/O vid varje request.
3. Klientens bundle-storlek
Skeppa bara det aktiva sprÄket till klienten:
<LinguiClientProvider
locale={locale}
messages={allMessages[locale]} // Endast ett sprÄk
>
4. Kostnadsoptimering för LLM
- Batch-översÀttningar: 30 strÀngar per API-anrop
- Cacha översĂ€ttningar: ĂversĂ€tt inte om oförĂ€ndrade strĂ€ngar
- AnvÀnd billigare modeller: GPT-4o-mini för icke-kritiska sprÄk
VÄr kostnad? ~$2-3 för 800+ strÀngar à 16 sprÄk. SmÄpengar jÀmfört med mÀnskliga översÀttare.
Integration med hela tech-stacken
LÄt oss se hur detta spelar ihop med resten av T3 Turbo:
tRPC med i18n
// server/api/routers/user.ts
import { createTRPCRouter, publicProcedure } from "../trpc";
import { msg } from "@lingui/core/macro";
export const userRouter = createTRPCRouter({
subscribe: publicProcedure
.mutation(async ({ ctx }) => {
// Felmeddelanden kan ocksÄ översÀttas!
if (!ctx.session?.user) {
throw new TRPCError({
code: "UNAUTHORIZED",
message: ctx.i18n._(msg`You must be logged in`),
});
}
// ... prenumerationslogik
}),
});
Skicka med i18n-instansen via context:
// server/api/trpc.ts
import { getI18nInstance } from "@/utils/i18n/appRouterI18n";
export const createTRPCContext = async (opts: CreateNextContextOptions) => {
const locale = getLocale();
const i18n = getI18nInstance(locale);
return {
session: await getServerAuthSession(),
i18n,
locale,
};
};
Databas med Drizzle
Spara anvÀndarens sprÄkpreferens:
// packages/db/schema/user.ts
import { pgTable, text, varchar } from "drizzle-orm/pg-core";
export const users = pgTable("user", {
id: varchar("id", { length: 255 }).primaryKey(),
locale: varchar("locale", { length: 10 }).default("en"),
// ... andra fÀlt
});
AI SDK Integration
ĂversĂ€tt AI-svar "on the fly":
import { openai } from "@ai-sdk/openai";
import { generateText } from "ai";
import { useLingui } from "@lingui/react/macro";
export function useAIChat() {
const { i18n } = useLingui();
const chat = async (prompt: string) => {
const systemPrompt = i18n._(msg`You are a helpful AI assistant for acme.`);
return generateText({
model: openai("gpt-4"),
messages: [
{ role: "system", content: systemPrompt },
{ role: "user", content: prompt },
],
});
};
return { chat };
}
Best Practices vi lÀrt oss
1. AnvÀnd alltid makron
// â DĂ„ligt: Runtime-översĂ€ttning (extraheras ej)
const text = t("Hello world");
// â
Bra: Makro (extraheras vid byggtid)
const text = t`Hello world`;
2. Kontext Àr allt
LÀgg till kommentarer för översÀttare (eller AI:n):
// i18n: This appears in the pricing table header
<Trans>Monthly</Trans>
// i18n: Button to submit payment form
<button>{t`Subscribe Now`}</button>
Lingui extraherar dessa som anteckningar till översÀttaren.
3. Hantera plural korrekt
import { Plural } from "@lingui/react/macro";
<Plural
value={count}
one="# credit remaining"
other="# credits remaining"
/>
Olika sprÄk har olika regler för plural. Lingui hanterar det.
4. Datum/Nummer-formatering
AnvÀnd Intl API:er:
const date = new Intl.DateTimeFormat(locale, {
dateStyle: "long",
}).format(new Date());
const price = new Intl.NumberFormat(locale, {
style: "currency",
currency: "USD",
}).format(29.99);
5. RTL-stöd
För arabiska, hantera textriktning:
export default function RootLayout({ children }) {
const locale = getLocale();
const direction = locale === "ar" ? "rtl" : "ltr";
return (
<html lang={locale} dir={direction}>
<body>{children}</body>
</html>
);
}
LĂ€gg till i Tailwind config:
module.exports = {
plugins: [
require('tailwindcss-rtl'),
],
};
AnvÀnd riktningsklasser:
<div className="ms-4"> {/* margin-start, fungerar för bÄde LTR/RTL */}
Checklista för deployment
Innan du skeppar:
- Kör
pnpm i18nför att sÀkerstÀlla att alla översÀttningar Àr uppdaterade - Testa varje sprÄk i produktionslÀge
- Verifiera att sprÄk-cookien sparas korrekt
- Kolla RTL-layout för arabiska
- Testa UX för sprÄkvÀljaren
- LÀgg till hreflang-taggar för SEO
- SÀtt upp sprÄkbaserad routing om det behövs
- Ăvervaka kostnader för LLM-översĂ€ttning
Resultatet
Efter att ha implementerat detta system:
- 17 sprÄk stöds direkt ur lÄdan
- ~850 strÀngar översatta automatiskt
- $2-3 total kostnad för fullstÀndig översÀttning
- 2 minuters uppdateringscykel nÀr nya strÀngar lÀggs till
- Noll manuellt översÀttningsarbete
- Kontextmedvetna översÀttningar av hög kvalitet
JÀmför det med:
- MÀnskliga översÀttare: $0.10-0.30 per ord = $1,000+
- Traditionella tjÀnster: Fortfarande dyrt, fortfarande lÄngsamt
- Manuellt arbete: Skalar inte
Varför detta spelar roll 2026
Hörni, webben Àr global. Om du bara skeppar pÄ engelska Är 2026 lÀmnar du 90% av vÀrlden utanför.
Men traditionell i18n Àr smÀrtsamt. Det hÀr tillvÀgagÄngssÀttet gör det busenkelt:
- Skriv kod med Trans/t-makron (tar 2 sekunder)
- Kör
pnpm i18n(automatiserat) - Skeppa till vÀrlden (profit)
Kombinationen av Linguis utvecklarupplevelse + LLM-drivna översÀttningar Àr en game-changer. Du fÄr:
- TypsÀkra översÀttningar
- Noll overhead vid runtime
- Automatisk extrahering
- Kontextmedvetna AI-översÀttningar
- SmÄpengar per sprÄk
- Skalar oÀndligt
GÄ steget lÀngre
Vill du levla upp? Prova:
Dynamisk innehÄllsöversÀttning
Spara översÀttningar i din databas:
// packages/db/schema/content.ts
export const blogPosts = pgTable("blog_post", {
id: varchar("id", { length: 255 }).primaryKey(),
titleEn: text("title_en"),
titleZhCn: text("title_zh_cn"),
titleJa: text("title_ja"),
// ... osv
});
Auto-översÀtt nÀr du sparar:
import { translateWithLLM } from "@acme/i18n";
export const blogRouter = createTRPCRouter({
create: protectedProcedure
.input(z.object({ title: z.string() }))
.mutation(async ({ input }) => {
// ĂversĂ€tt till alla sprĂ„k
const translations = await Promise.all(
LOCALES.map(async (locale) => {
const result = await translateWithLLM(
[{ msgid: input.title, msgstr: "" }],
locale
);
return [locale, result[0].msgstr];
})
);
await db.insert(blogPosts).values({
id: generateId(),
titleEn: input.title,
...Object.fromEntries(translations),
});
}),
});
AnvÀndarbidragna översÀttningar
LÄt anvÀndare skicka in bÀttre översÀttningar:
export const i18nRouter = createTRPCRouter({
suggestTranslation: publicProcedure
.input(z.object({
msgid: z.string(),
locale: z.string(),
suggestion: z.string(),
}))
.mutation(async ({ input }) => {
await db.insert(translationSuggestions).values(input);
// Meddela maintainers
await sendEmail({
to: "i18n@acme.com",
subject: `New translation suggestion for ${input.locale}`,
body: `"${input.msgid}" â "${input.suggestion}"`,
});
}),
});
A/B-testning av översÀttningar
Testa vilka översÀttningar som konverterar bÀst:
const variant = await abTest.getVariant("pricing-cta", locale);
const ctaText = variant === "A"
? t`Start Your Free Trial`
: t`Try acme Free`;
Koden
Allt detta Àr produktionskod frÄn en riktig app. Hela implementationen finns i vÄrt monorepo:
t3-acme-app/
âââ apps/nextjs/
â âââ lingui.config.ts
â âââ src/
â â âââ locales/ # Kompilerade kataloger
â â âââ utils/i18n/ # i18n-verktyg
â â âââ providers/ # LinguiClientProvider
â âââ script/i18n.ts # ĂversĂ€ttningsskript
âââ packages/i18n/
âââ src/
âââ translateWithLLM.ts
âââ enhanceTranslations.ts
âââ utils.ts
Slutord
Att bygga en flersprÄkig AI-app Är 2026 Àr inte svÄrt lÀngre. Verktygen finns hÀr:
- Lingui för extrahering och runtime
- Claude/GPT för kontextmedveten översÀttning
- T3 Turbo för bÀsta DX i gamet
Sluta betala tusentals dollar för översÀttningar. Sluta begrÀnsa din app till engelska.
Bygg globalt. Skeppa snabbt. AnvÀnd AI.
SÄ gör vi Är 2026.
FrÄgor? Problem? Hitta mig pÄ Twitter eller kolla in Lingui-dokumentationen och AI SDK-dokumentationen.
GÄ nu och skeppa den dÀr flersprÄkiga appen. VÀrlden vÀntar.
Dela detta

Feng Liu
shenjian8628@gmail.com