Migration zu Next.js / Astro in Basel

Migration einer dreisprachigen Website aus Basel zu Astro oder Next.js: Sprach-URLs behalten, hreflang und Canonical nach Google-Regeln, Weiterleitungen pro Sprache und ein Übersetzungsablauf im neuen CMS. Erste schriftliche Schätzung kostenlos.

Migration zu Next.js / Astro

Website- & Anwendungsmigration in Basel

Ich migriere Websites von WordPress, Joomla, Drupal, Angular, Vue und anderen Technologien zu Astro und Next.js. Jede Migration plane ich so, dass SEO, Inhalte und Funktionen erhalten bleiben, und schalte in einem vereinbarten Zeitfenster um. Ich arbeite allein und habe langjährige Erfahrung mit älteren und modernen Stacks.

  • Mein wordpress.org-Konto besteht seit 2006.
  • Ich habe zum WordPress-Core in den Versionen 7.0 und 7.1 beigetragen.
  • Ich betreue 30 Plugins auf wordpress.org.
  • Ich organisiere WordCamps und trete dort als Speaker auf.
  • Ich war bei jedem WordCamp Europe von 2017 bis 2026 dabei.

Mein WordPress.org-Profil

Basel liegt dort, wo Kundschaft und Lieferketten die Landesgrenze ständig queren. Das Kantonsportal nennt für die Logistik den EuroAirport Basel-Mulhouse-Freiburg, den Schweizerischen Rheinhafen und die internationalen Bahnhöfe, daneben die Life Sciences, Finanzdienstleister und den Handel mit Firmen wie Coop und Manor. Eine Website mit Kundschaft auf beiden Seiten der Grenze braucht oft Deutsch, Französisch und Englisch. Nach Art. 70 der Bundesverfassung bestimmen die Kantone ihre Amtssprachen; Amtssprachen des Bundes sind Deutsch, Französisch und Italienisch. Diese Seite behandelt eine Frage, die nur mehrsprachige Websites haben: Wie migrieren Sie zu Astro oder Next.js, ohne dass die Sprachstruktur bricht, die Google heute für Ihre Seiten kennt? Ich bin Mariusz Szatkowski, ein einzelner Entwickler in Gdynia, und arbeite remote und schriftlich.

#Welche Sprach-URLs hat Ihre Website heute, und welche bleiben?

Am Anfang steht eine Tabelle: jede indexierte URL, ihre Sprache, ihre deutsche, französische und englische Entsprechung (oder keine). Quellen sind ein Crawl, die Sitemaps und der Export der Seiten aus der Search Console. Google empfiehlt, jede Sprachversion unter einer eigenen URL anzubieten und nicht über Cookies oder Browsereinstellungen umzuschalten. Der Grund steht in der Dokumentation: Googlebot kommt meist aus den USA und sendet keinen Accept-Language-Header, findet also nicht alle Varianten, wenn der Inhalt von der Anfrage abhängt.

Die Strukturen, die ich in alten Websites finde, behandle ich so:

Heutige StrukturWas Google dazu sagtMein Vorgehen
/de/, /fr/, /en/Unterverzeichnisse: einfach einzurichten, ein HostBleibt, wenn sie sauber ist
fr.beispiel.chSubdomain: erlaubt, Sprache und Land nicht aus der URL erkennbarBleibt, oder wird bewusst in Verzeichnisse umgezogen (eigener Umzug)
beispiel.frLänderdomain: klares Länder-Signal, aber an ein Land gebundenBleibt, wenn das Land gemeint ist
?lang=frVon Google nicht empfohlenWird auf Sprach-URLs umgestellt, mit 301
Nur Cookie oder BrowserspracheGooglebot findet nicht alle VariantenNeue Sprach-URLs, Altadresse bekommt ein Ziel

