LoginGen Dokumentation
Einführung
LoginGen ist eine Vorlagen-Website für Login-Seiten. Der Grund für die Entwicklung dieses Projekts ist, dass es zwar viele Vorlagen-Websites auf dem Markt gibt, die meisten jedoch keine ausreichende Unterstützung für Login-Seiten bieten oder nur ein oder zwei einfache Vorlagen enthalten, oft ohne vollständige Frontend-Logik. Obwohl Login-Seiten in Bezug auf die Interaktionsgewichtung möglicherweise nicht so wichtig sind wie Landing Pages, kann eine ansprechende Login-Seite den ersten Eindruck der Nutzer von einer Website deutlich verbessern.
Die Technologie-Stack basiert hauptsächlich auf Next.js und Shadcn/ui. Neben den Vorlagen bietet LoginGen auch eine vollständige Frontend-Logik und nutzt die Server Actions-Funktionalität von Next.js für eine einheitliche serverseitige Authentifizierung (mit Ausnahme der sozialen Anmeldung, die aus Gründen der Benutzerfreundlichkeit als Client-seitiges Ereignis implementiert ist).
Der gesamte Code ist offen und kann wie bei Shadcn einfach kopiert und eingefügt werden, sodass Sie ihn nach den Anforderungen Ihres Projekts anpassen können – was auch empfohlen wird. Zur Vereinfachung wurden zudem einige häufig verwendete Eigenschaften der Formularkomponenten extrahiert, sodass sie sofort einsatzbereit sind.
In Zukunft werden kontinuierlich weitere Vorlagen hinzugefügt, verbessert und optimiert. Bleiben Sie gespannt!
Installation
Die Vorlagen basieren auf Next.js und Shadcn. Daher benötigen Sie zunächst die entsprechende Projektumgebung:
- "next": "^14.2+"
- "tailwindcss": "^3.4+"
- "react-hook-form: 7.52.2" – Verwenden Sie vorerst keine höhere Version, da diese beim Rendern Bugs aufweist (Issues: https://github.com/react-hook-form/react-hook-form/issues/12518)
Shadcn-Komponenten
Falls Sie andere Paketmanager verwenden oder die Komponenten manuell installieren möchten, lesen Sie bitte die Shadcn-Dokumentation.
pnpm dlx shadcn@latest add card tabs form button input input-otp separator sonner
Fügen Sie die folgenden CSS-Animationen zu Ihrer tailwind.config.js
-Datei hinzu:
// for input-otp
/** @type {import('tailwindcss').Config} */
module.exports = {
theme: {
extend: {
keyframes: {
'caret-blink': {
'0%,70%,100%': { opacity: '1' },
'20%,50%': { opacity: '0' }
}
},
animation: {
'caret-blink': 'caret-blink 1.25s ease-out infinite'
}
}
}
}
Für Sonner müssen Sie die folgende Komponente hinzufügen:
import { Toaster } from '@/components/ui/sonner'
export default function RootLayout({ children }) {
return (
<html lang='en'>
<head />
<body>
<main>{children}</main>
<Toaster />
</body>
</html>
)
}
Drittanbieter-Bibliotheken
pnpm add react-hook-form@7.52.2 zod motion @zxcvbn-ts/core @zxcvbn-ts/language-common @zxcvbn-ts/language-en embla-carousel-react embla-carousel-autoplay embla-carousel-fade lucide-react
pnpm add -D embla-carousel
react-hook-form
+zod
– Client-seitige Formularvalidierungmotion
– Animationsbibliothek@zxcvbn-*
– Bibliothek zur Passwortstärkeüberprüfungembla-carousel-*
– Karussell-Bibliothek (embla-carousel
muss indevDependencies
installiert werden, um die TypeScript-Typen korrekt zu erhalten)lucide-react
– Icon-Bibliothek
Code kopieren und einfügen
Jede Vorlagen-Vorschauseite zeigt den vollständigen Code an. Sie können den benötigten Code einfach kopieren und an der entsprechenden Stelle in Ihrem Projekt einfügen. Die in den Vorlagen enthaltenen Bilder können direkt heruntergeladen werden, und Videos werden über CDN bereitgestellt.
Derzeit gibt es keine npx
-ähnliche Ein-Klick-Installationsfunktion, dies könnte jedoch in Zukunft
implementiert werden.
Design
Jede Vorlage enthält eine styles/theme.module.css
-Datei, die alle Designvariablen sowie die für die Vorlage
erforderlichen Stile und Animationen enthält. Sie können die Stile in dieser Datei anpassen, um das Design zu
ändern oder es an die UI-Ästhetik Ihrer Website anzupassen.
Dunkelmodus
Für den Dunkelmodus folgen Sie bitte der Shadcn-Dokumentation. In
den theme.module.css
-Dateien der Vorlagen wird das Dunkeldesign mit dem :global(.dark)
-CSS-Selektor
versehen, um auf den globalen Dunkelmodus der Website zu reagieren.
I18n (TODO)
Derzeit wird die Mehrsprachigkeit noch nicht unterstützt, Sie können sie jedoch manuell hinzufügen, auch wenn dies etwas aufwändiger sein kann. Diese Funktion wird möglicherweise in Zukunft implementiert.
Formulareigenschaften
Es gibt fünf Formulare: Anmeldung, Registrierung, Passwort vergessen, Passwort zurücksetzen und OTP (One-Time Password)-Verifizierung. Jedes Formular verfügt über einige Parameter, die sofort einsatzbereit sind. Die meisten Parameter sind allgemein gültig.
Obwohl in den Vorlagen jedes Formular standardmäßig eine separate Route ist und die Navigation zwischen den Formularseiten serverseitig über Weiterleitungen erfolgt, sind alle Komponenten so gestaltet, dass sie Eigenschaften übergeben können. Das bedeutet, dass Sie auch Client-seitiges Routing verwenden können.
Anmeldung
Die Schnittstelle ist wie folgt definiert:
const _auths = ['social', 'email', 'password'] as const
type Auth = (typeof _auths)[number]
export interface SignInFormProps {
auths?: Readonly<Auth[]>
socials?: SocialKey[]
email?: string
emailStrategy?: 'magic-link' | 'one-time-pwd'
socialHandler?: (event: MouseEvent<HTMLButtonElement>, key: SocialKey) => void | Promise<void>
forgetHandler?: string | ((event: React.MouseEvent<HTMLAnchorElement>) => void | Promise<void>) // for more convenient use
serverAction?: (
formType: 'email' | 'password',
currentState: SignInActionState,
formData: FormData
) => Promise<SignInActionState>
serverStateSuccessHandler?: (formType: 'email' | 'password', email: string) => void | Promise<void>
}
Parameter | Standardwert | Erklärung |
---|---|---|
auths | ['social', 'password', 'email'] | Authentifizierungsmethoden: Soziale Anmeldung, E-Mail-Anmeldung, Passwort-Anmeldung |
socials | ['google', 'github'] | Arten der sozialen Anmeldung (das Layout passt sich automatisch an die Anzahl der ausgewählten Optionen und die Formularbreite an) |
Initiale E-Mail-Adresse, kann auch zur Vorabfüllung verwendet werden, wenn von der OTP-Verifizierungsseite zurückgekehrt wird | ||
emailStrategy | 'magic-link' | Art der gesendeten E-Mail: Bei 'magic-link' erfolgt keine Seitenumleitung, sondern ein Sonner-Popup. Andernfalls wird zur OTP-Verifizierungsseite weitergeleitet |
socialHandler | Callback-Funktion beim Klicken auf den sozialen Anmeldebutton (z. B. mit Bibliotheken wie Auth.js implementierbar) | |
forgetHandler | '#' | Callback beim Klicken auf "Passwort vergessen" (dient hauptsächlich der Benutzerfreundlichkeit) |
serverAction | Alle Formulare (außer soziale Anmeldung) werden über Server Actions serverseitig übermittelt | |
serverStateSuccessHandler | Normalerweise erfolgt nach erfolgreicher serverseitiger Authentifizierung eine serverseitige Weiterleitung. Falls Sie Client-seitige Weiterleitungslogik implementieren möchten, können Sie diesen Callback verwenden |
Hinweise:
socials
– Jede Vorlage enthält eineconfig/social.tsx
-Konfigurationsdatei, die Sie bearbeiten können, um zusätzliche soziale Anmeldemethoden hinzuzufügen. Sie können denkey
an Ihr Authentifizierungsframework anpassen und das SVG-Icon nach Belieben ändern.email
– In derverify-otp
-Formular-UI gibt es eine Schaltfläche zum Ändern der E-Mail-Adresse. Wenn der Benutzer darauf klickt, sollte er zur vorherigen Seite zurückkehren, um die E-Mail-Adresse zu korrigieren. Deremail
-Parameter dient dazu, die vorherige E-Mail-Adresse vorab anzuzeigen.
Registrierung
Die Schnittstelle ist wie folgt definiert:
export interface SignUpFormProps {
email?: string
serverAction: (currentState: SignUpActionState, formData: FormData) => Promise<SignUpActionState>
serverStateSuccessHandler?: (email: string) => void | Promise<void>
}
Parameter | Standardwert | Erklärung |
---|---|---|
Initiale E-Mail-Adresse, kann auch zur Vorabfüllung verwendet werden, wenn von der OTP-Verifizierungsseite zurückgekehrt wird | ||
serverAction | Formulardaten werden über Server Actions serverseitig übermittelt | |
serverStateSuccessHandler | Normalerweise erfolgt nach erfolgreicher serverseitiger Authentifizierung eine serverseitige Weiterleitung. Falls Sie Client-seitige Weiterleitungslogik implementieren möchten, können Sie diesen Callback verwenden |
Passwort vergessen
Die Schnittstelle ist wie folgt definiert:
export interface ForgetPasswordProps {
email?: string
emailStrategy?: 'magic-link' | 'one-time-pwd'
serverAction: (
currentState: ForgetPasswordActionState,
formData: FormData
) => Promise<ForgetPasswordActionState>
serverStateSuccessHandler?: (email: string) => void | Promise<void>
}
Parameter | Standardwert | Erklärung |
---|---|---|
Initiale E-Mail-Adresse, kann auch zur Vorabfüllung verwendet werden, wenn von der OTP-Verifizierungsseite zurückgekehrt wird | ||
emailStrategy | 'magic-link' | Art der gesendeten E-Mail: Bei 'magic-link' erfolgt keine Seitenumleitung, sondern ein Sonner-Popup. Andernfalls wird zur OTP-Verifizierungsseite weitergeleitet |
serverAction | Formulardaten werden über Server Actions serverseitig übermittelt | |
serverStateSuccessHandler | Normalerweise erfolgt nach erfolgreicher serverseitiger Authentifizierung eine serverseitige Weiterleitung. Falls Sie Client-seitige Weiterleitungslogik implementieren möchten, können Sie diesen Callback verwenden |
Passwort zurücksetzen
Die Schnittstelle ist wie folgt definiert:
export interface ResetPasswordFormProps {
email?: string // Only used to test password strength
resetToken?: string
serverAction: (
resetToken: string,
currentState: ResetPasswordActionState,
formData: FormData
) => Promise<ResetPasswordActionState>
serverStateSuccessHandler?: () => void | Promise<void>
}
Parameter | Standardwert | Erklärung |
---|---|---|
Diese E-Mail dient nur zur Überprüfung der Passwortstärke (empfohlen für bessere Passworteingaben der Benutzer) | ||
resetToken | Vom Server generiertes Token zur Verfolgung des Formularablaufs | |
serverAction | Formulardaten werden über Server Actions serverseitig übermittelt | |
serverStateSuccessHandler | Normalerweise erfolgt nach erfolgreicher serverseitiger Authentifizierung eine serverseitige Weiterleitung. Falls Sie Client-seitige Weiterleitungslogik implementieren möchten, können Sie diesen Callback verwenden |
resetToken Im Passwort-zurücksetzen-Ablauf generiert der Server normalerweise ein
token
, um den Absender des Formulars und dessen Status sicher zu verfolgen und zu bestätigen.Der Server übermittelt das
token
typischerweise auf zwei Arten: entweder als URL-Abfrageparameter oder imcookie
. Beim Absenden des Formulars überträgt der Browser automatisch den aktuellencookie
.Im ersten Fall können Sie
searchParams
oderuseSearchParams()
verwenden, um denresetToken
aus den Abfrageparametern abzurufen und an das Formular zu übergeben. Das Formular leitet denresetToken
dann beim Absenden automatisch an die Server Action weiter.Im zweiten Fall können Sie diesen Parameter ignorieren.
OTP-Verifizierung
Die Schnittstelle ist wie folgt definiert:
export interface VerifyOTPFormProps {
email: string
verifyToken?: string
editEmailHandler?: (event: MouseEvent<HTMLButtonElement>) => void
serverAction: (
email: string,
verifyToken: string,
currentState: VerifyOTPActionState,
formData: FormData
) => Promise<VerifyOTPActionState>
codeResendAction: (email: string, verifyToken: string) => Promise<VerifyOTPActionState>
serverStateSuccessHandler?: () => void | Promise<void>
}
Parameter | Standardwert | Erklärung |
---|---|---|
Initiale E-Mail-Adresse, die in der UI angezeigt wird, damit Benutzer sie bearbeiten können | ||
verifyToken | Vom Server generiertes Token zur Verfolgung des Formularablaufs | |
editEmailHandler | Event-Handler für den "E-Mail bearbeiten"-Button | |
codeResendAction | Funktion zum erneuten Senden des Codes (die Sekunden können über die Konstante code_resend_max_seconds in verify-otp-form.tsx eingestellt werden) | |
serverAction | Formulardaten werden über Server Actions serverseitig übermittelt | |
serverStateSuccessHandler | Normalerweise erfolgt nach erfolgreicher serverseitiger Authentifizierung eine serverseitige Weiterleitung. Falls Sie Client-seitige Weiterleitungslogik implementieren möchten, können Sie diesen Callback verwenden |
verifyToken Bei der Verifizierung eines One-Time Passwords generiert der Server normalerweise ein
token
, um den Absender des Formulars und dessen Status sicher zu verfolgen und zu bestätigen.Der Server übermittelt das
token
typischerweise auf zwei Arten: entweder als URL-Abfrageparameter oder imcookie
. Beim Absenden des Formulars überträgt der Browser automatisch den aktuellencookie
.Im ersten Fall können Sie
searchParams
oderuseSearchParams()
verwenden, um denverifyToken
aus den Abfrageparametern abzurufen und an das Formular zu übergeben. Das Formular leitet denverifyToken
dann beim Absenden automatisch an die Server Action weiter.Im zweiten Fall können Sie diesen Parameter ignorieren.
Serverseitige Logik
Mit Ausnahme der sozialen Anmeldung werden alle Authentifizierungsoptionen nach der Client-seitigen
Validierung über Server Actions an die serverseitige Logik übermittelt. Dabei kommen Reacts useFormState
und
useFormStatus
für die Formularübermittlung zum Einsatz.
In der Vorlagendatei types/action-state.ts
ist das Datenformat für Server Actions grundlegend definiert, das
Sie bei Bedarf erweitern können.
Hier ist ein Beispielcode für eine Server Action:
sign-in-action.ts
'use server'
import type { FormType, SignInActionState } from '@/types/server'
import { redirect } from 'next/navigation'
import { revalidatePath } from 'next/cache'
export async function signInAction(
formType: FormType,
currentState: SignInActionState,
formData: FormData
): Promise<SignInActionState> {
switch (formType) {
case 'email':
return await emailAction(formData)
case 'password':
return await passwordAction(formData)
}
}
async function emailAction(formData: FormData): Promise<SignInActionState> {
const data = Object.fromEntries(formData)
const parsed = signInSchemas.email.safeParse(data)
// Die Formularvalidierung ist auch serverseitig erforderlich
if (!parsed.success) {
const issues: Record<string, string> = {}
parsed.error.issues.map((issue) => (issues[issue.path[0]] = issue.message))
return {
success: false,
formIssues: issues
}
}
// Führen Sie serverseitige Operationen durch, z.B. E-Mails versenden, Datenbankoperationen etc.
// Die Weiterleitung kann serverseitig erfolgen
revalidatePath('/auth/sign-in')
redirect(`/auth/verify-otp`)
// Oder direkt an den Client zurückgeben
// return { success: true }
}
async function passwordAction(formData: FormData): Promise<SignInActionState> {
const data = Object.fromEntries(formData)
// Mock-Verzögerung
await new Promise((resolve) => setTimeout(resolve, 2000))
console.log('Sign in password server action form data : ' + JSON.stringify(data, null, 2))
return { success: true }
}