clerk-tanstack-patterns

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

TanStack React Start Patterns

TanStack React Start 开发模式

What Do You Need?

你需要实现什么?

TaskReference
Protect routes with beforeLoadreferences/router-guards.md
Auth in createServerFnreferences/server-functions.md
Pass auth to loadersreferences/loaders.md
Configure Vinxi + clerkMiddlewarereferences/vinxi-server.md
任务参考文档
使用beforeLoad保护路由references/router-guards.md
在createServerFn中实现身份验证references/server-functions.md
向加载器传递身份验证信息references/loaders.md
配置Vinxi + clerkMiddlewarereferences/vinxi-server.md

References

参考文档列表

ReferenceDescription
references/router-guards.md
beforeLoad auth redirect
references/server-functions.md
createServerFn with auth()
references/loaders.md
Auth context in loaders
references/vinxi-server.md
clerkMiddleware() setup
参考文档说明
references/router-guards.md
beforeLoad身份验证重定向逻辑
references/server-functions.md
搭配auth()使用createServerFn
references/loaders.md
加载器中的身份验证上下文
references/vinxi-server.md
clerkMiddleware()配置方法

Setup

安装配置

npm install @clerk/tanstack-react-start
.env
:
CLERK_PUBLISHABLE_KEY=pk_...
CLERK_SECRET_KEY=sk_...
src/start.ts
(Vinxi entry):
typescript
import { clerkMiddleware } from '@clerk/tanstack-react-start/server'
import { createStart } from '@tanstack/react-start'

export const startInstance = createStart(() => {
  return {
    requestMiddleware: [clerkMiddleware()],
  }
})
src/routes/__root.tsx
— wrap with
<ClerkProvider>
:
tsx
import { ClerkProvider } from '@clerk/tanstack-react-start'

function RootDocument({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <ClerkProvider>
          {children}
        </ClerkProvider>
      </body>
    </html>
  )
}
npm install @clerk/tanstack-react-start
.env
配置:
CLERK_PUBLISHABLE_KEY=pk_...
CLERK_SECRET_KEY=sk_...
src/start.ts
(Vinxi入口文件):
typescript
import { clerkMiddleware } from '@clerk/tanstack-react-start/server'
import { createStart } from '@tanstack/react-start'

export const startInstance = createStart(() => {
  return {
    requestMiddleware: [clerkMiddleware()],
  }
})
src/routes/__root.tsx
— 用
<ClerkProvider>
包裹根组件:
tsx
import { ClerkProvider } from '@clerk/tanstack-react-start'

function RootDocument({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <ClerkProvider>
          {children}
        </ClerkProvider>
      </body>
    </html>
  )
}

Mental Model

核心逻辑模型

TanStack Start runs on Vinxi. Auth flows through two layers:
  1. Server layer
    createServerFn
    +
    auth()
    from
    @clerk/tanstack-react-start/server
  2. Router layer
    beforeLoad
    on route definitions, throws
    redirect
    for unauthenticated
Both layers are server-executed. Client hooks (
useAuth
,
useUser
) are React hooks for the browser side.
TanStack Start运行在Vinxi之上,身份验证流程分为两层:
  1. 服务层 — 来自
    @clerk/tanstack-react-start/server
    createServerFn
    +
    auth()
  2. 路由层 — 路由定义上的
    beforeLoad
    钩子,未认证用户会触发
    redirect
    重定向
两层均在服务端执行。客户端钩子(
useAuth
useUser
)是运行在浏览器端的React钩子。

Minimal Pattern

最简实现示例

typescript
import { createFileRoute, redirect } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'
import { auth } from '@clerk/tanstack-react-start/server'

const authStateFn = createServerFn().handler(async () => {
  const { isAuthenticated, userId } = await auth()
  if (!isAuthenticated) {
    throw redirect({ to: '/sign-in' })
  }
  return { userId }
})

export const Route = createFileRoute('/dashboard')({
  beforeLoad: async () => await authStateFn(),
})
typescript
import { createFileRoute, redirect } from '@tanstack/react-router'
import { createServerFn } from '@tanstack/react-start'
import { auth } from '@clerk/tanstack-react-start/server'

const authStateFn = createServerFn().handler(async () => {
  const { isAuthenticated, userId } = await auth()
  if (!isAuthenticated) {
    throw redirect({ to: '/sign-in' })
  }
  return { userId }
})

export const Route = createFileRoute('/dashboard')({
  beforeLoad: async () => await authStateFn(),
})

Common Pitfalls

常见问题

SymptomCauseFix
auth()
returns empty
Missing
clerkMiddleware
in start.ts
Add to
requestMiddleware
array
redirect
not thrown
Using
return
instead of
throw
throw redirect(...)
in TanStack
Wrong import for
auth
Mixing client/server importsServer:
@clerk/tanstack-react-start/server
Loader context missing userIdNot passing from beforeLoadReturn from beforeLoad, access via
context
ClerkProvider
missing
Forgot root wrappingAdd to
__root.tsx
shell component
问题表现原因解决方法
auth()
返回空值
start.ts中缺少
clerkMiddleware
配置
将其添加到
requestMiddleware
数组中
redirect
未触发
使用了
return
而非
throw
抛出重定向
在TanStack中使用
throw redirect(...)
写法
auth
导入错误
混淆了客户端/服务端导入路径服务端导入路径为
@clerk/tanstack-react-start/server
加载器上下文缺少userId未从beforeLoad中传递参数在beforeLoad中返回对应值,通过
context
访问
缺少
ClerkProvider
忘记在根组件包裹Provider
__root.tsx
外壳组件中添加ClerkProvider

See Also

拓展阅读

  • clerk-setup
    - Initial Clerk install
  • clerk-custom-ui
    - Custom flows & appearance
  • clerk-orgs
    - B2B organizations
  • clerk-setup
    - Clerk初始安装教程
  • clerk-custom-ui
    - 自定义流程与样式
  • clerk-orgs
    - B2B组织管理功能

Docs

官方文档