Die Regel dahinter: Eine URL, die heute rankt, ändere ich nur, wenn es einen Grund gibt, der den Umzug aufwiegt. Sprachordner wie /fr/ setzt Astro direkt um: Mit prefixDefaultLocale: true hat auch die Hauptsprache ein Präfix, und über locales mit path lässt sich ein Ordner wie /francais/ auf den Sprachcode fr abbilden, falls die alte Website so aufgebaut war. Lokalisierte Wörter im Pfad sind laut Google in Ordnung, wenn die URL UTF-8-kodiert ist.

#Wie wird das Routing in Astro und in Next.js aufgebaut?

In Astro entsteht jede Sprache als Ordner unter src/pages/, der Ordnername muss genau dem Eintrag in locales entsprechen. Eine Konfiguration für die bestehende Struktur mit Sprachpräfix und passender Sitemap sieht so aus:

// astro.config.mjs
import { defineConfig } from "astro/config";
import sitemap from "@astrojs/sitemap";

export default defineConfig({
  site: "https://www.beispiel.ch",
  i18n: {
    locales: ["de", "fr", "en"],
    defaultLocale: "de",
    routing: { prefixDefaultLocale: true },
  },
  integrations: [
    sitemap({
      i18n: {
        defaultLocale: "de",
        locales: { de: "de-CH", fr: "fr-CH", en: "en" },
      },
    }),
  ],
});

Die Sitemap-Integration schreibt dann für jede URL die xhtml:link-Einträge aller Sprachvarianten, wie sie Googles Sitemap-Methode verlangt. Fehlt eine Seite in einer Sprache, kann Astro über i18n.fallback eine Ersatzseite erzeugen, entweder als Weiterleitung oder als Rewrite mit dem Inhalt der Ersatzsprache. Für Suchmaschinen halte ich beides für heikel (mehr dazu im Abschnitt zu Canonical), und ich bevorzuge, die Seite in dieser Sprache nicht anzubieten.

In Next.js liegen alle Seiten unter app/[lang], ein proxy.js leitet Adressen ohne Sprachpräfix um, und generateStaticParams erzeugt die Sprachversionen statisch. Die Next.js-Dokumentation beschreibt die Umleitung nach Accept-Language als Beispiel. Ich verwende sie nur für die Startadresse und nie für Inhaltsseiten, aus dem Grund, den Google nennt: Automatische Umleitungen nach vermuteter Sprache können Nutzer und Suchmaschinen daran hindern, alle Versionen zu sehen. Details zum App Router stehen auf der Seite Next.js für Basel, die Astro-Seite ist Astro für Basel.

Dreiländerbrücke bei Huningue und Weil am Rhein, nahe dem Dreiländereck bei Basel

Foto: Taxiarchos228, CC BY 3.0, Wikimedia Commons.

#Welche hreflang-Regeln gelten für Deutsch, Französisch und Englisch?

Die Regeln stammen aus Googles Dokumentation zu lokalisierten Versionen:

  • Jede Sprachversion nennt sich selbst und alle anderen. Die Menge der Links ist auf jeder Version identisch.
  • Zeigt Seite X auf Seite Y, muss Y auf X zurückzeigen, sonst werden die Angaben ignoriert.
  • Alternative URLs sind vollständig angegeben, mit https:// und Host, nicht als /fr/seite/.
  • Der Sprachcode kommt zuerst (ISO 639-1), die Region optional danach (ISO 3166-1 Alpha 2). Ein Länderkürzel allein ist ungültig. Codes wie EU oder UK ignoriert Google.
  • x-default bezeichnet die Seite für alle, deren Sprache nicht im Angebot ist, am besten eine Sprachwahlseite.
  • Eine der drei Methoden genügt: <link> im <head>, HTTP-Header oder Sitemap. Mehrere gleichzeitig bringen laut Google keinen Vorteil in der Suche und sind schwerer zu pflegen.

Für ein Basler Dreisprachen-Angebot sieht der <head> der Kontaktseite so aus:

<link rel="alternate" hreflang="de-CH" href="https://www.beispiel.ch/de/kontakt/" />
<link rel="alternate" hreflang="fr-CH" href="https://www.beispiel.ch/fr/contact/" />
<link rel="alternate" hreflang="en" href="https://www.beispiel.ch/en/contact/" />
<link rel="alternate" hreflang="x-default" href="https://www.beispiel.ch/" />

Ob de-CH oder nur de, hängt vom Inhalt ab. Die Region lohnt sich, wenn die Seite wirklich für die Schweiz geschrieben ist (Preise in Franken, Schweizer Rechtstexte, Schreibweise ohne scharfes s). Richtet sich dieselbe deutsche Seite auch an Kundschaft in Deutschland, genügt de. Die Sprachcodes pro Seite lege ich im Scope fest. In Next.js setzen Sie die Angaben über alternates.languages in den Metadaten, in Astro übernimmt sie die Sitemap oder ein Layout, das sie aus der Verknüpfung der Sprachversionen berechnet (Abschnitt zur Übersetzung).

#Was gilt für Canonical bei mehreren Sprachen?

Jede Sprachversion verweist mit rel="canonical" auf sich selbst, nicht auf die deutsche Seite. Google weist ausdrücklich darauf hin, dass rel="canonical"-Angaben mit hreflang für die Kanonisierung nicht verwendet werden, Sprachvarianten gehören in rel="alternate" hreflang. Wer die französische Seite auf die deutsche kanonisiert, meldet Google die französische Seite als Duplikat. Weitere Regeln aus der Google-Dokumentation zu Canonicals, die in der Migration zählen:

  • Die Canonical-URL steht im HTML-Quelltext und wird nicht erst per JavaScript gesetzt. Absolute URLs sind besser als relative.
  • Wer hreflang nutzt, gibt eine Canonical-Seite in derselben Sprache an.
  • Interne Links führen auf die kanonische URL, nicht auf eine Variante.
  • Zwei Methoden gleichzeitig (Link-Element und HTTP-Header) sind fehleranfälliger als eine.

Hier kommt die Fallback-Frage zurück. Laut Google gelten lokalisierte Seiten nur als Duplikate, wenn der Hauptinhalt nicht übersetzt ist. Ein Rewrite, der unter /fr/ den deutschen Text ausliefert, erzeugt genau diesen Fall. Besser ist, die französische Seite erst zu veröffentlichen, wenn die Übersetzung vorliegt, und sie bis dahin auch nicht ins hreflang aufzunehmen. Google erlaubt, auf einzelnen Seiten Sprachen auszulassen; die Seiten, die sich gegenseitig verweisen, werden weiter verarbeitet.

#Wie bekommen die alten Sprach-URLs ein Ziel?

Die Migration ist laut Googles Anleitung zum Umzug mit URL-Änderungen eine Zuordnung von alten zu neuen URLs. Für drei Sprachen führe ich sie pro Sprache, denn eine französische URL braucht ein französisches Ziel, kein deutsches. Aus der Anleitung nehme ich diese Punkte in den Scope:

  • Jede neue URL erhält ein selbstverweisendes Canonical, und hreflang-Angaben zeigen auf die neuen URLs.
  • Interne Links werden auf die neuen URLs umgeschrieben, die Sitemap enthält nur die neuen.
  • Weiterleitungsketten vermeide ich. Google nennt als Obergrenze ideal höchstens drei, in jedem Fall weniger als fünf.
  • Alle Hostnamen-Varianten (mit und ohne www) werden bedacht und in der Search Console verifiziert.
  • Die Weiterleitungen bleiben so lange wie möglich, in der Regel mindestens ein Jahr.

Ein Skript ruft vor dem Launch jede alte URL auf der Staging-Umgebung auf und prüft Statuscode und Endziel. Die Staging-Umgebung ist passwortgeschützt und auf noindex gestellt; direkt nach der Umstellung prüfe ich, dass dieses noindex nicht in die Produktion gelangt ist. Zusagen zu Rankings gebe ich nicht. Ich prüfe und messe: Indexierungsbericht, Crawling-Statistik und Klicks der Seiten, die vorher Traffic hatten, getrennt nach Sprache.

