Migration zu Next.js / Astro in Zürich

Wie eine migrierte Website vor dem Start geprüft wird: Weiterleitungen, Links, Bildschirmvergleich, Formulartests, Barrierefreiheit, Core Web Vitals, Go-/No-go-Liste und Rückweg. Für Betriebe in Zürich, mit Hinweisen zum revDSG.

Migration zu Next.js / Astro

Website- & Anwendungsmigration in Zürich

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.
  • Lokales WordPress-Meetup: WordPress Zürich

Mein WordPress.org-Profil

Eine Migration scheitert selten an der Technik des neuen Frontends. Sie scheitert an Dingen, die niemand vor dem Start geprüft hat: eine alte Adresse ohne Ziel, ein Formular, das keine Mail mehr verschickt, ein noindex aus der Entwicklungsphase. Auf dieser Seite beschreibe ich den Testplan, den ich für eine Website in Zürich vor der Umstellung auf Astro oder Next.js aufstelle, und die Liste, nach der Sie entscheiden, ob der Start stattfindet.

#Was gehört in einen Testplan für eine migrierte Website?

Neun Prüfungen, jede mit einem Werkzeug und einem Abbruchkriterium. Ohne Abbruchkriterium ist eine Prüfung eine Meinung.

PrüfungWerkzeugAbbruchkriterium
WeiterleitungenSkript über die URL-KarteEine alte URL ohne direktes Ziel
Links und MetadatenCrawl von StagingLink auf eine weitergeleitete oder fehlende Seite
Visueller VergleichPlaywright, toHaveScreenshotAbweichung, die niemand erklären kann
FormularePlaywright im BrowserEine Mail kommt nicht an
Barrierefreiheitaxe und HandprüfungVerstoss auf einer Schlüsselseite
Core Web VitalsLabormessung, später FelddatenWert klar über der Schwelle ohne Plan
DatenschutzDiensteliste, DatenbestandUnbekannter Dienst oder Klartextkopie
RückwegProbelauf der DNS-UmstellungRückweg nie ausprobiert
FreigabeGo-/No-go-ListeEine offene Zeile ohne Verantwortlichen

Die Prüfungen laufen gegen die Produktionsfassung der neuen Seite. Die Astro-Dokumentation rät dazu, Tests gegen den Produktionscode laufen zu lassen, damit sie der ausgelieferten Seite ähneln, und zeigt dafür Playwrights webServer-Option mit npm run preview. Bei Next.js empfiehlt die Dokumentation für asynchrone Server Components End-to-End-Tests statt Unit-Tests, weil manche Werkzeuge sie noch nicht vollständig unterstützen. Für eine Migration ist das ohnehin die richtige Ebene: Mich interessiert, was ein Besucher im Browser sieht, nicht, wie eine Komponente intern aufgebaut ist.

#Wie prüfe ich die Weiterleitungen gegen die URL-Karte?

Die URL-Karte ist die Testliste. Ein Skript liest jede Zeile, ruft die alte Adresse ab, folgt der Weiterleitung nicht und vergleicht Statuscode und Location mit der Karte:

for (const [oldPath, newPath] of map) {
  const res = await fetch(base + oldPath, { redirect: 'manual' });
  const location = res.headers.get('location');
  if (res.status !== 301 || location !== newPath) console.log('FEHLER', oldPath, res.status, location);
}

Google verlangt bei einem Umzug mit URL-Änderungen serverseitige, dauerhafte Weiterleitungen, also 301 oder 308, und rät davon ab, Ketten zu bauen: Jede alte Adresse soll direkt zum endgültigen Ziel führen. Viele alte Seiten auf eine unpassende Zielseite wie die Startseite zu schicken, gilt ebenfalls als Fehler. Dieselbe Seite nennt als Prüfung vor und nach dem Start ausdrücklich, dass keine noindex-Angaben und keine robots.txt-Sperren aus der Entwicklung übrig bleiben.

Der Test läuft zweimal. Auf Staging, bevor Sie etwas freigeben, und gegen die Live-Domain direkt nach der Umstellung. Beim zweiten Lauf kommen die Adressen dazu, die nur in den Server-Logs auftauchen. Die Weiterleitungen sollen laut Google im Allgemeinen mindestens ein Jahr bestehen bleiben, deshalb gehören sie in die Konfiguration des neuen Hosts und nicht in ein Übergangsskript.

Der Crawl von Staging beantwortet eine andere Frage als der Weiterleitungstest: Was liefert die neue Seite selbst aus? Ich prüfe pro URL den Statuscode, den Titel, die H1, die Canonical-Adresse, die robots-Angabe und die hreflang-Verweise. Google nennt für den Umzug ausdrücklich, dass Canonical-Tags, hreflang-Angaben und interne Links auf die neuen Adressen zeigen sollen. Ein interner Link, der nur über eine Weiterleitung ans Ziel kommt, ist ein Fehler im neuen Code, auch wenn die Seite im Browser funktioniert.

