Next.js-Entwickler in Wiesbaden

Login für Intranet, Mitgliederbereich oder Kundenportal in Next.js: Sitzung im Cookie oder in der Datenbank, sichere Cookie-Optionen, Prüfung in der Datenzugriffsschicht und die Hinweise des HBDI zu Anmeldeformularen.

Next.js-Entwickler

Mein Platz in der WordPress-Community

  • 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

#Login in Next.js: Intranet, Mitgliederbereich, Kundenportal

Eine Anmeldung braucht eine Next.js-Anwendung meist für einen von drei Zwecken: ein Intranet für Beschäftigte, einen geschützten Bereich für die Mitglieder eines Vereins oder Verbands, ein Portal, in dem Kunden ihre Unterlagen abrufen. Technisch sind das drei Varianten derselben Aufgabe. Wer ist die Person, wie lange bleibt sie angemeldet, und was darf sie sehen?

Diese Seite beschreibt, wie ich das in Next.js baue, Stand November 2026 mit Next.js 16.4.6 als aktueller Version laut npm. Für Unternehmen und Vereine in Wiesbaden kommt eine Quelle hinzu, die oft übersehen wird: Der Hessische Beauftragte für Datenschutz und Informationsfreiheit (HBDI) hat eigene Hinweise dazu veröffentlicht, wie Anmeldeformulare keine Daten preisgeben. Sie stehen weiter unten.

Wie Server Actions abgesichert werden, beschreibe ich ausführlich auf der Seite für Bonn. Hier geht es um das, was davor liegt: die Sitzung selbst und den Ort, an dem sie geprüft wird.

#Drei Aufgaben, die die Next.js-Anleitung auseinanderhält

Die Anleitung zur Authentifizierung teilt das Thema in drei Schritte. Authentifizierung stellt fest, ob jemand die Person ist, die er vorgibt zu sein, etwa per Benutzername und Passwort. Sitzungsverwaltung hält diesen Zustand über mehrere Anfragen fest. Autorisierung entscheidet, welche Routen und Daten die Person erreicht.

Die Anleitung zeigt ein eigenes Login mit Passwort, nennt es aber ausdrücklich ein Lehrbeispiel. Für mehr Sicherheit und weniger Aufwand empfiehlt sie eine Bibliothek, die Anmeldung, Sitzung und Berechtigung mitbringt, oft auch Social Login, Mehr-Faktor-Anmeldung und Rollen. Ich halte mich daran. Die Beispiele unten dienen dazu, zu verstehen, was eine Bibliothek für Sie erledigt und an welchen Stellen Sie trotzdem selbst entscheiden müssen.

Next.js unterscheidet zwei Arten von Sitzungen. Bei der zustandslosen Sitzung liegen die Sitzungsdaten oder ein Token im Cookie des Browsers, und der Server prüft sie bei jeder Anfrage. Bei der Datenbanksitzung liegen die Daten auf dem Server, und der Browser bekommt nur eine verschlüsselte Sitzungs-ID. Die Anleitung nennt die erste Variante einfacher, aber weniger sicher, wenn sie falsch umgesetzt wird; die zweite sicherer, dafür aufwendiger und ressourcenhungriger.

Die Dokumentation von Auth.js zu Sitzungsstrategien benennt den entscheidenden Nachteil der Cookie-Variante: Ein JWT lässt sich vor seinem Ablauf nicht ungültig machen, außer man führt auf dem Server eine Sperrliste und prüft jedes Token dagegen. Auth.js löscht beim Abmelden zwar das Cookie, aber eine an anderer Stelle gespeicherte Kopie bleibt bis zum Ablauf gültig. Deshalb arbeitet diese Variante mit kurzen Laufzeiten. Dazu kommt die Größe: Ein Cookie fasst typischerweise rund 4096 Bytes, und die Daten reisen bei jeder Anfrage mit.

Die Datenbanksitzung lässt sich jederzeit auf dem Server ändern. Auth.js nennt als Beispiele das Abmelden auf allen Geräten und die Begrenzung gleichzeitiger Anmeldungen; die Next.js-Anleitung ergänzt den Zeitpunkt der letzten Anmeldung und die Zahl aktiver Geräte. Der Preis ist eine Datenbankabfrage pro Prüfung.