#Wie läuft die Übersetzung im neuen CMS?

Die Texte liefern Ihre Fachleute, ich liefere die Struktur. Ein Ablauf, der mit Astro gut trägt, folgt dem Rezept aus der Astro-Dokumentation: ein Ordner pro Sprache unter src/content/, Schema-Validierung für jedes Feld und dynamische Routen mit lang und slug. Dazu kommen drei Bausteine, die ich selbst hinzufüge:

  • Ein gemeinsamer Schlüssel pro Seite (zum Beispiel translationKey), der die deutsche, französische und englische Fassung verbindet. Aus ihm entstehen hreflang und Sprachwechsler, nicht aus Dateinamen.
  • Ein Statusfeld pro Sprachversion (Entwurf, übersetzt, freigegeben). Nur freigegebene Fassungen erscheinen im Build, in der Sitemap und im hreflang.
  • Eine Oberflächen-Wörterbuchdatei für Navigation, Formulare und Buttons. Die Astro-Dokumentation zeigt dafür ein Muster, in dem fehlende Übersetzungen auf die Hauptsprache zurückfallen. Das passt für Eigennamen und Fachbegriffe, nicht für ganze Texte.

Bleibt Ihr bisheriges CMS die Quelle, weil die Redaktion täglich veröffentlicht, lese ich die Sprachversionen über dessen Schnittstelle und bilde dieselbe Verknüpfung ab. Ändern sich Inhalte selten, wandern sie als Markdown ins Repository. Wer Texte lieber im Browser pflegt, findet in der CMS-Übersicht der Astro-Dokumentation Git-basierte Optionen wie Decap CMS und CloudCannon, die ich auf Wunsch prüfe. Die Wahl halte ich mit Begründung im schriftlichen Scope fest, ebenso die Frage Astro oder Next.js; den allgemeinen Vergleich finden Sie auf der Seite zur Migration zu Next.js und Astro, das Headless-Modell auf der Seite zur Headless-CMS-Entwicklung.

#Was ändert sich beim Datenschutz in drei Sprachen?

Das Datenschutzgesetz (DSG, SR 235.1, Stand 1. September 2023) verlangt in Art. 19 Abs. 1, dass der Verantwortliche die betroffene Person angemessen über die Beschaffung von Personendaten informiert. Aufsicht führt nach Art. 4 der Eidgenössische Datenschutz- und Öffentlichkeitsbeauftragte (EDÖB). Ob die Datenschutzerklärung in jeder Sprache der Website vorliegen muss, entscheidet Ihre Rechtsberatung. Technisch folge ich dem sicheren Weg: Die Erklärung ist eine eigene Seite pro Sprache, im Footer jeder Sprachversion verlinkt, und ihre Angaben stimmen mit den Diensten überein, die die neue Website tatsächlich aufruft. Die Texte kommen von Ihrer Anwältin oder Ihrem Anwalt.

#Checkliste vor dem Launch

PrüfungWie ich sie ausführe
Jede alte URL hat ein ZielSkript auf Staging, Status und Endziel pro Sprache
hreflang gegenseitig und mit SelbstverweisPrüfskript über die gerenderten Seiten
Canonical zeigt auf die eigene Sprach-URLPrüfskript, absolute URLs im Quelltext
Keine Seite in Sprache X ohne ÜbersetzungBuild bricht ab, wenn ein Eintrag den Status “freigegeben” ohne Text hat
Sitemap enthält nur neue, direkt erreichbare URLsAbgleich mit der Weiterleitungskarte
noindex aus Staging fehlt in ProduktionAbruf der Produktionsseiten nach dem Umstellen
Datenschutzseite in jeder Sprache verlinktStichprobe pro Sprache

#So läuft ein Projekt mit mir