Bei mehreren Sprachversionen, wie sie in Zürich üblich sind, zählt der Crawl jede Sprache getrennt. Die Prüfung der Verweise zwischen den Sprachen beschreibe ich ausführlich auf der Seite für Basel, hier genügt der Hinweis, dass jede Sprachversion eine eigene Zeile in der Testliste hat.

#Wie vergleiche ich alte und neue Seiten visuell?

Playwright erzeugt mit await expect(page).toHaveScreenshot() Referenzbilder und vergleicht spätere Läufe mit ihnen. Mein Vorgehen für eine Migration: Ich lege die Referenzbilder von der alten Website an, für eine feste Auswahl von Adressen, nämlich die Startseite, jede Seitenvorlage und die zehn Seiten mit den meisten Klicks aus der Search Console. Danach läuft derselbe Test gegen Staging. Jede Abweichung wird einzeln angesehen und entweder als gewollt freigegeben oder behoben.

Zwei Einschränkungen aus der Playwright-Dokumentation: Die Darstellung hängt vom Betriebssystem, von der Browserversion, von Einstellungen und von der Hardware ab. Referenzbilder und Vergleichslauf müssen deshalb in derselben Umgebung entstehen. Und Schwellen wie maxDiffPixels sind standardmässig nicht gesetzt, ein Test mit Standardwerten kann also kleine Abweichungen melden, die niemand sieht. Ich setze sie bewusst und schreibe die Werte in die Abnahme.

Hardbrücke über die Limmat in Zürich

Foto: Jag9889, CC BY-SA 4.0, Wikimedia Commons.

Der Vergleich ersetzt keine Freigabe durch Sie. Er zeigt, wo sich etwas verändert hat. Ob eine veränderte Tabelle oder ein verschobenes Bild stört, entscheiden Sie.

#Wie teste ich Formulare mit Playwright?

Ein Formular, das nach dem Umzug keine Mail mehr verschickt, kostet Anfragen, ohne dass es jemand sofort merkt. Deshalb schicke ich jedes Formular im Browser ab und prüfe zwei Dinge: die Bestätigung auf der Seite und die Mail beim Empfänger. Ein kleiner Test:

import { test, expect } from '@playwright/test';

test('Kontaktformular bestätigt den Versand', async ({ page }) => {
  await page.goto('/kontakt/');
  await page.getByLabel('E-Mail').fill('[email protected]');
  await page.getByLabel('Nachricht').fill('Test vor dem Go-live');
  await page.getByRole('button', { name: 'Senden' }).click();
  await expect(page.getByText('Vielen Dank')).toBeVisible();
});

Die Playwright-Hinweise für gute Tests tragen das Muster: Locators nach Rolle und Beschriftung, die der Besucher sieht, statt CSS-Klassen. Assertions wie toBeVisible(), die wiederholen, bis die Bedingung erfüllt ist. Jeder Test ist unabhängig vom anderen. Externe Dienste, die Sie nicht kontrollieren, werden über die Network API ersetzt, statt sie im Test aufzurufen. Für Formulare heisst das: Der Test prüft, dass Ihr Frontend die richtige Anfrage sendet und die Antwort richtig anzeigt. Dass die Mail wirklich ankommt, prüfe ich einmal von Hand mit einer Adresse, die Ihnen gehört.

Zur Fehlersuche empfiehlt Playwright auf CI den Trace Viewer und das Aufzeichnen der Traces erst beim ersten Wiederholen, weil vollständige Traces die Läufe verlangsamen. Ich übernehme das.

#Was prüft die Barrierefreiheit automatisch, und was nicht?

Das Paket @axe-core/playwright führt die axe-Engine innerhalb eines Playwright-Tests aus. Das Muster aus der Dokumentation: Seite öffnen, new AxeBuilder({ page }).analyze() aufrufen und erwarten, dass violations leer ist. Ich lasse diesen Test über die Startseite, jede Seitenvorlage, jedes Formular und die Seiten mit den meisten Klicks laufen.

Playwright selbst sagt, dass automatische Tests nur einige Probleme finden, etwa fehlende oder ungültige Eigenschaften, und dass viele Barrierefreiheitsprobleme nur von Hand auffallen. Empfohlen wird eine Kombination aus automatischen Tests, manueller Prüfung und Tests mit echten Nutzern. Eine grüne axe-Prüfung heisst deshalb nicht, dass die Seite barrierefrei ist. Zur Handprüfung gehören bei mir die Bedienung nur mit der Tastatur, die sichtbare Fokusmarkierung, die Reihenfolge der Überschriften und die Fehlermeldungen in den Formularen.

