Skip to main content 홈 크리에이터 jeremylongshore claude-code-plugins-plus-skills clerk-core-workflow-a
clerk-core-workflow-a Implement user sign-up and sign-in flows with Clerk.
Use when building authentication UI, customizing sign-in experience,
or implementing OAuth social login.
Trigger with phrases like "clerk sign-in", "clerk sign-up",
"clerk login flow", "clerk OAuth", "clerk social login".
설치로 이동 Skills Marketplace 커뮤니티가 만든 AI 스킬을 발견하고 탐색하세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/jeremylongshore/claude-code-plugins-plus-skills --skill clerk-core-workflow-a명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Zip 다운로드 다운로드 중... 이 저장소의 다른 Skills Implement session management and middleware with Clerk.
Use when managing user sessions, configuring route protection,
or implementing token refresh and custom JWT templates.
Trigger with phrases like "clerk session", "clerk middleware",
"clerk route protection", "clerk token", "clerk JWT".
Configure enterprise SSO, role-based access control, and organization management.
Use when implementing SSO integration, configuring role-based permissions,
or setting up organization-level controls.
Trigger with phrases like "clerk SSO", "clerk RBAC",
"clerk enterprise", "clerk roles", "clerk permissions", "clerk organizations".
Create your first authenticated request with Clerk.
Use when making initial API calls, testing authentication,
or verifying Clerk integration works correctly.
Trigger with phrases like "clerk hello world", "first clerk request",
"test clerk auth", "verify clerk setup".
jeremylongshore
jeremylongshore/claude-code-plugins-plus-skills
GitHub 저장소 열기 name clerk-core-workflow-a description Implement user sign-up and sign-in flows with Clerk.
Use when building authentication UI, customizing sign-in experience,
or implementing OAuth social login.
Trigger with phrases like "clerk sign-in", "clerk sign-up",
"clerk login flow", "clerk OAuth", "clerk social login".
allowed-tools Read, Write, Edit, Grep version 1.14.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","clerk","authentication"] compatibility Designed for Claude Code, also compatible with Codex and OpenClaw
Clerk Core Workflow A: Sign-Up & Sign-In
Overview
Implement authentication flows with Clerk: pre-built components for rapid setup, custom forms for full UI control, OAuth social login, email/phone verification, and multi-factor authentication.
Prerequisites
Clerk SDK installed and configured (clerk-install-auth completed)
OAuth providers enabled in Dashboard > User & Authentication > Social Connections
Sign-in/sign-up environment variables set
Instructions
Step 1: Pre-Built Components (Quick Start)
import { SignIn } from '@clerk/nextjs'
export default function SignInPage ( ) {
return (
<div className ="flex min-h-screen items-center justify-center" >
<SignIn
appearance ={{
elements: {
rootBox: 'mx-auto ',
card: 'shadow-xl rounded-2xl ',
headerTitle: 'text-2xl ',
socialButtonsBlockButton: 'rounded-lg ',
},
}}
routing ="path"
path ="/sign-in"
signUpUrl ="/sign-up"
/>
</div >
)
}
{ }
( ) {
(
)
}
import
SignUp
from
'@clerk/nextjs'
export
default
function
SignUpPage
return
<div className ="flex min-h-screen items-center justify-center" >
<SignUp routing ="path" path ="/sign-up" signInUrl ="/sign-in" />
</div >
NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/onboarding
Step 2: Custom Sign-In Form (Full UI Control) 'use client'
import { useSignIn } from '@clerk/nextjs'
import { useRouter } from 'next/navigation'
import { useState } from 'react'
export function CustomSignIn ( ) {
const { signIn, setActive, isLoaded } = useSignIn ()
const router = useRouter ()
const [email, setEmail] = useState ('' )
const [password, setPassword] = useState ('' )
const [error, setError] = useState ('' )
const [loading, setLoading] = useState (false )
if (!isLoaded) return null
const handleSubmit = async (e : React .FormEvent ) => {
e.preventDefault ()
setError ('' )
setLoading (true )
try {
const result = await signIn.create ({
identifier : email,
password,
})
if (result.status === 'complete' ) {
await setActive ({ session : result.createdSessionId })
router.push ('/dashboard' )
} else if (result.status === 'needs_second_factor' ) {
router.push ('/sign-in/mfa' )
} else if (result.status === 'needs_identifier' ) {
setError ('Please enter your email address' )
}
} catch (err : any ) {
const clerkError = err.errors ?.[0 ]
switch (clerkError?.code ) {
case 'form_identifier_not_found' :
setError ('No account found with this email' )
break
case 'form_password_incorrect' :
setError ('Incorrect password' )
break
case 'session_exists' :
router.push ('/dashboard' )
break
default :
setError (clerkError?.message || 'Sign-in failed' )
}
} finally {
setLoading (false )
}
}
return (
<form onSubmit ={handleSubmit} className ="space-y-4 max-w-sm mx-auto" >
<input
type ="email" value ={email}
onChange ={e => setEmail(e.target.value)}
placeholder="Email address" required
className="w-full p-2 border rounded"
/>
<input
type ="password" value ={password}
onChange ={e => setPassword(e.target.value)}
placeholder="Password" required
className="w-full p-2 border rounded"
/>
{error && <p className ="text-red-500 text-sm" > {error}</p > }
<button type ="submit" disabled ={loading} className ="w-full p-2 bg-blue-600 text-white rounded" >
{loading ? 'Signing in...' : 'Sign In'}
</button >
</form >
)
}
Step 3: OAuth Social Login 'use client'
import { useSignIn } from '@clerk/nextjs'
export function OAuthButtons ( ) {
const { signIn, isLoaded } = useSignIn ()
if (!isLoaded) return null
const signInWith = (strategy : 'oauth_google' | 'oauth_github' | 'oauth_apple' ) => {
signIn.authenticateWithRedirect ({
strategy,
redirectUrl : '/sso-callback' ,
redirectUrlComplete : '/dashboard' ,
})
}
return (
<div className ="flex flex-col gap-3" >
<button onClick ={() => signInWith('oauth_google')} className="p-2 border rounded">
Continue with Google
</button >
<button onClick ={() => signInWith('oauth_github')} className="p-2 border rounded">
Continue with GitHub
</button >
<button onClick ={() => signInWith('oauth_apple')} className="p-2 border rounded">
Continue with Apple
</button >
</div >
)
}
import { AuthenticateWithRedirectCallback } from '@clerk/nextjs'
export default function SSOCallback ( ) {
return <AuthenticateWithRedirectCallback />
}
Step 4: Custom Sign-Up with Email Verification 'use client'
import { useSignUp } from '@clerk/nextjs'
import { useRouter } from 'next/navigation'
import { useState } from 'react'
export function CustomSignUp ( ) {
const { signUp, setActive, isLoaded } = useSignUp ()
const router = useRouter ()
const [step, setStep] = useState<'form' | 'verify' >('form' )
const [email, setEmail] = useState ('' )
const [password, setPassword] = useState ('' )
const [code, setCode] = useState ('' )
const [error, setError] = useState ('' )
if (!isLoaded) return null
const handleSignUp = async (e : React .FormEvent ) => {
e.preventDefault ()
try {
await signUp.create ({ emailAddress : email, password })
await signUp.prepareEmailAddressVerification ({ strategy : 'email_code' })
setStep ('verify' )
} catch (err : any ) {
setError (err.errors ?.[0 ]?.longMessage || 'Sign-up failed' )
}
}
const handleVerify = async (e : React .FormEvent ) => {
e.preventDefault ()
try {
const result = await signUp.attemptEmailAddressVerification ({ code })
if (result.status === 'complete' ) {
await setActive ({ session : result.createdSessionId })
router.push ('/onboarding' )
}
} catch (err : any ) {
setError (err.errors ?.[0 ]?.longMessage || 'Verification failed' )
}
}
if (step === 'verify' ) {
return (
<form onSubmit ={handleVerify} className ="space-y-4" >
<p > Check your email for a verification code</p >
<input
value ={code} onChange ={e => setCode(e.target.value)}
placeholder="Enter 6-digit code" required
/>
{error && <p className ="text-red-500" > {error}</p > }
<button type ="submit" > Verify Email</button >
</form >
)
}
return (
<form onSubmit ={handleSignUp} className ="space-y-4" >
<input type ="email" value ={email} onChange ={e => setEmail(e.target.value)} placeholder="Email" required />
<input type ="password" value ={password} onChange ={e => setPassword(e.target.value)} placeholder="Password" required />
{error && <p className ="text-red-500" > {error}</p > }
<button type ="submit" > Create Account</button >
</form >
)
}
Step 5: Multi-Factor Authentication (TOTP) 'use client'
import { useSignIn } from '@clerk/nextjs'
import { useRouter } from 'next/navigation'
import { useState } from 'react'
export function MFAVerification ( ) {
const { signIn, setActive } = useSignIn ()
const router = useRouter ()
const [code, setCode] = useState ('' )
const [error, setError] = useState ('' )
const handleMFA = async (e : React .FormEvent ) => {
e.preventDefault ()
try {
const result = await signIn!.attemptSecondFactor ({
strategy : 'totp' ,
code,
})
if (result.status === 'complete' ) {
await setActive!({ session : result.createdSessionId })
router.push ('/dashboard' )
}
} catch (err : any ) {
setError (err.errors ?.[0 ]?.message || 'Invalid code' )
}
}
return (
<form onSubmit ={handleMFA} className ="space-y-4" >
<h2 > Two-Factor Authentication</h2 >
<p > Enter the code from your authenticator app</p >
<input
value ={code} onChange ={e => setCode(e.target.value)}
placeholder="6-digit TOTP code" maxLength={6} required
inputMode="numeric" pattern="[0-9]*"
/>
{error && <p className ="text-red-500" > {error}</p > }
<button type ="submit" > Verify</button >
</form >
)
}
Error Handling Error Cause Solution form_identifier_not_foundEmail not registered Show sign-up link or check Clerk instance form_password_incorrectWrong password Display error, offer password reset link session_existsAlready signed in Redirect to dashboard verification_failedWrong or expired code Allow retry; offer "Resend code" button oauth_callback_errorOAuth misconfigured Check redirect URIs in Dashboard > Social Connections identifier_already_signed_inMulti-session not enabled Enable multi-session or redirect to dashboard
Enterprise Considerations
Customize component appearance with Clerk's appearance prop or custom CSS -- matches your design system without building from scratch
For Enterprise SSO (SAML/OIDC), users authenticate through their IdP; the <SignIn> component handles the redirect automatically
Phone number verification uses phone_code strategy instead of email_code
Magic link sign-in uses email_link strategy for passwordless auth
Track sign-up conversion rates by subscribing to user.created webhooks
MFA enrollment is managed via <UserProfile /> component or user.createTOTP() API
Resources
Next Steps Proceed to clerk-core-workflow-b for session management and middleware.
Output
Working Clerk auth integration for the target stack (components + middleware/routes as applicable)
Documented env vars (CLERK_*) and session verification path
Checklist of production-hardening steps completed or explicitly deferred
Examples
Add Clerk to a Next.js App Router app User: Wire Clerk auth into my Next.js App Router app with protected /dashboard.
Skill: installs Clerk packages, adds middleware, wraps layout with ClerkProvider,
protects /dashboard, documents CLERK_SECRET_KEY + NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY.
Diagnose a broken session redirect User: Users bounce between /sign-in and /dashboard in a loop.
Skill: traces middleware matcher, publicRoutes, and afterSignInUrl; fixes redirect cycle.