Frida Marketing
WebbutvecklingNext.js-utveckling

Hur man bygger en 10-språkig Next.js-webbplats (App Router-guide 2026)

1 juni 2026
11 min läsning

Återställningsstub — innehåll återställt från CMS-inlägg ID 81.

Jinsi ya Kujenga Tovuti ya Next.js ya Lugha 10 (Mwongozo wa App Router 2026)

Att bygga en flerspråkig webbplats är en av de mest lönsamma investeringarna du kan göra inom SEO och konvertering. Sjuttiofem procent av online-shoppare föredrar att köpa produkter med information på sitt modersmål (CSA Research, 2020), men färre än 5% av aktiva webbplatser stöder fler än tre språk. Vi lanserade nyligen Frida Marketing på 10 språk med Next.js 15 App Router — utan next-intl, utan en översättnings-SaaS och utan 10 separata kodbaser. Här är exakt hur vi byggde det.

Viktiga insikter

  • 76% av shoppare föredrar att köpa på sitt modersmål; 40% kommer aldrig att köpa från webbplatser som inte erbjuder det (CSA Research, 2020)
  • Engelska täcker bara 49,7% av globalt webbinnehåll — att bygga flerspråkigt låser upp de andra 50,3% (W3Techs, juni 2026)
  • Ett dynamiskt [lang]-segment + en API-prefixberäkning hanterar 10 språk från en enda uppsättning sidfiler
  • Gemini 2.5 Flash översätter ett komplett HTML-inlägg på 3 000 ord per språk på under 90 sekunder till nästan noll kostnad

Varför det är billigare än du tror att bygga flerspråkigt

Kostnadsargumentet mot flerspråkiga webbplatser är nästan alltid överdrivet. Next.js 15 App Router hanterar hela routningslagret via ett enda dynamiskt segment. Innehållslagret — titlar, brödtext, metadata — kommer från ditt API per språk. Och översättningslagret kan automatiseras helt.

Engelska representerar 49,7% av allt webbplatsinnehåll per språk. Spanska och tyska har vardera 6,0%, japanska 5,0% och franska 4,6% (W3Techs, juni 2026). Att stödja de fem största icke-engelska språken ensamt täcker ungefär 70% av indexerat globalt webbinnehåll. Next.js körs på 2,7% av alla webbplatser globalt och 17,9% av tillfrågade utvecklare använder det (Stack Overflow Developer Survey, 2024) — vilket innebär att verktygen och community-stödet för flerspråkigt Next.js är bättre än någonsin.

Den verkliga kostnaden är inte kod — det är innehåll. När din routning är på plats är det en API-anrop per publicerat inlägg att lägga till ett språk. Vi har publicerat 7 inlägg på 10 språk med noll underhållskostnader per språk. Arkitekturbeslutet är investeringen; körtiden är gratis.

Web content language distribution bar chart showing English at 49.7%, Spanish and German at 6.0% each, Japanese 5.0%, French 4.6%, all other 28.7%
Källa: W3Techs, juni 2026

96% av företag som investerade i lokalisering rapporterade positiv ROI, med 65% som uppnådde minst 3x avkastning (DeepL Business Survey, 2024). Affärsfallet är solitt. Den tekniska barriären är mycket lägre än de flesta utvecklare förväntar sig.

Hur du strukturerar ditt dynamiska [lang]-segment

Next.js App Router förvandlar ditt filsystem till din router. Skapa en src/app/[lang]/-katalog och varje rutt inuti den får params.lang automatiskt. Den enda parametern är hela grunden för en webbplats med 10 språk.

`` src/app/ ├── page.tsx ← English homepage (/) ├── blog/[slug]/page.tsx ← English blog posts ├── admin/layout.tsx ← English admin └── [lang]/ ├── page.tsx ← All other language homepages (/fi, /fr, /de…) ├── blog/[slug]/page.tsx ← Language blog posts └── admin/ └── layout.tsx ← Language admin (same file, reads params.lang) ``

Engelska finns i roten. Alla andra språk finns under [lang]. Du skriver en fil och låter params.lang styra logiken — inga språkspecifika sidkopior någonsin.

Definiera din språkkonfiguration i en kanonisk fil:

```typescript // src/lib/languages.ts export const LANGUAGES = [ { code: 'fi', urlPrefix: 'fi', apiPrefix: 'fi_', name: 'Finnish' }, { code: 'fr', urlPrefix: 'fr', apiPrefix: 'fr_', name: 'French' }, { code: 'de', urlPrefix: 'de', apiPrefix: 'de_', name: 'German' }, { code: 'it', urlPrefix: 'it', apiPrefix: 'it_', name: 'Italian' }, { code: 'no', urlPrefix: 'no', apiPrefix: 'no_', name: 'Norwegian' }, { code: 'ch', urlPrefix: 'ch', apiPrefix: 'pt_', name: 'Swiss German' }, // ⚠️ API uses pt_ { code: 'sr', urlPrefix: 'sr', apiPrefix: 'sr_', name: 'Serbian' }, { code: 'es', urlPrefix: 'es', apiPrefix: 'es_', name: 'Spanish' }, { code: 'sw', urlPrefix: 'sv', apiPrefix: 'sw_', name: 'Swedish' }, // ⚠️ URL uses sv ];

export const LANG_CODES = LANGUAGES.map(l => l.code); ```

Två egenheter att omedelbart dokumentera: ch (schweizertyska) använder pt_ som sitt API-prefix av historiska namnskäl, och sw (svenska) använder sv som sitt URL-prefix för att matcha ISO-standarden. Dessa avvikelser kommer inte att orsaka buggar om du centraliserar konfigurationen, men de kommer att förvirra varje utvecklare som ansluter sig till projektet utan denna dokumentation.

Ansluta språkroutar till ditt backend-API

Hela flerspråks-API-integrationen är en beräkning:

``typescript const prefix = params.lang ? ${params.lang}_ : ''; const posts = await fetch(${API_URL}/api/${prefix}posts); ``

När params.lang är 'fi', hämtas /api/fi_posts. När det är undefined (engelsk rot), hämtas /api/posts. Varje sida, varje dataanrop, varje administrativ operation använder samma mönster. Det finns ingen per-språk-hämtningshjälpare, ingen switch-sats, inget specialfall.

Developer working at desk with dual monitors and sticky notes, warm home office lighting

Vi kör detta mönster över 10 språk och 5 innehållstyper — inlägg, produkter, sidor, författare och kategorier — i produktion. Det enda gränsfallet vi stötte på: vissa API-slutpunkter har olika strukturer för engelska jämfört med de språkspecifika versionerna. I vår installation finns /api/{lang}_posts/by-url/{slug} för varje språk, men den engelska motsvarigheten är en helt annan kontroller (/api/resolve-route?url=...). Kontrollera alltid dina engelska API-routar separat — de är ofta strukturerade annorlunda än de språkspecifika, särskilt på Laravel-backends där de engelska routarna byggdes först.

Adminpanelen använder samma prefixmönster:

``typescript // src/app/[lang]/admin/posts/page.tsx export default function AdminPostsPage({ params }: { params: { lang?: string } }) { const prefix = params.lang ? ${params.lang}_ : ''; // Fetch from /api/${prefix}posts // Build edit/delete links with /${params.lang}/admin/edit-post/${id} } ``

En enda AdminPostsPage-komponent hanterar alla 10 språkens adminpaneler. Den engelska admin finns på /admin/posts; finska finns på /fi/admin/posts. Samma fil.

Generera statiska sidor för alla 10 språk

Statisk generering är där flerspråkiga Next.js-webbplatser får sin prestandafördel. Använd generateStaticParams för att förrenderera varje språkvariant vid byggtid:

```typescript // src/app/[lang]/page.tsx — static language homepages export async function generateStaticParams() { return LANG_CODES.map(lang => ({ lang })); // Returns: [{lang:'fi'},{lang:'fr'},{lang:'de'},...] }

// src/app/[lang]/blog/[slug]/page.tsx — static blog posts per language export async function generateStaticParams({ params }: { params: { lang: string } }) { const prefix = params.lang ? ${params.lang}_ : ''; const res = await fetch(${API_URL}/api/${prefix}posts); const data = await res.json(); return data.data.map((post: { url: string }) => ({ slug: post.url })); } ```

Statiska sidor visas som i next build-utdata. De förrenderas till HTML vid driftsättning, skjuts ut till Vercels edge CDN och laddas på millisekunder globalt. För en webbplats med 10 språk är detta skillnaden mellan en 50ms TTFB och en 800ms origin-träff vid varje begäran.

En regel att komma ihåg: kombinera aldrig generateStaticParams med { cache: 'no-store' }-hämtningar på samma sida. I Next.js 15 produktionsbyggen kastar detta Error: Page changed from static to dynamic at runtime — en bugg som bara uppstår i produktion, inte i utveckling. Använd ISR istället:

``typescript const res = await fetch(${API_URL}/api/${prefix}posts, { next: { revalidate: 3600 }, // Regenerate stale pages every hour }); export const dynamicParams = true; // Allow new slugs without a full rebuild ``

Bar chart comparing weekly npm downloads: next-intl 2.3 million, next-i18next 538 thousand, react-intl 400 thousand
Källa: npm-registret, juni 2026

next-intl har 2,3 miljoner nedladdningar per vecka från npm i juni 2026, vilket gör det till det dominerande biblioteket inom området. Det är rätt val om du behöver lokaliseringsanpassad formatering eller hantering av hårdkodade UI-strängar. För datadrivna CMS-webbplatser är det valfritt — ren App Router-routning hanterar allt du faktiskt behöver.

SEO för en webbplats med 10 språk: Hreflang och generateMetadata

Hreflang berättar för Google vilken språkversion som ska visas för vilken publik. Utan det konkurrerar dina 10 språksidor mot varandra om samma sökfrågor. App Router-implementeringen är ren:

```typescript // src/lib/hreflang.ts const HREFLANG_CODE: Record = { fi: 'fi', fr: 'fr', de: 'de', it: 'it', no: 'no', ch: 'de-CH', // Swiss German internal code → BCP 47 de-CH sr: 'sr', es: 'es', sw: 'sv', // Internal code sw → ISO sv (Swedish) };

export function getAlternates(routeKey: string, lang?: string) { const BASE = 'https://fridamarketing.com'; const enUrl = ${BASE}/${routeKey};

const languages: Record = { 'x-default': enUrl, en: enUrl, };

for (const [code, hreflang] of Object.entries(HREFLANG_CODE)) { const urlPrefix = code === 'sw' ? 'sv' : code; languages[hreflang] = ${BASE}/${urlPrefix}/${routeKey}; }

return { canonical: lang ? ${BASE}/${lang === 'sw' ? 'sv' : lang}/${routeKey} : enUrl, languages, }; } ```

Använd det i generateMetadata på varje sida:

``typescript export async function generateMetadata({ params }: Props): Promise { const post = await fetchPost(params.lang, params.slug); return { title: post.meta_title, description: post.meta_description, alternates: getAlternates(blog/${post.url}, params.lang), }; } ``

Detta genererar en komplett hreflang-uppsättning för varje sida — x-default, en och alla 9 språkvarianter — med noll manuellt underhåll. Inga XML-sitemap hreflang-block att hålla synkroniserade; Next.js injicerar dem som -taggar i den renderade .

Open notebook with hand-drawn site architecture diagram beside a laptop and coffee cup

Enligt flerspråkig SEO-forskning ser företag som investerar i lokalisering 300–500% mer organisk trafik från internationella marknader (MotionPoint, 2025). Hreflang-lagret är det som fångar den trafiken. Utan det ignorerar Google antingen språksignalerna eller visar fel version för varje lokalisering.

Automatisera översättning: Gemini API i din publiceringspipeline

Manuell översättning till 10 språk är fel modell för alla team utan en dedikerad lokaliseringsbudget. Mänsklig översättning kostar 0,15–0,30 USD per ord — ett inlägg på 2 500 ord kostar 375–750 USD per språk, eller 3 375–6 750 USD för alla 9 (Seatongue, 2025). Efterredigering av maskinöversättning minskar detta med 50–70%. Men för strukturerat HTML-innehåll från ett CMS är helt automatiserad API-översättning med en exakt prompt ännu bättre.

Här är det centrala översättningsanropet vi använder med Gemini 2.5 Flash:

``javascript async function translatePost(content, targetLang) { const prompt = Translate the following JSON to ${targetLang}. Rules: - Translate all text values: title, intro, body, meta_title, meta_description - Preserve ALL HTML tags, attributes, and structure in body exactly as-is - Generate a URL-safe localized slug and return it as "url" - Keep brand names, code examples, and proper nouns in English - Return valid JSON only: { title, intro, body, meta_title, meta_description, url }

Content: ${JSON.stringify(content)}`;

const response = await gemini.generateContent(prompt); return JSON.parse(response.text()); } ```

Vi har kört detta i produktion för 7 publicerade inlägg, var och en översatt till 9 språk automatiskt. Kvaliteten är redo för publicering för finska, franska, tyska, spanska och italienska utan manuell granskning. Norska och svenska behöver enstaka stickprovskontroller. Serbiska behöver en korrekturläsning — Gemini är mindre tillförlitlig med kyrilliska i komplexa HTML-sammanhang. För en innehållstung webbplats minskar denna metod översättningskostnaderna med över 90% jämfört med även efterredigering av maskinöversättning.

Tidpunkten är viktig. Ett HTML-inlägg på 3 000 ord tar Gemini 2.5 Flash cirka 60–90 sekunder per språk. Det är 9–13 minuter för alla 9 översättningar. Ställ alltid in en 150-sekunders avbrottstid på varje API-anrop och implementera exponentiell backoff — modellen kan ibland hänga sig vid hög efterfrågan:

``javascript const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 150000); try { const res = await fetch(GEMINI_URL, { signal: controller.signal, ...opts }); clearTimeout(timeoutId); return res; } catch (err) { clearTimeout(timeoutId); if (err.name === 'AbortError') { // Retry with exponential backoff await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 5000)); } } ``

Källa: CSA Research, 2020

84% av marknadsförare säger att innehållslokalisering har hjälpt till att öka deras intäkter, och företag som investerade i översättning var 1,5 gånger mer benägna att se en intäktsökning (Redokun, 2025). Automatiseringen tar bort det sista verkliga hindret — driftskostnaden för att hantera översättningar i stor skala.

---

Bygger du en flerspråkig Next.js-webbplats? Vi designar och bygger Next.js-webbplatser för globala publiker — full i18n-routning, hreflang SEO och automatiserade översättningspipelines ingår. Se våra Next.js utvecklingstjänster eller kontakta oss för att diskutera ditt projekt.

---

Vanliga frågor

Behöver jag next-intl för att bygga en flerspråkig Next.js-webbplats?

Nej. Next.js 15 App Router hanterar flerspråkig routning inbyggt via ett dynamiskt [lang]-segment. Bibliotek som next-intl tillför värde för lokaliseringsanpassad formatering (datum, valutor, pluralisering) och hantering av hårdkodade UI-strängar. Om ditt innehåll kommer från ett CMS eller API behöver du dem inte för routning, statisk generering eller SEO.

Hur kopplar jag URL-språkprefix till API-slutpunkter i Next.js?

Beräkna ett prefix vid körtid: const prefix = params.lang ? \`${params.lang}_\` : '';. Använd det i varje hämtningsanrop — till exempel, /api/${prefix}posts. Detta mönster hanterar alla 10 språk från en delad sidfil. Inga språkspecifika sidor, inga switch-satser, inga specialfall.

Vad är det bästa sättet att automatiskt översätta en Next.js-webbplats till flera språk?

Använd Gemini 2.5 Flash eller GPT-4 i din publiceringspipeline. Skicka det engelska innehållet som JSON med en systemprompt för att översätta alla textvärden samtidigt som HTML-taggar bevaras och en lokaliserad URL-slug genereras. Lägg till en 150-sekunders timeout och exponentiell backoff. Efterredigering av maskinöversättning kostar 50–70% mindre än full mänsklig översättning (Seatongue, 2025), och full API-automatisering minskar det ytterligare.

Hur lägger jag till hreflang-taggar på en Next.js 15 App Router-webbplats?

Bygg en getAlternates(routeKey, lang)-funktion som returnerar ett Next.js alternates-objekt. Mappa interna URL-koder till BCP 47-språkkoder — sw → sv för svenska, ch → de-CH för schweizertyska — och inkludera x-default som pekar på den engelska kanoniska. Returnera det från alternates.languages inuti varje sidas generateMetadata-export.

Hur många språk ska min webbplats stödja?

Börja med 2–3 som matchar dina främsta trafikkällor, expandera sedan. Engelska täcker endast 49,7% av globalt webbinnehåll (W3Techs, juni 2026), så ett andra språk öppnar en ny adresserbar publik med nästan noll marginalkostnad när din routning och översättningspipeline är på plats. Företag som investerar i lokalisering rapporterar 96% positiv ROI, med 65% som uppnår minst 3x avkastning (DeepL, 2024).

Slutsats

En Next.js-webbplats med 10 språk är inte 10 gånger arbetet. Det är ett dynamiskt [lang]-segment, en API-prefixberäkning, en hreflang-hjälpare och ett översättningsskript — multiplicerat över din publiceringspipeline. Vi byggde detta för Frida Marketing och det körs i produktion på 10 språk utan underhållskostnader per språk och utan prenumeration på en lokaliserings-SaaS.

Routingen är ett förmiddagsarbete. Hreflang är ett eftermiddagsarbete. Översättningspipelinen är ett helgprojekt. Och utdelningen — att nå de 50,3% av webben som inte är engelska — är permanent.

Börja med [lang]-segmentet idag. Lägg till hreflang denna vecka. Koppla upp Gemini översättnings-API denna månad.