FrageCookie (zustandslos)Datenbank
Zugang einer Person sofort sperrenerst nach Ablauf oder mit SperrlisteSitzung löschen genügt
Abmelden auf allen Gerätennicht ohne Zusatzaufwandvorgesehen
Zusätzliche InfrastrukturkeineTabelle für Sitzungen
Datenmenge in der Sitzungbegrenzt durch die Cookie-Größepraktisch frei

Meine Faustregel: Für ein Intranet nehme ich die Datenbank. Verlässt jemand das Unternehmen, soll sein Zugang am selben Tag enden und nicht erst, wenn ein Token abläuft. Für einen Mitgliederbereich mit Rundschreiben und Terminen reicht oft das Cookie mit einer Laufzeit von einigen Stunden.

Für das Sitzungs-Cookie nennt die Anleitung fünf Optionen. HttpOnly sperrt den Zugriff aus JavaScript im Browser. Secure schickt das Cookie nur über HTTPS. SameSite legt fest, ob es bei Anfragen von fremden Seiten mitgeht. Max-Age oder Expires löscht es nach einer bestimmten Zeit. Path begrenzt den Pfad. Gesetzt wird das Cookie auf dem Server, und zwar laut Referenz zu cookies nur in einer Server Function oder einem Route Handler: HTTP erlaubt keine Cookies mehr, sobald das Streaming begonnen hat, und beim Rendern einer Server Component wird es gar nicht unterstützt.

Bei SameSite wähle ich Lax. Laut MDN schickt der Browser ein Cookie mit Strict nur bei Anfragen, die von der eigenen Seite ausgehen; Lax schickt es zusätzlich, wenn jemand von einer fremden Seite zu Ihnen navigiert. Bei Strict sähe ein Mitglied, das über den Link in einem Rundschreiben kommt, die erste Seite abgemeldet. Fehlt die Angabe ganz, behandelt der Browser das Cookie als Lax.

Eine zusätzliche Absicherung bietet der Präfix __Host- im Namen. MDN beschreibt, dass der Browser ein solches Cookie nur annimmt, wenn es mit Secure von einer HTTPS-Seite gesetzt wird, kein Domain-Attribut trägt und als Path / hat. Damit kann keine Subdomain es überschreiben.

Zum Inhalt: Laut Anleitung gehört in die Sitzung nur das Minimum, etwa die Nutzer-ID und die Rolle, keine E-Mail-Adresse, keine Telefonnummer und kein Passwort. Das hat einen technischen Grund. Das Beispiel der Anleitung erzeugt mit der Bibliothek Jose ein JWT mit HS256. So ein Token ist signiert, nicht verschlüsselt: Niemand kann es fälschen, aber jeder, der das Cookie hat, kann seinen Inhalt lesen. Den Schlüssel erzeugt die Anleitung mit openssl rand -base64 32 und legt ihn als Umgebungsvariable ab.

So sieht das bei mir für einen Mitgliederbereich aus. Der Code ist gegen Next.js 16.4.6 und Jose 6 typgeprüft:

// lib/session.ts
import 'server-only'
import { SignJWT, jwtVerify } from 'jose'
import { cookies } from 'next/headers'

const COOKIE = '__Host-sitzung'
const schluessel = new TextEncoder().encode(process.env.SESSION_SECRET)

export type Sitzung = { userId: string; rolle: 'mitglied' | 'vorstand' }

export async function sitzungAnlegen(daten: Sitzung) {
  const ablauf = new Date(Date.now() + 8 * 60 * 60 * 1000)
  const token = await new SignJWT(daten)
    .setProtectedHeader({ alg: 'HS256' })
    .setExpirationTime(ablauf)
    .sign(schluessel)

  const cookieStore = await cookies()
  cookieStore.set(COOKIE, token, {
    httpOnly: true,
    secure: true,
    sameSite: 'lax',
    path: '/',
    expires: ablauf,
  })
}

export async function sitzungLesen(): Promise<Sitzung | null> {
  const token = (await cookies()).get(COOKIE)?.value
  if (!token) return null
  try {
    const { payload } = await jwtVerify<Sitzung>(token, schluessel, {
      algorithms: ['HS256'],
    })
    return { userId: payload.userId, rolle: payload.rolle }
  } catch {
    return null
  }
}