Sie senden mir die Adresse der Website, das CMS mit Version, die Sprachen und welche Seiten in welcher Sprache existieren. Ich stelle meine Fragen schriftlich und liefere einen Scope mit Annahmen, Weiterleitungskarte, Sprachcodes und der Wahl zwischen Astro und Next.js. Danach folgen Staging, Abnahme durch Sie und auf Wunsch eine laufende Wartung. Layout, Mockups und Wireframes liefern Sie; ich setze sie um. Treffen und Telefonate gibt es nicht, alles läuft über E-Mail und Dokumente. Von Ihnen brauche ich Zugang zum bisherigen CMS und zur Search Console, die Kontakte Ihrer Übersetzenden und die rechtlichen Texte pro Sprache.

#Häufige Fragen zur mehrsprachigen Migration

#Soll Französisch unter /fr/ oder auf einer eigenen Domain laufen?

Beides ist möglich. Google nennt Länderdomains als klares Signal für ein Land, aber teurer in Betrieb und auf ein Land beschränkt; Unterverzeichnisse sind einfach einzurichten und liegen auf demselben Host. Wer heute schon /fr/ nutzt, behält es. Ein Wechsel der Struktur ist ein eigener Umzug mit eigenem Risiko.

#Darf die Website Besucher nach Browsersprache weiterleiten?

Google rät davon ab, Nutzer automatisch auf eine andere Sprachversion umzuleiten, weil dadurch Nutzer und Suchmaschinen nicht alle Versionen sehen. Ich beschränke eine Erkennung höchstens auf die Startadresse ohne Sprache und lasse jede Inhaltsseite unter ihrer Sprach-URL stehen. Auf jeder Seite bleibt ein sichtbarer Sprachwechsler.

#Muss jede Seite in allen drei Sprachen existieren?

Nein. Fehlt eine Übersetzung, erscheint die Seite in dieser Sprache nicht und taucht auch nicht im hreflang auf. Google verarbeitet weiterhin die Sprachen, die sich gegenseitig verweisen. Eine deutsche Kopie unter einer französischen URL ist dagegen ein Duplikat.

#Wie lange müssen die alten Weiterleitungen bleiben?

Laut Google möglichst lange, in der Regel mindestens ein Jahr, damit alle Signale auf die neuen URLs übergehen. Ich liefere die Weiterleitungskarte pro Sprache als Datei, damit sie auch bei einem späteren Wechsel des Hosters erhalten bleibt.

#Welche Seite bekommt x-default?

Die Seite für Besucher, deren Sprache Sie nicht anbieten. Google hat x-default für Sprachwahlseiten vorgesehen. Hat die Website keine, ist die Startseite der Hauptsprache die übliche Wahl; das halte ich im Scope fest.

#Wo liegen die Übersetzungen nach der Migration, und wer pflegt sie?

Je nach Redaktionsrhythmus im bisherigen CMS als Headless-Quelle oder als Markdown im Repository, ein Ordner pro Sprache. Die Texte liefern Ihre Fachleute. Ich baue die Verknüpfung der Sprachversionen und die Prüfung, die fehlende Übersetzungen sichtbar macht.

#Schreiben Sie mir zu Ihrer mehrsprachigen Website

Schicken Sie mir über das Kontaktformular die Adresse Ihrer Website, das heutige CMS, die Sprachen, Ihr Ziel und den Wunschtermin. Ein Export der Seiten aus der Search Console hilft, ist aber keine Voraussetzung. Die erste schriftliche Einschätzung erhalten Sie kostenlos, mit meinen Rückfragen und den Risiken, die ich in Ihrer Sprachstruktur sehe. Sie verpflichtet Sie zu nichts.

Siehe auch in Schweiz

Brauchen Sie die Leistung: Migration zu Next.js / Astro in Basel?

Beschreiben Sie Ihr Projekt per E-Mail. Antwort innerhalb von 48 Stunden.

Projekt beschreiben

Weitere WordPress-Dienste und Wissensbasis entdecken