Claude Code Plugins

Community-maintained marketplace

Feedback

Create and manage authentication pages with server-side session handling. Use when adding login, register, or protected pages WITHOUT flicker/skeleton.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name auth-pages
description Create and manage authentication pages with server-side session handling. Use when adding login, register, or protected pages WITHOUT flicker/skeleton.
allowed-tools Read, Edit, Write, Glob

Authentication Pages (FSD)

Better Auth integration with Next.js 16 - Magic Link (passwordless) authentication.

Authentication Method

This project uses Magic Link authentication - users sign in by clicking a link sent to their email. No passwords!

FSD Paths

src/
├── app/(auth)/
│   ├── login/                  # Magic Link Login Page
│   ├── magic-link/verify/      # Magic Link Verification UI
│   └── verify-email/           # Email Verification UI
├── app/(protected)/
│   ├── dashboard/              # Protected Dashboard
│   └── settings/               # Session Management
├── features/auth/              # Auth Feature
│   ├── ui/
│   │   ├── login-form.tsx      # Orchestrates login flow
│   │   ├── login-card.tsx      # Email input form
│   │   └── email-sent-card.tsx # "Check your email" UI
│   ├── model/
│   │   ├── use-login.ts        # Login state & logic
│   │   └── use-auth-sync.ts    # Cross-tab sync
│   └── index.ts
├── features/user-settings/     # Session Management
│   ├── ui/
│   │   ├── sessions-list.tsx
│   │   └── session-card.tsx
│   ├── model/
│   │   └── use-sessions.ts
│   └── index.ts
├── shared/lib/
│   ├── auth-client/            # Client: signIn.magicLink, signOut
│   ├── auth-server/            # Server: getSession, auth config
│   └── geo/                    # User Agent parsing
└── widgets/header/             # Header with UserMenu

Magic Link Login Flow

1. User enters email → /login
2. signIn.magicLink() called
3. Backend webhook sends email
4. User clicks link → /magic-link/verify?token=...
5. Token verified → Session created → Redirect to /dashboard
6. Login notification sent (new device only)

Auth Client (Magic Link)

import { signIn, signOut } from "@shared/lib/auth-client"

// Request Magic Link
await signIn.magicLink({
  email,
  callbackURL: "/dashboard",
  newUserCallbackURL: "/dashboard",
  errorCallbackURL: "/login?error=verification_failed",
})

// Sign Out
await signOut()

Server-Side Session (NO FLICKER!)

Protected Page Pattern

// app/(protected)/dashboard/page.tsx - SERVER COMPONENT
import { getSession } from "@shared/lib/auth-server"
import { redirect } from "next/navigation"
import { Header } from "@widgets/header"

export default async function DashboardPage() {
  // Server-side Session Check - NO Flicker!
  const session = await getSession()
  if (!session) redirect("/login")

  return (
    <div className="min-h-screen bg-background">
      <Header user={session.user} />
      {/* Content */}
    </div>
  )
}

Session Management

Users can view and revoke sessions at /settings:

import { useSessions } from "@features/user-settings"

export function SessionsList() {
  const { sessions, revokeSession, revokeOtherSessions } = useSessions()

  return (
    <div>
      {sessions.map((session) => (
        <SessionCard
          key={session.id}
          session={session}
          onRevoke={revokeSession}
        />
      ))}
      <Button onClick={revokeOtherSessions}>
        Alle anderen Sessions beenden
      </Button>
    </div>
  )
}

Backend Webhooks

All emails are sent by the Go backend (Clean Architecture):

POST /api/v1/webhooks/send-magic-link
POST /api/v1/webhooks/send-verification-email
POST /api/v1/webhooks/session-created

Protected by X-Webhook-Secret header.

Rate Limiting

  • Magic Link: 3 requests per minute
  • Verification Email: 3 requests per minute

Cross-Tab Synchronization

// features/auth/model/use-auth-sync.ts
import { useAuthSync, broadcastSignOut } from "@features/auth"

// In Header component
useAuthSync() // Listen for auth changes

// On sign out
await signOut()
await broadcastSignOut() // Notify other tabs

Magic Link Verify Page

Custom UI for /magic-link/verify:

  • Loading: Spinner while verifying
  • Success: Immediate redirect to dashboard
  • Rate Limited: "Zu viele Anfragen" message
  • Expired: "Link abgelaufen" message
  • Invalid: "Ungültiger Link" message

Login Notifications

Email sent on new device/IP:

  • Checks if device/IP combination is known
  • Only sends notification for NEW devices
  • Includes "Sessions verwalten" button to /settings

IMPORTANT: What NOT to do

DO NOT use useSession() in Protected Pages → Causes flicker ❌ DO NOT use password fields → Magic Link only ❌ DO NOT send emails from frontend → Use backend webhooks ❌ DO NOT use direct SQL in auth hooks → Use webhooks

INSTEAD:

  • Server Component checks session with getSession()
  • redirect() if no session
  • Pass user as prop to Client Components
  • All emails via backend webhooks