sitzungAnlegen rufe ich nur aus der Server Action des Anmeldeformulars auf. Das Paket server-only sorgt dafür, dass der Build abbricht, falls jemand die Datei in eine Client-Komponente importiert.

#Die Datenzugriffsschicht prüft, nicht das Layout

Next.js empfiehlt eine Datenzugriffsschicht, kurz DAL: eine Datei, in der alle Datenabfragen und die Berechtigungslogik zusammenlaufen. Darin steht eine Funktion, die die Sitzung prüft und bei Bedarf zur Anmeldung weiterleitet. Mit cache aus React wird ihr Ergebnis während eines Render-Durchlaufs nur einmal berechnet. Die Anleitung weist auf eine Grenze hin: Server Actions und Route Handlers gehören nicht zu einem Render-Durchlauf, dort läuft die Funktion bei jedem Aufruf neu.

Dazu kommen Data Transfer Objects. Die Anleitung rät, nur die Felder zurückzugeben, die die Oberfläche braucht, und nie ganze Datensätze, in denen auch Passwörter oder Telefonnummern stehen können. Im Beispiel unten hat ein Vereinsprotokoll auch die E-Mail-Adresse des Verfassers; sie verlässt die DAL nicht. Protokolle, die nur der Vorstand sehen darf, liefert die Funktion anderen Mitgliedern gar nicht aus:

// lib/dal.ts
import 'server-only'
import { cache } from 'react'
import { redirect } from 'next/navigation'
import { sitzungLesen } from '@/lib/session'
import { db } from '@/lib/db'

export const sitzungPruefen = cache(async () => {
  const sitzung = await sitzungLesen()
  if (!sitzung) redirect('/anmelden')
  return sitzung
})

export async function protokollLesen(id: string) {
  const { rolle } = await sitzungPruefen()
  const protokoll = await db.protokoll.findUnique({ where: { id } })
  if (!protokoll) return null
  if (protokoll.nurVorstand && rolle !== 'vorstand') return null

  return { titel: protokoll.titel, datum: protokoll.datum, text: protokoll.text }
}

Ein häufiger Fehler ist die Prüfung im Layout. Die Anleitung erklärt zwei Gründe, warum das nicht trägt. Layouts werden wegen des partiellen Renderings bei einer Navigation nicht neu gerendert, die Sitzung wird also nicht bei jedem Seitenwechsel geprüft. Und ein Layout entscheidet nicht darüber, ob der Rest der Route läuft: Segmente und parallele Slots rendert der Router, auch wenn das Layout sie ausblendet, und ihr Inhalt kann im RSC-Payload landen. Ein return null im Layout, wie man es aus Single-Page-Apps kennt, empfiehlt die Anleitung ausdrücklich nicht.

Eine Lücke hat die DAL: Sie schützt Daten, die zur Anfragezeit geladen werden. Statische Routen, deren Inhalt für alle Nutzer gleich ist, entstehen beim Build. Für solche Seiten, etwa Inhalte hinter einer Bezahlschranke, nennt die Anleitung Proxy als Schutz. Ihr Beispiel vergleicht Pfade mit includes, also nur exakt: /dashboard ist geschützt, /dashboard/einstellungen nicht. In echten Projekten prüfe ich Präfixe. Warum Proxy allein nie reicht, steht auf der Bonner Seite.

Mit aktivierten Cache Components gilt eine weitere Regel aus der Anleitung dazu: Eine Funktion mit use cache kann cookies() nicht lesen. Die exportierte Funktion ermittelt den Nutzer und gibt nur die ID an eine gecachte Hilfsfunktion weiter. Diese Hilfsfunktion bleibt unexportiert, damit niemand sie mit der ID einer anderen Person aufruft. Mehr zum Cache steht auf der Seite für Augsburg.

#Auth.js, Better Auth oder eigene Sitzungen

Die Next.js-Anleitung listet zwölf Bibliotheken, darunter Auth0, Better Auth, Clerk, NextAuth.js, Supabase und WorkOS, für die reine Sitzungsverwaltung außerdem iron-session und Jose. Zwei davon sind in Projekten, die ich übernehme, am häufigsten: Auth.js und Better Auth.

