Claude-skill-registry clerk-core-workflow-a
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/clerk-core-workflow-a" ~/.claude/skills/majiayu000-claude-skill-registry-clerk-core-workflow-a && rm -rf "$T"
manifest:
skills/data/clerk-core-workflow-a/SKILL.mdsource content
Clerk Core Workflow A: Sign-Up & Sign-In
Overview
Implement comprehensive user authentication flows including email, OAuth, and custom UI.
Prerequisites
- Clerk SDK installed and configured
- OAuth providers configured in Clerk dashboard (if using social login)
- Sign-in/sign-up URLs configured in environment
Instructions
Step 1: Pre-built Components (Quick Start)
// app/sign-in/[[...sign-in]]/page.tsx import { SignIn } from '@clerk/nextjs' export default function SignInPage() { return ( <div className="flex min-h-screen items-center justify-center"> <SignIn appearance={{ elements: { formButtonPrimary: 'bg-blue-500 hover:bg-blue-600', card: 'shadow-lg' } }} routing="path" path="/sign-in" signUpUrl="/sign-up" /> </div> ) } // app/sign-up/[[...sign-up]]/page.tsx import { SignUp } from '@clerk/nextjs' export default function SignUpPage() { return ( <div className="flex min-h-screen items-center justify-center"> <SignUp appearance={{ elements: { formButtonPrimary: 'bg-green-500 hover:bg-green-600' } }} routing="path" path="/sign-up" signInUrl="/sign-in" /> </div> ) }
Step 2: Custom Sign-In Form
'use client' import { useSignIn } from '@clerk/nextjs' import { useState } from 'react' import { useRouter } from 'next/navigation' export function CustomSignIn() { const { signIn, isLoaded, setActive } = useSignIn() const [email, setEmail] = useState('') const [password, setPassword] = useState('') const [error, setError] = useState('') const router = useRouter() const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() if (!isLoaded) return try { const result = await signIn.create({ identifier: email, password, }) if (result.status === 'complete') { await setActive({ session: result.createdSessionId }) router.push('/dashboard') } } catch (err: any) { setError(err.errors?.[0]?.message || 'Sign in failed') } } return ( <form onSubmit={handleSubmit}> <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Email" /> <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="Password" /> {error && <p className="text-red-500">{error}</p>} <button type="submit">Sign In</button> </form> ) }
Step 3: OAuth Social Login
'use client' import { useSignIn } from '@clerk/nextjs' export function SocialLogin() { const { signIn, isLoaded } = useSignIn() const handleOAuth = async (provider: 'oauth_google' | 'oauth_github' | 'oauth_apple') => { if (!isLoaded) return await signIn.authenticateWithRedirect({ strategy: provider, redirectUrl: '/sso-callback', redirectUrlComplete: '/dashboard' }) } return ( <div className="space-y-2"> <button onClick={() => handleOAuth('oauth_google')}> Continue with Google </button> <button onClick={() => handleOAuth('oauth_github')}> Continue with GitHub </button> <button onClick={() => handleOAuth('oauth_apple')}> Continue with Apple </button> </div> ) } // app/sso-callback/page.tsx import { AuthenticateWithRedirectCallback } from '@clerk/nextjs' export default function SSOCallback() { return <AuthenticateWithRedirectCallback /> }
Step 4: Email Verification Flow
'use client' import { useSignUp } from '@clerk/nextjs' import { useState } from 'react' export function EmailVerification() { const { signUp, isLoaded, setActive } = useSignUp() const [verificationCode, setVerificationCode] = useState('') const [pendingVerification, setPendingVerification] = useState(false) const handleSignUp = async (email: string, password: string) => { if (!isLoaded) return await signUp.create({ emailAddress: email, password, }) // Send email verification await signUp.prepareEmailAddressVerification({ strategy: 'email_code' }) setPendingVerification(true) } const handleVerify = async () => { if (!isLoaded) return const result = await signUp.attemptEmailAddressVerification({ code: verificationCode }) if (result.status === 'complete') { await setActive({ session: result.createdSessionId }) } } if (pendingVerification) { return ( <div> <input value={verificationCode} onChange={(e) => setVerificationCode(e.target.value)} placeholder="Verification code" /> <button onClick={handleVerify}>Verify</button> </div> ) } return <SignUpForm onSubmit={handleSignUp} /> }
Output
- Working sign-in/sign-up pages
- OAuth social login configured
- Email verification flow
- Custom authentication UI
Error Handling
| Error | Cause | Solution |
|---|---|---|
| form_identifier_not_found | Email not registered | Show sign-up prompt |
| form_password_incorrect | Wrong password | Show error, offer reset |
| session_exists | Already signed in | Redirect to dashboard |
| verification_failed | Wrong code | Allow retry, resend code |
Examples
Magic Link Authentication
const handleMagicLink = async (email: string) => { await signIn.create({ identifier: email, strategy: 'email_link', redirectUrl: `${window.location.origin}/verify-magic-link` }) } // app/verify-magic-link/page.tsx import { EmailLinkComplete } from '@clerk/nextjs' export default function VerifyMagicLink() { return <EmailLinkComplete /> }
Resources
Next Steps
Proceed to
clerk-core-workflow-b for session management and middleware.