clerk-hello-world

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Clerk Hello World

Clerk Hello World

Overview

概述

Make your first authenticated request using Clerk to verify the integration works.
使用Clerk发起你的第一个认证请求,以验证集成是否正常工作。

Prerequisites

前提条件

  • Clerk SDK installed (
    clerk-install-auth
    completed)
  • Environment variables configured
  • ClerkProvider wrapping application
  • 已安装Clerk SDK(完成
    clerk-install-auth
  • 已配置环境变量
  • 应用已被ClerkProvider包裹

Instructions

操作步骤

Step 1: Create Protected Page

步骤1:创建受保护页面

typescript
// app/dashboard/page.tsx
import { auth, currentUser } from '@clerk/nextjs/server'

export default async function DashboardPage() {
  const { userId } = await auth()
  const user = await currentUser()

  if (!userId) {
    return <div>Please sign in to access this page</div>
  }

  return (
    <div>
      <h1>Hello, {user?.firstName || 'User'}!</h1>
      <p>Your user ID: {userId}</p>
      <p>Email: {user?.emailAddresses[0]?.emailAddress}</p>
    </div>
  )
}
typescript
// app/dashboard/page.tsx
import { auth, currentUser } from '@clerk/nextjs/server'

export default async function DashboardPage() {
  const { userId } = await auth()
  const user = await currentUser()

  if (!userId) {
    return <div>Please sign in to access this page</div>
  }

  return (
    <div>
      <h1>Hello, {user?.firstName || 'User'}!</h1>
      <p>Your user ID: {userId}</p>
      <p>Email: {user?.emailAddresses[0]?.emailAddress}</p>
    </div>
  )
}

Step 2: Create Protected API Route

步骤2:创建受保护API路由

typescript
// app/api/hello/route.ts
import { auth } from '@clerk/nextjs/server'

export async function GET() {
  const { userId } = await auth()

  if (!userId) {
    return Response.json({ error: 'Unauthorized' }, { status: 401 })
  }

  return Response.json({
    message: 'Hello from Clerk!',
    userId,
    timestamp: new Date().toISOString()
  })
}
typescript
// app/api/hello/route.ts
import { auth } from '@clerk/nextjs/server'

export async function GET() {
  const { userId } = await auth()

  if (!userId) {
    return Response.json({ error: 'Unauthorized' }, { status: 401 })
  }

  return Response.json({
    message: 'Hello from Clerk!',
    userId,
    timestamp: new Date().toISOString()
  })
}

Step 3: Test Authentication Flow

步骤3:测试认证流程

typescript
// Client-side test component
'use client'
import { useUser, useAuth } from '@clerk/nextjs'

export function AuthTest() {
  const { user, isLoaded, isSignedIn } = useUser()
  const { getToken } = useAuth()

  if (!isLoaded) return <div>Loading...</div>
  if (!isSignedIn) return <div>Not signed in</div>

  const testAPI = async () => {
    const token = await getToken()
    const res = await fetch('/api/hello', {
      headers: { Authorization: `Bearer ${token}` }
    })
    console.log(await res.json())
  }

  return (
    <div>
      <p>Signed in as: {user.primaryEmailAddress?.emailAddress}</p>
      <button onClick={testAPI}>Test API</button>
    </div>
  )
}
typescript
// Client-side test component
'use client'
import { useUser, useAuth } from '@clerk/nextjs'

export function AuthTest() {
  const { user, isLoaded, isSignedIn } = useUser()
  const { getToken } = useAuth()

  if (!isLoaded) return <div>Loading...</div>
  if (!isSignedIn) return <div>Not signed in</div>

  const testAPI = async () => {
    const token = await getToken()
    const res = await fetch('/api/hello', {
      headers: { Authorization: `Bearer ${token}` }
    })
    console.log(await res.json())
  }

  return (
    <div>
      <p>Signed in as: {user.primaryEmailAddress?.emailAddress}</p>
      <button onClick={testAPI}>Test API</button>
    </div>
  )
}

Output

输出结果

  • Protected page showing user information
  • API route returning authenticated user data
  • Successful request/response verification
  • 显示用户信息的受保护页面
  • 返回认证用户数据的API路由
  • 验证请求/响应是否成功

Error Handling

错误处理

ErrorCauseSolution
userId is nullUser not authenticatedRedirect to sign-in or check middleware
currentUser returns nullSession expiredRefresh page or re-authenticate
401 UnauthorizedToken missing or invalidCheck Authorization header
Hydration ErrorServer/client mismatchUse 'use client' for client hooks
错误原因解决方案
userId 为 null用户未认证重定向到登录页面或检查中间件
currentUser 返回 null会话已过期刷新页面或重新认证
401 Unauthorized令牌缺失或无效检查Authorization请求头
Hydration Error服务端/客户端不匹配为客户端钩子使用'use client'指令

Examples

示例

Using with React Hooks

与React Hooks配合使用

typescript
'use client'
import { useUser, useClerk } from '@clerk/nextjs'

export function UserProfile() {
  const { user } = useUser()
  const { signOut } = useClerk()

  return (
    <div>
      <img src={user?.imageUrl} alt="Profile" />
      <h2>{user?.fullName}</h2>
      <button onClick={() => signOut()}>Sign Out</button>
    </div>
  )
}
typescript
'use client'
import { useUser, useClerk } from '@clerk/nextjs'

export function UserProfile() {
  const { user } = useUser()
  const { signOut } = useClerk()

  return (
    <div>
      <img src={user?.imageUrl} alt="Profile" />
      <h2>{user?.fullName}</h2>
      <button onClick={() => signOut()}>Sign Out</button>
    </div>
  )
}

Express.js Example

Express.js示例

typescript
import { clerkMiddleware, requireAuth } from '@clerk/express'

app.use(clerkMiddleware())

app.get('/api/protected', requireAuth(), (req, res) => {
  res.json({
    message: 'Hello!',
    userId: req.auth.userId
  })
})
typescript
import { clerkMiddleware, requireAuth } from '@clerk/express'

app.use(clerkMiddleware())

app.get('/api/protected', requireAuth(), (req, res) => {
  res.json({
    message: 'Hello!',
    userId: req.auth.userId
  })
})

Resources

参考资源

Next Steps

后续步骤

Proceed to
clerk-local-dev-loop
for local development workflow setup.
继续执行
clerk-local-dev-loop
以设置本地开发工作流。