Am 22. September 2025 hat das Better-Auth-Team bekanntgegeben, dass es Auth.js, früher NextAuth.js, künftig pflegt. Bestehende Installationen bekommen weiter Sicherheitskorrekturen und dringende Fehlerbehebungen. Neuen Projekten empfiehlt das Team Better Auth, mit einer Ausnahme in der Ankündigung: zustandslose Sitzungen ohne Datenbank. Diese Lücke ist inzwischen geschlossen; die Dokumentation zur Sitzungsverwaltung beschreibt einen Modus ohne Datenbank, der automatisch greift, wenn keine Datenbank konfiguriert ist.

Für Next.js installiert man Auth.js laut Anleitung als next-auth@beta. Auf npm ist das im November 2026 die Version 5.0.0-beta.32, während die stabile Linie bei 4.24.15 steht. Pflicht ist eine einzige Umgebungsvariable, AUTH_SECRET, die der Befehl npx auth secret erzeugt.

Bei Better Auth lohnt ein Blick in die Sitzungstabelle. Sie speichert neben Token, Nutzer-ID und Ablauf auch die IP-Adresse und den User-Agent. Das sind personenbezogene Daten, die in Ihre Datenschutzinformation und Ihr Löschkonzept gehören; die rechtliche Einordnung trifft Ihre Datenschutzberatung. Standardmäßig läuft eine Sitzung dort sieben Tage und verlängert sich bei Nutzung.

Ein Unterschied zwischen den Dokumentationen betrifft Proxy. Die Next.js-Anleitung rät, dort nur das Cookie zu lesen und Datenbankabfragen zu vermeiden, weil Proxy bei jeder Route läuft, auch bei vorab geladenen. Die Next.js-Integration von Better Auth zeigt ab Next.js 16 auch eine vollständige Prüfung mit Datenbank in Proxy. Ich folge der Next.js-Anleitung und lasse die teure Prüfung in der DAL.

Eigene Sitzungen wie im Beispiel oben schreibe ich nur, wenn die Anmeldung ohnehin ein vorhandenes System übernimmt, etwa die Mitgliederverwaltung eines Verbands mit eigener Schnittstelle, und die Anwendung nur noch die Sitzung halten muss.

#Intranet mit Microsoft-Konten

Viele Intranets sollen sich mit den vorhandenen Microsoft-Konten der Beschäftigten öffnen. Auth.js bringt dafür einen Provider für Microsoft Entra ID mit, den früheren Namen Azure AD. Er braucht drei Werte: die Client-ID der App-Registrierung, ein Client-Secret und den Issuer.

Beim Issuer liegt die Falle. Fehlt er, verwendet der Provider laut Dokumentation https://login.microsoftonline.com/common/v2.0, die Variante für Arbeits-, Schul- und private Microsoft-Konten. Für ein Intranet gehört die Adresse mit der eigenen Verzeichnis-ID hinein, die Auth.js als Einstellung für nur eine Organisation beschreibt. Welche Konten sich tatsächlich anmelden können, legt zusätzlich die Auswahl bei der App-Registrierung fest; beides stimme ich in der Konfiguration aufeinander ab. Das Secret zeigt Microsoft laut der Anleitung nur einmal an. Es gehört direkt in den Passwortmanager und in die Umgebungsvariablen, nie in den Quelltext.

Kochbrunnen in Wiesbaden

Foto: Marco Almbauer, CC0, Wikimedia Commons.

#Was der HBDI zu Anmeldeformularen schreibt

Unternehmen und Vereine in Wiesbaden unterstehen der Aufsicht des HBDI. Er hat einen Hinweis veröffentlicht, der genau die Formulare einer Anwendung mit Login betrifft: Datenlecks in Anmeldeformularen vermeiden, Stand 23.02.2024.

Der HBDI beschreibt zwei Muster. Eine Fehlermeldung wie “Das eingegebene Passwort zu diesem Konto ist falsch” verrät, dass die Kennung stimmt und das Konto existiert. Ein Formular zum Zurücksetzen des Passworts verrät dasselbe, wenn es meldet, dass zu einer Adresse kein Konto existiert. Bei einem Bewerber- oder Gesundheitsportal hält der HBDI erhebliche Schäden für die Betroffenen für denkbar. Er verweist auf den Grundsatz der Vertraulichkeit in Art. 5 Abs. 1 lit. f DSGVO und auf die Technikgestaltung nach Art. 25 Abs. 1; eine solche Offenlegung könne eine Verletzung des Schutzes personenbezogener Daten sein.

