Migration von WordPress zu Astro in Wuppertal
Viele Unternehmen in Wuppertal nutzen WordPress, stoßen aber an Grenzen bei Performance, Sicherheit und Hosting-Kosten. Astro löst diese Probleme mit statischem HTML, null JavaScript und Edge-Deployment. Ich migriere bestehende WordPress-Seiten zu Astro mit vollständiger SEO-Erhaltung, URL-Mapping und 301-Weiterleitungen.
- PageSpeed 95-100
Statisches HTML ohne JavaScript. Schneller als jede WordPress-Lösung.
- SEO-sichere Migration
URL-Mapping, 301-Weiterleitungen, Google-Rankings erhalten.
- Hosting auf Cloudflare Pages
Globales CDN, kostenloses SSL, sofortige Deployments. Hosting-Kosten nahe null.
Formulare in Astro: wann eine Seite einen Server braucht
Ich bin Mariusz Szatkowski, arbeite seit 2006 mit WordPress und baue Websites heute auch mit Astro. Ich sitze in Gdynia, arbeite vollständig remote und schriftlich, Meetings und Telefonate gibt es nicht. Diese Seite richtet sich an Unternehmen in Wuppertal und im Bergischen Land, deren Website ein Anfrageformular hat und die wissen wollen, was dahinter passiert.
Mein Thema ist die Serverseite eines Formulars: Astro Actions, die Prüfung der Eingaben mit Zod, Seiten, die bei Anfrage gerendert werden, und ein Spamschutz ohne Tracker von Drittanbietern. Alles, was ich zu Astro schreibe, stammt aus der Dokumentation zu Actions und der Seite zum Rendern bei Anfrage.
Die Wirtschaftsförderung Wuppertal nennt auf ihrer Standortseite als Kompetenzfelder Automotive, Chemie, Health Care, technische Textilien sowie Maschinen- und Werkzeugbau. Ich leite daraus eine Vermutung ab, keine Tatsache über einzelne Firmen: Auf solchen Websites sind Produktseiten und Datenblätter meist statisch, aber dazu gehören oft Formulare, etwa Händleranfrage, Musteranfrage oder Bewerbung. Nur diese kleinen Teile brauchen Servercode.