#Warum weichen Labor- und Felddaten bei den Core Web Vitals ab?

Die Schwellen sind amtlich: LCP bis 2,5 Sekunden, INP bis 200 Millisekunden, CLS bis 0,1, jeweils bewertet am 75. Perzentil der Seitenaufrufe, getrennt nach Mobilgeräten und Desktop (web.dev). Daraus folgt, dass ein einzelner Messlauf nichts beweist.

web.dev erklärt die Unterschiede zwischen beiden Datenarten: Ein Labortest nutzt ein Gerät, ein Netz und einen Standort und trifft damit nicht zwingend das 75. Perzentil der Felddaten. Beim LCP kann sich das gemessene Element je nach Bildschirmgrösse, Anmeldestatus oder Testvariante unterscheiden, und Caching oder der Zurück-Vorwärts-Cache machen echte Aufrufe schneller als einen Labortest mit leerem Cache. Der INP hängt davon ab, wann Besucher wirklich interagieren, das kann ein Labor nicht vorhersagen. Beim CLS zählt das Feld Verschiebungen über die ganze Lebensdauer der Seite, auch nach dem Scrollen.

Für den Testplan folgt daraus: Vor dem Start messe ich im Labor, weil es reproduzierbar ist und die Ursache zeigt. Ein Wert klar über der Schwelle ist ein Fund, den ich vor dem Start behebe. Ob die Schwelle im Feld gehalten wird, zeigen erst echte Besuche der neuen Seite, also die Wochen nach dem Start. web.dev rät, Prioritäten nach Felddaten zu setzen und das Labor zur Fehlersuche zu nutzen. Ich halte die Labormessung der alten und der neuen Seite im selben Profil fest, damit der Vergleich vorher und nachher möglich bleibt.

#Was verlangt das revDSG von den Tests selbst?

Testumgebungen sind ein Datenschutzthema, das oft vergessen wird. Das revidierte Datenschutzgesetz (Fedlex) enthält drei Stellen, die hier greifen. Die Aufsicht führt der Eidgenössische Datenschutz- und Öffentlichkeitsbeauftragte (EDÖB).

  • Art. 8 Abs. 1: Verantwortliche und Auftragsbearbeiter gewährleisten durch geeignete technische und organisatorische Massnahmen eine dem Risiko angemessene Datensicherheit. Eine Kopie der Produktionsdatenbank auf einer Staging-Domain ist Datenbestand wie das Original: Zugangsschutz, kein Indexieren, keine Weitergabe per Mail.
  • Art. 6 Abs. 4: Personendaten werden vernichtet oder anonymisiert, sobald sie für den Zweck nicht mehr erforderlich sind. Nach der Abnahme wird die Staging-Kopie gelöscht.
  • Art. 9 Abs. 1 und 2: Wer die Bearbeitung einem Auftragsbearbeiter überträgt, muss sich vergewissern, dass dieser die Datensicherheit gewährleisten kann. Das betrifft externe Werkzeuge, etwa einen Dienst für visuelle Vergleiche, der Seiten abruft.

Mein Vorgehen daraus: Formulartests laufen mit erfundenen Personen und Adressen, die Ihnen gehören. Muss eine Datenbankkopie her, stimmen wir vorher schriftlich ab, welche Tabellen mitkommen. Die rechtliche Bewertung bleibt bei Ihrer Rechtsberatung, ich bin Entwickler und kein Anwalt.

#Wie sieht die Go-/No-go-Liste aus?

Die Liste hat eine Zeile pro Prüfung, einen Verantwortlichen und eine Entscheidung. Eine Zeile mit offenem Fund ist ein No-go, bis der Fund behoben oder von Ihnen schriftlich akzeptiert ist.

ZeileBelegEntscheidung
Alle alten URLs führen direkt zum ZielAusgabe des Skripts, null FehlerGo oder No-go
Keine Staging-Sperre in ProduktionAbruf der Live-Seiten nach dem StartGo oder No-go
Canonical, hreflang und Sitemap zeigen auf neue AdressenCrawl-BerichtGo oder No-go
Alle Abweichungen im Bildvergleich geklärtListe mit FreigabenGo oder No-go
Jedes Formular verschickt und bestätigtTestprotokoll mit Eingang beim EmpfängerGo oder No-go
axe-Lauf ohne Verstösse, Handprüfung erledigtBericht und NotizenGo oder No-go
Labormessung für alte und neue Seite festgehaltenMessprotokolleGo oder No-go
Dienste und Datenbestand erfasst, Staging-Kopie geregeltDienstelisteGo oder No-go
Rückweg ausprobiertProbelauf mit DatumGo oder No-go