Seine Empfehlung sind neutrale Formulierungen. Als Beispiele nennt er “Die Kombination aus Benutzerkennung und Passwort ist falsch” und für das Zurücksetzen “Sofern ein solches Benutzerkonto existiert, wurde ein Link zum Zurücksetzen des Passworts versandt”.

Ich wende das auch auf die Registrierung an. Die Next.js-Anleitung schlägt vor, doppelte E-Mail-Adressen schon beim Tippen zu prüfen, um unnötige Absendungen zu sparen. In einem Mitgliederbereich verzichte ich darauf, weil genau diese Prüfung verrät, wer schon Mitglied ist. Stattdessen bekommt die Adresse eine Mail, und erst dort steht, ob ein Konto besteht.

Der HBDI verweist außerdem auf die Orientierungshilfe der Datenschutzkonferenz zur Zugangssicherung, Stand 29. März 2019. Daraus übernehme ich in jedes Login-Projekt diese Punkte:

  • Passwörter in der Regel mit mindestens 10 Zeichen; das Lehrbeispiel der Next.js-Anleitung verlangt nur 8.
  • Bereits kompromittierte Passwörter werden abgelehnt.
  • Fehlgeschlagene Anmeldeversuche werden registriert und beim nächsten erfolgreichen Login angezeigt; nach einer festgelegten Zahl folgt eine zeitweise Sperre.
  • Ein neues Passwort per E-Mail ist ungeeignet; Stand der Technik sind Links, die nur einmal und höchstens eine Stunde gelten.
  • Zwei-Faktor-Anmeldung wird angeboten, bevorzugt TOTP ohne Mobilfunknummer, außerdem WebAuthn; bei hohem Risiko hält die Orientierungshilfe sie für notwendig.
  • Anmeldedaten liegen logisch getrennt von den Inhaltsdaten.

Secure und der Präfix __Host- funktionieren nur über HTTPS. Wie verbreitet Lücken dabei sind, zeigt ein Projekt des HBDI: Er hat einen Webseiten-Check mit hessischen Vereinen erprobt, Stand 23.09.2025, der prüft, ob die Verbindung beim Senden persönlicher Daten sicher verschlüsselt ist. Geprüft werden drei Punkte: ob die Seite noch ohne HTTPS erreichbar ist, ob die Verschlüsselungsverfahren dem Stand der Technik entsprechen und welche TLS-Version läuft. Die Umsetzungshinweise dazu stellt der HBDI öffentlich bereit. Für einen Mitgliederbereich prüfe ich alle drei Punkte vor dem Livegang.

#Prüfliste für den Login Ihrer Anwendung

PrüfpunktWoran Sie es erkennen
Sitzungsart passt zum SperrbedarfKann ein Zugang noch am selben Tag beendet werden?
Cookie mit HttpOnly, Secure, SameSite, Ablauf und PathIn den Entwicklerwerkzeugen des Browsers sichtbar
Keine E-Mail-Adresse und kein Name im Sitzungs-TokenToken dekodieren und lesen
Sitzung in der DAL geprüft, nicht im LayoutSuche nach Prüfungen in layout.tsx
Abfragen geben nur benötigte Felder zurückRückgabewerte der DAL-Funktionen lesen
Neutrale Meldungen bei Login, Reset und RegistrierungMit einer unbekannten Adresse testen
Reset-Links einmalig und höchstens eine Stunde gültigLink zweimal öffnen
Zwei-Faktor-Anmeldung verfügbarKontoeinstellungen
Bei Entra ID ein eigener IssuerUmgebungsvariable AUTH_MICROSOFT_ENTRA_ID_ISSUER
Seite nicht ohne HTTPS erreichbarAdresse mit http:// aufrufen

#Wie ein Login-Projekt bei mir abläuft

Ich arbeite allein, aus der Ferne und schriftlich, ohne Termine und Telefonate. Sie schreiben mir, wer sich anmelden soll, welche Bereiche geschützt werden und ob es schon eine Benutzerverwaltung gibt. Ich antworte mit Rückfragen und einer schriftlichen Beschreibung von Umfang und Annahmen, darin eine Rollentabelle: welche Rolle welche Seite und welche Daten sieht. Gebaut wird auf einer Staging-Umgebung mit Testkonten für jede Rolle. Sie prüfen dort, geben schriftlich frei, dann folgt der Livegang. Auf Wunsch übernehme ich danach Updates und Sicherheitsreleases; Stunden wandern dabei nicht in den nächsten Monat.

