> So richtet man Nuxt i18n ein, damit Suchmaschinen jede Sprache indexieren: Routing-Strategie, useLocaleHead, hreflang-Regeln, Teilübersetzungen, Sitemaps.
>
> Web page: https://balazscsorba.com/de/blog/nuxt-i18n-multilingual-seo-hreflang · Language: Deutsch · Also available in: [English](https://balazscsorba.com/blog/nuxt-i18n-multilingual-seo-hreflang.md) · [Magyar](https://balazscsorba.com/hu/blog/nuxt-i18n-multilingual-seo-hreflang.md)
> Author: Balázs Csorba · Published: 2026-10-16 · Keywords: nuxt i18n seo, nuxt hreflang, useLocaleHead, nuxt i18n canonical, hreflang x-default, prefix_except_default, multilingual seo nuxt, nuxt i18n sitemap hreflang, hreflang self-referencing, nuxt i18n baseUrl

[Blog](https://balazscsorba.com/de/blog)/Web-Engineering

# Mehrsprachiges SEO mit Nuxt i18n: URL-Strategie, hreflang, Canonicals und Sitemaps

So richtet man Nuxt i18n ein, damit Suchmaschinen jede Sprache indexieren: Routing-Strategie, useLocaleHead, hreflang-Regeln, Teilübersetzungen, Sitemaps.

[Balázs Csorba](https://balazscsorba.com/de/about)·16\. Oktober 2026·8 Min. Lesezeit

-   Nuxt
-   i18n
-   SEO
-   hreflang
-   Multilingual

![Drei Sprachversionen einer Seite, Englisch, Deutsch und Ungarisch, mit hreflang-Pfeilen untereinander verknüpft und einem x-default-Fallback.](https://balazscsorba.com/images/blog/nuxt-i18n-multilingual-seo-hreflang/cover.webp?v=d362e3eb5b)

## Das Wichtigste in Kürze

-   Jeder Sprache eine eigene URL geben; Google empfiehlt das statt Cookies oder Browsereinstellungen, und der Googlebot sendet keinen Accept-Language-Header.
-   In @nuxtjs/i18n bei jeder Locale language und eine produktive baseUrl setzen, dann liefert useLocaleHead lang-, hreflang-, og:locale- und Canonical-Tags.
-   hreflang-Sätze müssen auf jeder Version identisch sein, die Seite selbst enthalten, vollständige URLs und gültige ISO-Sprachcodes nutzen.
-   Bei Seiten in weniger Sprachen nur die echten Übersetzungen listen und den Canonical unübersetzter Kopien aufs Original zeigen lassen.
-   Nicht nach Browsersprache umleiten; einen Sprachumschalter mit echten Links anbieten und hreflang die Suchenden zur richtigen Version schicken lassen.

Auf dieser Seite

1.  [Welche URL-Strategie sollte eine mehrsprachige Nuxt-Seite nutzen?](https://balazscsorba.com/#url-strategy)
2.  [Wie konfiguriert man @nuxtjs/i18n fürs SEO?](https://balazscsorba.com/#configure-nuxt-i18n)
3.  [Was schreibt useLocaleHead in den Head der Seite?](https://balazscsorba.com/#use-locale-head)
4.  [Welche hreflang-Regeln werden oft falsch umgesetzt?](https://balazscsorba.com/#hreflang-rules)
5.  [Was ist mit Seiten, die nur in manchen Sprachen existieren?](https://balazscsorba.com/#partial-translations)
6.  [Gehört hreflang auch in die Sitemap?](https://balazscsorba.com/#sitemaps)
7.  [Warum nicht nach Browsersprache weiterleiten?](https://balazscsorba.com/#no-automatic-redirects)
8.  [Was muss für mehrsprachiges SEO noch übersetzt werden?](https://balazscsorba.com/#beyond-the-head)
9.  [Wie prüft man das Setup?](https://balazscsorba.com/#test-it)
10.  [Quellen](https://balazscsorba.com/#sources)

Diesen Artikel anhören

0:000:00

Eine mehrsprachige Nuxt-Seite kann für Besucher perfekt aussehen und für Suchmaschinen trotzdem halb unsichtbar sein: Die deutschen Seiten werden nicht indexiert, Google zeigt ungarischen Suchenden die englische Seite, oder zwei Sprachversionen konkurrieren um dieselbe Suchanfrage. Fast immer liegt die Ursache im Head der Seite: fehlende oder widersprüchliche hreflang-Links, ein Canonical auf die falsche Sprache oder eine URL-Strategie, die Sprachen hinter einem Cookie versteckt.

Dieser Artikel zeigt ein Setup mit @nuxtjs/i18n, das Suchmaschinen verstehen, am Beispiel dieser Website, die statisch auf Englisch, Deutsch und Ungarisch generiert wird. Es geht um die Routing-Strategie, useLocaleHead, die hreflang-Regeln aus Googles Dokumentation, Seiten, die nur in manchen Sprachen existieren, Sitemaps und warum automatische Sprachweiterleitungen schaden.

## Welche URL-Strategie sollte eine mehrsprachige Nuxt-Seite nutzen?

Googles Empfehlung für [mehrsprachige Websites](https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites) ist eindeutig: für jede Sprachversion eigene URLs statt Cookies oder Browsereinstellungen. Wechselt der Inhalt auf einer URL je nach Sprache, findet Google womöglich nicht alle Varianten, denn der Googlebot crawlt meist aus den USA und sendet Anfragen ohne Accept-Language-Header. Nuxt i18n bietet vier [Routing-Strategien](https://i18n.nuxtjs.org/docs/guide):

Strategie

URLs

SEO-Urteil

`prefix_except_default`

/blog, /de/blog, /hu/blog

Guter Standard; die Hauptsprache behält saubere URLs

`prefix`

/en/blog, /de/blog, /hu/blog

Gut; symmetrisch, braucht eine Weiterleitung oder Sprachauswahl an der Wurzel

`prefix_and_default`

/blog and /en/blog, /de/blog

Funktioniert, erzeugt aber Duplikate; der Canonical zeigt auf die URL ohne Präfix

`no_prefix`

/blog for all

Für öffentliche Inhalte meiden; eine URL wird nur in einer Sprache indexiert

Unterverzeichnisse auf einer Domain sind auch im Betrieb die günstigste Option. Eigene Länderdomains lohnen sich, wenn das Geschäft pro Land wirklich getrennt ist; für eine zweite Sprache braucht man sie nicht.

## Wie konfiguriert man @nuxtjs/i18n fürs SEO?

Zwei Einstellungen sind nötig, damit die [SEO-Funktionen](https://i18n.nuxtjs.org/docs/guide/seo) korrekte Ausgaben liefern: Jede Locale braucht ein `language`\-Tag, das zum `hreflang`\-Wert und zum `<html lang>` wird, und `baseUrl` muss der produktive Origin sein, denn hreflang- und Canonical-URLs müssen vollständig sein. So sieht die Konfiguration dieser Website aus:

```
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n'],
  i18n: {
    baseUrl: 'https://balazscsorba.com',
    strategy: 'prefix_except_default',
    defaultLocale: 'en',
    locales: [
      { code: 'en', language: 'en-US', name: 'English', file: 'en.json' },
      { code: 'de', language: 'de-AT', name: 'Deutsch', file: 'de.json' },
      { code: 'hu', language: 'hu-HU', name: 'Magyar', file: 'hu.json' },
    ],
    // No automatic redirect by browser language; the switcher links to every version.
    detectBrowserLanguage: false,
  },
})
```

## Was schreibt useLocaleHead in den Head der Seite?

`useLocaleHead()` liefert Head-Metadaten, die man an `useHead` übergibt: das `lang`\-Attribut für `<html>`, einen Alternate-Link mit `hreflang` für jede konfigurierte Locale, `og:locale`\- und `og:locale:alternate`\-Meta-Tags und einen Canonical-Link. Einmal in `app.vue` aufrufen, dann bekommt es jede Seite.

```
<!-- app.vue -->
<script setup lang="ts">
const i18nHead = useLocaleHead({ dir: true, seo: true })

useHead(() => ({
  htmlAttrs: { lang: i18nHead.value.htmlAttrs?.lang },
  link: [...(i18nHead.value.link ?? [])],
  meta: [...(i18nHead.value.meta ?? [])],
}))
</script>
```

Für eine Seite unter `/de/blog/post` enthält der gerenderte Head dann `<html lang="de-AT">`, einen Canonical-Link auf die deutsche URL und Alternate-Links für `en-US`, `de-AT` und `hu-HU`. Das Modul ergänzt außerdem einen Catch-all-Link pro Sprachgruppe, etwa `hreflang="en"`, und ein `x-default`. Das generierte HTML einmal pro Seitentyp prüfen; man nimmt leicht an, der Head stimme, nur weil das Modul installiert ist.

## Welche hreflang-Regeln werden oft falsch umgesetzt?

hreflang funktioniert nur als geschlossener Satz: Verlinkt die deutsche Seite nicht zurück, ignoriert Google das Paar womöglich.

Googles [hreflang-Dokumentation](https://developers.google.com/search/docs/specialty/international/localized-versions) ist kurz, und die meisten Fehler, die ich in Audits finde, verletzen eine dieser Regeln:

-   **Die Seite selbst einschließen.** Jede Version listet einen Link pro Variante, sich selbst eingeschlossen, und der Satz ist auf jeder Version identisch.
-   **Vollständige URLs verwenden,** mit Protokoll und Host. Relative hrefs sind meist die Folge einer fehlenden `baseUrl`.
-   **Gültige Codes nutzen:** eine Sprache nach ISO 639-1, optional gefolgt von einer Region nach ISO 3166-1 (`de-AT`). Eine Region allein funktioniert nicht, und Codes wie `es-419` werden nicht unterstützt.
-   **`x-default` ergänzen** für Nutzer, deren Sprache zu keiner Version passt, meist die Seite in der Standardsprache.
-   **Den Canonical selbstreferenzierend setzen** auf jeder Sprachversion. Eine deutsche Seite, deren Canonical auf die englische zeigt, sagt Google, die deutsche fallen zu lassen.

Noch ein wichtiger Punkt: Google sagt, dass es weder hreflang noch das `lang`\-Attribut zur Spracherkennung nutzt, sondern die Sprache aus dem Inhalt erkennt. Ein übersetztes Template mit unübersetztem Fließtext bleibt eine englische Seite.

## Was ist mit Seiten, die nur in manchen Sprachen existieren?

Mit `prefix_except_default` erzeugt Nuxt für jede Locale eine Route, ein rein englischer Artikel wird also auch unter `/de/blog/post` mit deutscher Navigation und englischem Text gerendert. Ohne Eingriff bewirbt useLocaleHead ihn als deutsche Übersetzung, und der Canonical der deutschen Kopie zeigt auf sich selbst. Diese Website behebt beides in `app.vue`: Eine Seite, die in weniger Sprachen existiert, meldet diese an, hreflang listet dann nur sie, und unübersetzte Kopien setzen ihren Canonical aufs englische Original.

```
// app.vue (excerpt): pageLocales is set by pages that exist in fewer languages
const headLinks = computed(() => {
  const links = i18nHead.value.link ?? []
  const only = pageLocales.value
  if (!only || only.path !== route.path) return links
  return links
    .filter((l) => l.rel !== 'alternate' || !l.hreflang || l.hreflang === 'x-default'
      || only.locales.some((c) => l.hreflang.startsWith(c)))
    .map((l) => (l.rel === 'canonical' && !only.translated
      ? { ...l, href: `${siteUrl}${switchLocalePath('en')}` }
      : l))
})
```

Die Alternative ist, unübersetzte Routen gar nicht zu erzeugen und einen 404 oder eine Weiterleitung aufs Original zu liefern. Das ist für Suchmaschinen sauberer, aber schlechter für Besucher, die die Oberfläche auf Deutsch gestellt haben und dabei bleiben wollen. Beides funktioniert, solange der Head die Wahrheit darüber sagt, welche Übersetzungen existieren.

## Gehört hreflang auch in die Sitemap?

Google akzeptiert hreflang an drei Stellen, in HTML-Tags, HTTP-Headern und der Sitemap, behandelt sie als gleichwertig und sagt, mehrere davon brächten in der Suche keinen Vorteil, erschwerten aber die Pflege. HTTP-Header sind vor allem für Nicht-HTML-Dateien wie PDFs nützlich. Diese Website gibt Head-Tags und Sitemap-Einträge aus, weil beide beim Build aus denselben Beitragsdaten erzeugt werden und so nicht auseinanderlaufen können. Kommen sie bei dir aus verschiedenen Codepfaden, eine Variante wählen.

```
<url>
  <loc>https://balazscsorba.com/de/blog/agent-loop-explained</loc>
  <xhtml:link rel="alternate" hreflang="en" href="https://balazscsorba.com/blog/agent-loop-explained"/>
  <xhtml:link rel="alternate" hreflang="de" href="https://balazscsorba.com/de/blog/agent-loop-explained"/>
  <xhtml:link rel="alternate" hreflang="hu" href="https://balazscsorba.com/hu/blog/agent-loop-explained"/>
  <xhtml:link rel="alternate" hreflang="x-default" href="https://balazscsorba.com/blog/agent-loop-explained"/>
</url>
```

## Warum nicht nach Browsersprache weiterleiten?

Google rät davon ab, Nutzer anhand der vermuteten Sprache auf eine Sprachversion umzuleiten, weil das Nutzer und Suchmaschinen daran hindern kann, alle Versionen zu erreichen. `detectBrowserLanguage` von Nuxt i18n kann beim ersten Besuch umleiten; bei einer öffentlichen Website schalte ich es ab und setze stattdessen auf zwei Dinge: hreflang, das Suchende direkt aus der Ergebnisseite zur richtigen Version schickt, und einen Sprachumschalter aus echten Links, dem auch Crawler folgen können.

**Eine bewusste Wahl merken, keine Vermutung**

Die im Umschalter gewählte Sprache in einem Cookie zu speichern ist in Ordnung; das spiegelt eine Entscheidung. Eine Weiterleitung anhand des Accept-Language-Headers ist eine Vermutung, und der Googlebot sendet diesen Header gar nicht.

## Was muss für mehrsprachiges SEO noch übersetzt werden?

-   **Titel und Meta-Descriptions pro Locale.** Sie sind das, was Suchende in den Ergebnissen lesen; eine deutsche Seite mit englischem Titel verliert Klicks.
-   **Strukturierte Daten mit `inLanguage`**, passend zur Seite, damit KI-Suche und Rich Results die richtige Version zitieren. Mehr dazu im [GEO-Audit dieser Website](https://balazscsorba.com/de/blog/generative-engine-optimization-audit).
-   **Alt-Texte und Open-Graph-Bilder** mit lokalisiertem Text, wenn das Bild Wörter enthält.
-   **Interne Links, die in der Sprache bleiben.** Überall `localePath()` verwenden, damit ein deutscher Artikel auf deutsche Seiten verlinkt und Besucher nicht ins Englische abfließen.

Performance zählt in jeder Sprache gleich; es gelten dieselben Regeln wie in [Core Web Vitals für Nuxt](https://balazscsorba.com/de/blog/nuxt-core-web-vitals-performance), und Lazy Loading der Nachrichtendateien pro Locale hält das Bundle klein.

## Wie prüft man das Setup?

Das generierte HTML einer Seite pro Typ und Sprache abrufen und die Link-Sätze vergleichen; ein kurzes Skript findet die üblichen Fehler, bevor die Search Console es Wochen später tut.

```
// check-hreflang.mjs: every version must list the same set, including itself
const pages = ['/blog/agent-loop-explained', '/de/blog/agent-loop-explained', '/hu/blog/agent-loop-explained']
const base = 'https://balazscsorba.com'
const sets = await Promise.all(pages.map(async (p) => {
  const html = await (await fetch(base + p)).text()
  const attr = (tag, name) => tag.match(new RegExp(` ${name}="([^"]+)"`))?.[1]
  const tags = html.match(/<link[^>]*>/g) ?? []
  const links = tags.filter((t) => attr(t, 'rel') === 'alternate' && attr(t, 'hreflang'))
    .map((t) => [attr(t, 'hreflang'), attr(t, 'href')])
  const canonical = attr(tags.find((t) => attr(t, 'rel') === 'canonical') ?? '', 'href')
  if (canonical !== base + p) console.warn(`${p}: canonical is ${canonical}`)
  if (!links.some(([, href]) => href === base + p)) console.warn(`${p}: does not list itself`)
  return links.map(([lang, href]) => `${lang} ${href}`).sort().join('\n')
}))
console.log(new Set(sets).size === 1 ? 'hreflang sets match' : 'hreflang sets differ')
```

## Quellen

1.  [Nuxt i18n docs: SEO (useLocaleHead)](https://i18n.nuxtjs.org/docs/guide/seo)
2.  [Nuxt i18n docs: Routing strategies](https://i18n.nuxtjs.org/docs/guide)
3.  [Google Search Central: Tell Google about localized versions of your page](https://developers.google.com/search/docs/specialty/international/localized-versions)
4.  [Google Search Central: Managing multi-regional and multilingual sites](https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites)
5.  [Google Search Central: How to specify a canonical URL](https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls)

## Häufige Fragen

Welche Routing-Strategie von Nuxt i18n ist die beste fürs SEO?

prefix\_except\_default und prefix geben jeder Sprache eine eigene URL, wie Google es empfiehlt. prefix\_except\_default lässt die Standardsprache ohne Präfix. no\_prefix für öffentliche Inhalte meiden, denn alle Sprachen teilen sich eine URL und Suchmaschinen können nur eine davon indexieren.

Erzeugt useLocaleHead hreflang automatisch?

Ja. Es liefert das lang-Attribut des html-Elements, einen Alternate-Link mit hreflang für jede konfigurierte Locale, og:locale-Tags und einen Canonical-Link. Dafür braucht jede Locale einen language-Wert und das Modul eine baseUrl, damit die URLs vollständig sind.

Brauche ich x-default?

Es wird empfohlen. Google nutzt x-default für Nutzer, deren Sprache zu keiner Version passt. Meist zeigt es auf die Version in der Standardsprache oder auf eine Sprachauswahlseite.

Gehört hreflang in den HTML-Head oder in die Sitemap?

Beides geht. Google behandelt HTML-Tags, HTTP-Header und Sitemap-Einträge als gleichwertig und sagt, dass mehrere davon keinen Zusatznutzen bringen. Die Variante wählen, die man korrekt halten kann; bei statischen Seiten aus einer Datenquelle können beide aus demselben Code kommen.

Nutzt Google hreflang, um die Sprache einer Seite zu erkennen?

Nein. Laut Google wird die Sprache mit eigenen Algorithmen aus dem Inhalt erkannt; hreflang sagt nur, welche URLs lokalisierte Versionen derselben Seite sind. Eine deutsche Seite voller englischem Text ist für Google trotzdem englisch.

Geschrieben von Balázs Csorba

Senior Fullstack & AI Engineer in der Steiermark – über 10 Jahre Vue, Nuxt, Node.js und PHP, heute baue ich Werkzeuge für KI-Agenten.

[Vue.js- & Nuxt-Entwicklung →](https://balazscsorba.com/de/expertise/vue-nuxt-developer)[Über mich →](https://balazscsorba.com/de/about)

## Weitere Artikel

-   [Denial of Wallet: öffentliche LLM-Endpunkte in einer Nuxt-App absichern](https://balazscsorba.com/de/blog/llm-endpoint-abuse-denial-of-wallet)
-   [llms.txt versus Markdown Content Negotiation: was Agenten wirklich abrufen](https://balazscsorba.com/de/blog/llms-txt-vs-markdown-content-negotiation)
-   [Ein 3D-Segelspiel mit Multiplayer in reinem three.js](https://balazscsorba.com/de/blog/multiplayer-sailing-game-threejs)
-   [Laden nach EPEX-Preisen in Österreich: was meine Home-Assistant-App spart](https://balazscsorba.com/de/blog/home-assistant-ev-charging-energy-manager)

## Klingt nach dem, was du suchst?

Erzähl mir von deinem Projekt oder deiner Stelle – ich freue mich, von dir zu hören.

[Kontakt aufnehmen](mailto:contact@balazscsorba.com) [Auf LinkedIn vernetzen](https://www.linkedin.com/in/balazs-csorba)