Die Entscheidung trifft eine Person bei Ihnen. Ich liefere die Belege, Sie unterschreiben die Zeilen.

#Wie funktioniert der Rückweg?

Ein Rollback ist ein Teil des Plans und wird vor dem Start ausprobiert, nicht erst, wenn er gebraucht wird. Die alte Seite läuft bis zu Ihrer Freigabe unverändert weiter, ihre Datensicherung liegt ausserhalb des Hostings. Die DNS-Umstellung ist so vorbereitet, dass die alte Adresse zurückgesetzt werden kann, und die Gültigkeitsdauer der DNS-Einträge wird dafür vor dem Start gesenkt. Bei einem Rückweg entferne ich die Weiterleitungen von alt auf neu, sonst schicken sie Besucher in eine Seite, die nicht mehr läuft.

Ein Rückweg ist nicht dasselbe wie ein Fehler nach dem Start. Fällt nach dem Start ein einzelner Fund auf, etwa ein Formular, behebe ich ihn auf der neuen Seite. Zum Rückweg greife ich, wenn viele Seiten oder ein Kernprozess betroffen sind. Wo die Grenze liegt, steht vorab in der Go-/No-go-Liste.

#Wie läuft ein Testprojekt mit mir ab?

Sie senden mir die Adresse der Website, das CMS mit Version, die Sprachen und eine Liste der Formulare. Ich stelle meine Fragen schriftlich und liefere einen Umfang mit Annahmen, dem Testplan und der Go-/No-go-Liste. Danach folgen Staging, Testprotokolle und Ihre Abnahme. Auf Wunsch schliesst sich eine laufende Wartung an. Gestaltung und Wireframes kommen von Ihnen, ich setze sie um. Ich arbeite allein, schriftlich und aus der Ferne: Fragen, Befunde und Protokolle kommen per E-Mail. Welcher Stack passt, besprechen wir schriftlich auf Basis der Seite zur Migration zu Next.js und Astro.

#Häufige Fragen

Reicht ein Crawl der neuen Seite als Test? Nein. Ein Crawl zeigt, was die neue Seite ausliefert, nicht, ob jede alte Adresse am richtigen Ziel ankommt. Dafür brauche ich die URL-Karte und einen Abruf jeder alten Adresse. Ein Crawl ersetzt weder den Formulartest noch die Handprüfung der Barrierefreiheit.

Warum zeigt das Labor andere Core-Web-Vitals-Werte als die Search Console? Das Labor misst ein Gerät, ein Netz und einen Standort. Felddaten stammen von echten Besuchen und werden am 75. Perzentil bewertet. Für die Priorisierung zählen die Felddaten, das Labor dient der Fehlersuche vor dem Start.

Kann ich die alte Website nach dem Start wiederherstellen? Ja, wenn der Rückweg vorher geplant ist: Die alte Seite läuft bis zur Freigabe unverändert weiter, die DNS-Umstellung ist für den Rückweg vorbereitet, und die Weiterleitungen werden bei einem Rollback entfernt.

Wie lange bleiben die Weiterleitungen aktiv? Google empfiehlt, sie bei einem Umzug mit URL-Änderungen im Allgemeinen mindestens ein Jahr zu behalten. Ich plane sie als Dauerlösung und streiche sie nicht nach der Anlaufphase.

Brauche ich für die Tests echte Kundendaten? Nein. Staging und Formulartests laufen mit erfundenen Personen und Adressen, die Ihnen gehören. Wird eine Kopie der Produktionsdatenbank gebraucht, gilt für sie dieselbe Datensicherheit wie für das Original.

Was brauchen Sie von mir für den Testplan? Zugang zur alten Website und zur Search Console, eine Liste der Formulare mit den Empfängeradressen und Ihre Entscheidung, welche Seiten für Sie geschäftskritisch sind. Die Go-/No-go-Liste unterschreiben Sie, nicht ich.

#Schreiben Sie mir vor dem Umzug

Schicken Sie mir über das Kontaktformular die Adresse Ihrer Website, das eingesetzte CMS, Ihr Ziel, den gewünschten Starttermin und die Liste Ihrer Formulare. Ich melde mich schriftlich an Werktagen, die erste schriftliche Einschätzung ist kostenlos.

Siehe auch in Schweiz

Brauchen Sie die Leistung: Migration zu Next.js / Astro in Zürich?

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

Projekt beschreiben

Weitere WordPress-Dienste und Wissensbasis entdecken