Zum Start brauche ich Zugang zum Repository oder zur bestehenden Anwendung, die Rollentabelle als Entwurf, bei Microsoft-Konten einen Ansprechpartner in Ihrer IT, der die App-Registrierung anlegt, und das Layout der Login-Seiten als Wireframe. Gestaltung liefern Sie, ich setze sie um.

#Weitere Seiten zu Wiesbaden und Next.js

Wie eine Next.js-Anwendung Fehler protokolliert, ohne Personendaten ins Log zu schreiben, steht auf der Seite für Essen; für ein PHP-Backend dahinter gibt es die Seite zu PHP in Wiesbaden. Sicherheitsheader und Content Security Policy beschreibe ich für Frankfurt. Für eine klassische Website ohne Login ist die Seite zu WordPress in Wiesbaden der bessere Einstieg.

#Fragen zu Login und Sitzungen

Reicht es, angemeldete Nutzer in proxy.ts weiterzuleiten? Nein. Die Next.js-Anleitung beschreibt Proxy als optionalen Ort für schnelle Weiterleitungen anhand des Cookies und sagt ausdrücklich, dass er nicht die einzige Verteidigungslinie sein soll. Die eigentliche Prüfung gehört in die Datenzugriffsschicht, so nah wie möglich an die Daten.

Soll die Sitzung im Cookie oder in der Datenbank liegen? Das hängt davon ab, ob Sie Zugänge sofort sperren müssen. Eine Sitzung im Cookie gilt bis zu ihrem Ablauf. Eine Datenbanksitzung lässt sich auf dem Server löschen, auch für alle Geräte einer Person. Für ein Intranet nehme ich deshalb meist die Datenbank, für einen kleinen Mitgliederbereich reicht oft das Cookie mit kurzer Laufzeit.

Kann ich für ein neues Projekt noch Auth.js verwenden? Ja, das Better-Auth-Team pflegt Auth.js weiter mit Sicherheitskorrekturen und dringenden Fehlerbehebungen. Für neue Projekte empfiehlt es aber Better Auth. Die Next.js-Integration von Auth.js wird als next-auth@beta installiert; im November 2026 ist das Version 5.0.0-beta.32.

Darf das Anmeldeformular melden, dass eine E-Mail-Adresse unbekannt ist? Der HBDI rät davon ab. Solche Meldungen verraten, ob ein Konto existiert, und das kann eine Verletzung der Vertraulichkeit sein. Er empfiehlt neutrale Formulierungen, etwa dass die Kombination aus Kennung und Passwort falsch ist.

Muss ich eine Zwei-Faktor-Anmeldung anbieten? Die Orientierungshilfe der Datenschutzkonferenz von 2019 sagt, dass sie angeboten werden soll, und bei Verarbeitungen mit hohem Risiko hält sie sie für notwendig. Bevorzugt werden offene Verfahren wie TOTP, die keine Mobilfunknummer brauchen, und WebAuthn.

Gestalten Sie auch die Login-Seite? Nein. Die Gestaltung der Login-Seiten, Mockups und Wireframes kommen von Ihnen. In einer Tabellenvorlage tragen Sie ein, welches Element wohin gehört, und ich setze das responsiv um, einschließlich der Fehlermeldungen und Zustände.

#Schreiben Sie mir zu Ihrem Login

Soll Ihr Intranet, Ihr Mitgliederbereich oder Ihr Kundenportal in Wiesbaden eine Anmeldung bekommen, oder wollen Sie eine bestehende prüfen lassen? Schreiben Sie mir über das Kontaktformular: die Adresse der Anwendung, wer sich anmelden soll, den vorhandenen Stack und Ihren Wunschtermin. Die erste schriftliche Schätzung ist kostenlos, und ich antworte an Werktagen mit meinen Rückfragen.

Brauchen Sie die Leistung: Next.js-Entwickler in Wiesbaden?

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

Projekt beschreiben

Weitere WordPress-Dienste und Wissensbasis entdecken