Foto: Im Fokus, CC BY-SA 4.0, Wikimedia Commons.
Statische Seite, Adapter und Rendern bei Anfrage
Astro rendert nach der Dokumentation standardmäßig jede Seite beim Build zu statischem HTML. Eine Seite, die bei Anfrage vom Server erzeugt wird, braucht zwei Dinge:
- Einen Adapter für die Laufzeit, auf der der Code läuft. Astro pflegt offizielle Adapter für Node.js, Netlify, Vercel und Cloudflare.
export const prerender = falsean der einzelnen Seite oder dem Endpunkt. Der Rest der Website bleibt statisch.
Die Dokumentation rät, mit dem statischen Modus zu beginnen, bis die meisten Seiten wirklich auf Anfrage entstehen. Der Modus output: 'server' bringt laut Dokumentation keine zusätzlichen Funktionen, er dreht nur den Standard um. Für eine Firmenwebsite mit einem Formular bleibt also fast alles statisch, und nur die Kontaktseite bekommt Servercode.
Zwei Adapter erkläre ich Kunden am häufigsten, beide nach ihren Dokumentationsseiten:
@astrojs/nodebaut im Modusstandaloneeinen Server, der beim Start des Einstiegsmoduls selbst läuft. Im Modusmiddlewarelässt er sich in einen anderen Node.js-Server wie Express oder Fastify einhängen, der dann auch die statischen Dateien ausliefern muss.@astrojs/cloudflareerzeugt Worker-Code. Umgebungsvariablen und Bindings stehen laut Dokumentation in der Dateiwrangler.jsonc.
Welcher passt, hängt an Ihrem Hosting und Ihrer Datenschutzprüfung, nicht an Astro. Das klären wir schriftlich vor dem Start.
Eine Action für ein Anfrageformular
Eine Action ist laut Dokumentation eine typsichere Backend-Funktion. Sie kümmert sich um das Lesen der Daten und die Eingabeprüfung mit Zod, und sie vereinheitlicht Fehler über ActionError. Actions gibt es seit Astro 4.15. Stand 11. November 2026 ist laut npm-Registry Astro 7.4.11 die aktuelle Version, und Ihr Projekt bekommt eine feste Version, die ich im Umfang festhalte.
Ein Anfrageformular mit vier Feldern, nach dem Muster der Dokumentation:
// src/actions/index.ts
import { defineAction } from 'astro:actions';
import { z } from 'astro/zod';
export const server = {
anfrage: defineAction({
accept: 'form',
input: z.object({
name: z.string().min(2).max(120),
email: z.email(),
nachricht: z.string().min(10).max(4000),
firma_website: z.string().nullish(), // Köderfeld, siehe unten
}),
handler: async (input) => {
if (input.firma_website) return { ok: true }; // stillschweigend verwerfen
// hier: E-Mail oder CRM beauftragen
return { ok: true };
},
}),
};Drei Punkte aus der Dokumentation, die in der Praxis zählen:
accept: 'form'ist nötig, weil Actions sonst JSON erwarten.- Leere Felder kommen als
nullan. Wird ein Textfeld leer abgeschickt, ist der Wert laut Dokumentationnull, nicht"". Deshalb steht beim Köderfeldnullish(). - Bei ungültiger Eingabe liefert die Action den Fehler
BAD_REQUEST, und der Handler läuft gar nicht erst an.
Was der Handler mit der Anfrage macht (Mail, CRM, Ticket), ist eine eigene Entscheidung. Ich lege sie im schriftlichen Umfang fest, weil daran der Datenschutz hängt.
Das Formular auch ohne JavaScript
Eine Action lässt sich aus einem normalen HTML-Formular aufrufen: method="POST" und action={actions.anfrage}. Das funktioniert laut Dokumentation ohne Client-JavaScript und ist ein Rückfall, wenn Skripte nicht laden. Die Seite muss dafür auf Anfrage gerendert werden.
---
import { actions, isInputError } from 'astro:actions';
export const prerender = false;
const result = Astro.getActionResult(actions.anfrage);
const fehler = isInputError(result?.error) ? result.error.fields : {};
---
<form method="POST" action={actions.anfrage}>
<label for="email">E-Mail</label>
<input id="email" type="email" name="email" required aria-describedby="email-fehler" />
{fehler.email && <p id="email-fehler">{fehler.email.join(', ')}</p>}
<!-- weitere Felder -->
<button>Anfrage senden</button>
</form>Astro.getActionResult() liefert auf dem Server data oder error, oder undefined, wenn die Action in dieser Anfrage nicht lief. isInputError() trennt Eingabefehler von anderen Fehlern, und fields enthält die Meldungen pro Feldname. Die Verbindung zwischen Eingabefeld und Fehlertext über aria-describedby übernehme ich aus dem Beispiel der Dokumentation.
Zwei Eigenheiten, die ich vor dem Start nenne:
- Eingaben werden nach dem Absenden geleert. Die Dokumentation beschreibt dafür
transition:persistmit View Transitions. - Das Ergebnis gilt nur für diese POST-Anfrage. Beim Neuladen erscheint die Rückfrage, ob das Formular erneut gesendet werden soll. Wer das nicht will, setzt laut Dokumentation das Muster POST, Redirect, GET in einer Middleware um, mit Cookie oder Session-Speicher.
Spamschutz ohne Tracker
Jedes öffentliche Formular zieht automatisierte Anfragen an. Mein Vorgehen in dieser Reihenfolge, von billig zu aufwendig:
- Serverseitige Grenzen. Die Zod-Schemas begrenzen Länge und Form jedes Feldes. Das ist Spamschutz und Datensparsamkeit zugleich.
- Köderfeld. Ein für Menschen unsichtbares Feld, das nur Skripte ausfüllen. Es hält einfache Bots auf, mehr nicht, und ich verkaufe es nicht als vollständigen Schutz.
- Ratenbegrenzung. Die Dokumentation empfiehlt, Berechtigung und Ratenbegrenzung pro Action im Handler zu prüfen. Wo ich sie setze (Handler oder Hosting), hängt vom Adapter ab.
- Eine Rätselprüfung ohne Fremddienst. ALTCHA ist ein MIT-lizenziertes Projekt, das sich nach eigener Beschreibung selbst betreiben lässt, per Proof-of-Work arbeitet und ohne Cookies und Fingerprinting auskommt. Das sind Angaben des Projekts. Ich prüfe sie im Browser, bevor ich sie auf Ihrer Seite als zutreffend behandle.
Ein Fremddienst als Spamschutz lädt Skripte und überträgt Besucherdaten an Dritte. Dann gehört er auf die Liste der Fremddienste im Datenschutz. Wo der Schutz auf Ihrem eigenen Server läuft, entfällt diese Zeile.
Eine Action ist ein öffentlicher Endpunkt
Die Dokumentation sagt es ausdrücklich: Actions sind unter einem Pfad wie /_actions/blog.like öffentlich erreichbar. Deshalb gelten dieselben Prüfungen wie für jede Schnittstelle. Zwei Folgerungen:
- Berechtigung im Handler. Geschützte Aktionen prüfen den Nutzer im Handler und werfen sonst
ActionErrormit dem CodeUNAUTHORIZED. Ein Kontaktformular braucht das nicht, ein Händlerbereich schon. - Herkunftsprüfung. Astro prüft bei Seiten, die auf Anfrage gerendert werden, standardmäßig, ob Formulare aus derselben Herkunft kommen (
security.checkOrigin, Standardtrue). Laut Konfigurationsreferenz nutzt Astro dafürSec-Fetch-Siteund fällt aufOriginzurück. Eine fremde Herkunft erhält Status 403. Ich lasse die Einstellung an und schreibe es in den Umfang, falls sie aus einem Grund abgeschaltet werden muss.
Datenschutz: was ein Formular nach NRW-Recht auslöst
Zuständig für Unternehmen in Wuppertal ist die Landesbeauftragte für Datenschutz und Informationsfreiheit Nordrhein-Westfalen (LDI NRW). Ich bin Entwickler, die rechtliche Bewertung gehört zu Ihrer Rechtsberatung. Folgende drei Aussagen sind für den Aufbau nützlich:
- Datenschutzerklärung ergänzen. Die LDI NRW schreibt in ihrem Muster für Datenschutzhinweise, dass die Erklärung zu ergänzen ist, wenn die Website unter anderem ein Kontaktformular anbietet.
- Datenminimierung und Speicherbegrenzung. Nach Art. 5 Abs. 1 Buchst. c und e DSGVO müssen Daten auf das notwendige Maß beschränkt sein und dürfen nur so lange identifizierbar bleiben, wie es der Zweck erfordert. Für ein Formular heißt das: nur Felder, die Sie für die Antwort brauchen, und eine Aufbewahrungsfrist für Anfragen.
- Zugriff auf das Endgerät. § 25 TDDDG verlangt für Speicherung und Zugriff auf Informationen im Endgerät grundsätzlich eine Einwilligung, mit der Ausnahme, dass beides unbedingt erforderlich ist, um einen ausdrücklich gewünschten digitalen Dienst bereitzustellen. Ein Formular mit Köderfeld und serverseitiger Prüfung speichert nichts im Browser. Bei jedem Spamschutz schaue ich nach, ob er etwas ablegt, und trage das Ergebnis in die Liste ein.
Checkliste für Ihr Formular
| Frage | Folge |
|---|---|
| Gibt es überhaupt Servercode auf der Seite? | Ohne Anfrage-Rendering reicht eine statische Seite, Formular über einen externen Dienst oder ein CMS |
| Welche Seite muss auf Anfrage rendern? | Nur diese, mit prerender = false, dazu ein Adapter |
| Wohin gehen die Daten? | Mail, CRM, Ticketsystem: im Umfang festgelegt und in der Datenschutzerklärung genannt |
| Welche Felder sind Pflicht? | Nur was für die Antwort nötig ist, jedes mit Längengrenze im Schema |
| Wie lange bleiben Anfragen gespeichert? | Eine Frist, die Sie festlegen |
| Läuft das Formular ohne JavaScript? | Ja, über method="POST" und action={actions.name} |
| Welcher Spamschutz? | Grenzen, Köderfeld, Ratenbegrenzung, bei Bedarf selbst betriebene Rätselprüfung |
| Lädt der Spamschutz etwas von Dritten? | Wenn ja, auf die Liste der Fremddienste |
| Wo laufen Server und Daten? | Adapter und Hosting, mit Standort, im schriftlichen Umfang |
So läuft ein Projekt mit mir
Alles ist schriftlich.
- Briefing. Sie senden mir die Adresse Ihrer Website, das Ziel, den Termin und den aktuellen Stack. Ich frage schriftlich nach, was fehlt.
- Umfang und Annahmen. Ich halte fest, welche Formulare es gibt, wohin die Daten gehen, welcher Adapter und welches Hosting vorgesehen sind und was ich von Ihnen voraussetze. Layout, Grafik und Wireframes kommen von Ihnen, ich setze sie technisch um. Gestartet wird erst, wenn Sie den Umfang schriftlich bestätigt haben.
- Aufbau auf einer Testumgebung. Sie sehen den Stand auf einer Vorschau-Adresse und können das Formular selbst absenden.
- Abnahme. Sie nehmen anhand des schriftlichen Umfangs ab. Änderungen außerhalb davon erfasse ich als neues Angebot.
- Start und Wartung (optional). Nach dem Start kann ich Updates und Abhängigkeiten übernehmen. Wie das abläuft, steht auf der Seite Wartung und Support in Wuppertal. Stunden daraus gelten für den jeweiligen Monat.
Besteht Ihre Seite hauptsächlich aus einer Anwendung mit Anmeldung und Datenbank, ist Next.js in Wuppertal oft die bessere Wahl. Läuft Ihre Seite auf WordPress und soll es bleiben, hilft die Seite zu WordPress in Wuppertal.
Häufige Fragen
Brauche ich für ein Kontaktformular in Astro einen Server?
Eine Action ist Servercode und braucht deshalb eine Seite, die auf Anfrage gerendert wird, also einen Adapter. Alternativ bleibt die Seite statisch und das Formular geht an einen externen Dienst. Das ist dann ein Fremddienst im Datenschutz. Ich lege die Variante im Umfang fest.
Was passiert, wenn jemand das Formular ohne JavaScript abschickt?
Bei einem Formular mit method="POST" und action={actions.name} läuft die Action auf dem Server, und Fehler lassen sich mit Astro.getActionResult() in der Seite anzeigen. Das nennt die Dokumentation einen Rückfall, falls JavaScript nicht lädt.
Wie schützen Sie das Formular vor Spam, ohne Google reCAPTCHA?
Mit Grenzen im Schema, einem Köderfeld und einer Ratenbegrenzung. Reicht das nicht, kommt eine selbst betriebene Rätselprüfung wie ALTCHA infrage. Ein einzelnes Mittel schützt nicht vollständig, deshalb kombiniere ich sie.
Darf ich Anfragen aus dem Formular einfach speichern?
Das beurteilt Ihre Rechtsberatung. Technisch halte ich fest, welche Felder gespeichert werden und wie lange. Art. 5 DSGVO verlangt Datenminimierung und Speicherbegrenzung, und die LDI NRW verlangt eine ergänzte Datenschutzerklärung, wenn es ein Kontaktformular gibt.
Ist eine Action von außen erreichbar?
Ja. Nach der Dokumentation sind Actions öffentliche Endpunkte unter /_actions/. Darum prüfe ich Eingaben im Schema und Berechtigungen im Handler, und security.checkOrigin bleibt eingeschaltet.
Kommen Sie für das Projekt nach Wuppertal?
Nein. Ich arbeite von Gdynia aus ausschließlich schriftlich: Briefing, Rückfragen, Umfang, Testumgebung zur Abnahme. Meetings und Telefonate gibt es nicht. Eine erste Einschätzung bekommen Sie schriftlich und ohne Berechnung.
Schreiben Sie mir
Schicken Sie mir über das Kontaktformular die Adresse Ihrer Website, Ihr Ziel, Ihren Termin und den aktuellen Stack, am besten mit den Formularen, die heute Anfragen erzeugen, und dem Ort, an den diese Anfragen gehen. Ich lese alles, frage schriftlich nach und antworte mit einer ersten Einschätzung zu Umfang und Annahmen. Dafür berechne ich nichts. Passt Astro nicht zu Ihrem Vorhaben, schreibe ich das offen und nenne die bessere Lösung.
Ausgewählte Projekte
Beispiele aus meiner Arbeit.
scalac.io - WordPress Projekt | WPPoland
scalac.io ist eine internationale Plattform, die im Jahr 2014 ins Leben gerufen wurde, um den Herausforderungen im Umgang mit Big Data sowie der Skalierung v...
sprint.pl - WordPress Projekt | WPPoland
Sprint.pl ist eine Webseite, die für Sprint S.A. entwickelt wurde, ein in Olsztyn ansässiges Unternehmen, das seit 1988 als Systemintegrator und Anbieter for...
surfuje.pl - WordPress Projekt | WPPoland
surfuje.pl ist eine Website für Surfer und Wassersportinteressierte, mit klaren Inhalten, einfacher Veröffentlichung und stabilem Betrieb.
WordPress Support & Entwicklung in Wuppertal
Brauchen Sie die Leistung: Astro-Entwickler in Wuppertal?
Beschreiben Sie Ihr Projekt per E-Mail. Antwort innerhalb von 48 Stunden.
Projekt beschreibenWeitere WordPress-Dienste und Wissensbasis entdecken
Migration zu Astro, Next.js und Headless WordPress.
WooCommerce-Synchronisierung mit ERP und Großhandel.
Geschäftsprozessautomatisierung rund um WordPress und Firmensysteme.
Bibliothek konkreter Automatisierungsfälle.
Headless WordPress, Sanity, Strapi und Contentful mit Astro oder Next.js.
Astro, MDX, Edge Delivery und an echtem Traffic gemessene Core Web Vitals.
Individuelle WordPress-Entwicklung und Architektur.
Skalierbare Headless-, ERP- und KI-Architektur für Enterprise.
Verwandte Kategorien
Unterstützende Artikel

Sechs bis sechzehn Wochen für typische Projekte, in vier Phasen: Analyse, Scoping, Build und Umstellung, Tuning. Die Variablen sind Katalogumfang, Anzahl der Integrationen, URL-Erhalt und die Bereitschaft des Redaktionsteams, nicht die Wahl des Frameworks.

Umfassende 4-Jahres-TCO-Analyse (Total Cost of Ownership), reale Core-Web-Vitals-Benchmarks, Astro 7 GraphQL APQ-Architektur und eine 10-Punkte-Entscheidungsmatrix für Enterprise-Entscheider zwischen entkoppeltem und traditionellem WordPress.

Die Entscheidung Shopify Plus vs WooCommerce headless im Jahr 2026 ist kein binärer "Plattform vs Custom"-Kompromiss mehr. Beide laufen headless, beide integrieren KI, beide liefern am Edge aus. Die echten Achsen sind Kontrolle, Gesamtkosten über fünf Jahre und Exit-Strategie. Dieser Artikel durchläuft die Entscheidungsmatrix mit bestätigten Plattformfakten.