-
Notifications
You must be signed in to change notification settings - Fork 377
chore(tanstack-react-start): Reuse existing auth object from server handler #6595
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: 77b6343 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
The latest updates on your projects. Learn more about Vercel for GitHub.
|
@clerk/agent-toolkit
@clerk/astro
@clerk/backend
@clerk/chrome-extension
@clerk/clerk-js
@clerk/dev-cli
@clerk/elements
@clerk/clerk-expo
@clerk/expo-passkeys
@clerk/express
@clerk/fastify
@clerk/localizations
@clerk/nextjs
@clerk/nuxt
@clerk/clerk-react
@clerk/react-router
@clerk/remix
@clerk/shared
@clerk/tanstack-react-start
@clerk/testing
@clerk/themes
@clerk/types
@clerk/upgrade
@clerk/vue
commit: |
📝 WalkthroughWalkthroughThe PR refactors server auth to propagate an auth object via server context: middleware authenticates early and sets event.context.auth so downstream getAuth obtains auth via getContext('auth') instead of re-running request-based authentication. authenticateRequest now returns a RequestState and no longer handles Netlify handshake redirects. createClerkHandler became async (returns a Promise) and the TanStack Start server template now awaits a handlerFactory inside a defineHandlerCallback. README, error messages, and several package versions were updated. Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. 📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (4)
packages/tanstack-react-start/src/server/getAuth.ts (1)
10-18
: Remove redundant type assertionThe variable is already annotated as GetAuthFn. The trailing as GetAuthFn is redundant and can confuse overload resolution.
Apply this diff:
-export const getAuth: GetAuthFn<Request> = ((request: Request, opts?: GetAuthOptions) => { +export const getAuth: GetAuthFn<Request> = ((request: Request, opts?: GetAuthOptions) => { ... -}) as GetAuthFn<Request>; +});packages/tanstack-react-start/src/server/middlewareHandler.ts (3)
33-35
: Type the event context and avoid re-computation of toAuth()Two improvements:
- Add a stable closure over the AuthObject so repeated getAuth calls don’t recompute toAuth().
- Augment the TanStack server event context type so event.context.auth is type-safe.
Apply this diff:
- // Set context for getAuth to use - event.context.auth = () => requestState.toAuth(); + // Set context for getAuth to use + const auth = requestState.toAuth(); + event.context.auth = () => auth;And add module augmentation (outside this file) so the context is typed. For example, create packages/tanstack-react-start/src/server/context.d.ts:
import type { AuthObject } from '@clerk/backend/internal'; declare module '@tanstack/react-start/server' { // Adjust the interface name below if TanStack exposes a different context shape interface ServerRequestEventContext { auth?: () => AuthObject; } }
33-35
: Consider namespacing the context key to avoid collisionsIf other middlewares also use an auth key, there’s a risk of overwrite. Not a blocker, but consider clerkAuth or clerk.auth for namespacing in a follow-up.
15-61
: Add tests covering context propagation and token narrowingAdd integration tests for:
- getAuth returns the same object as requestState.toAuth() when called within a handler.
- getAuth({ acceptsToken: 'session_token' | 'any' | ['session_token', 'api_key'] }) narrows per getAuthObjectForAcceptedToken.
- getAuth outside the handler (or without context) throws the new noAuthContextInGetAuth error.
I can scaffold tests using TanStack’s test utilities and a minimal router to verify context propagation.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
packages/tanstack-react-start/src/server/getAuth.ts
(1 hunks)packages/tanstack-react-start/src/server/middlewareHandler.ts
(3 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
**/*.{js,jsx,ts,tsx}
: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels
Files:
packages/tanstack-react-start/src/server/middlewareHandler.ts
packages/tanstack-react-start/src/server/getAuth.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use Prettier for consistent code formatting
Files:
packages/tanstack-react-start/src/server/middlewareHandler.ts
packages/tanstack-react-start/src/server/getAuth.ts
packages/**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
TypeScript is required for all packages
Files:
packages/tanstack-react-start/src/server/middlewareHandler.ts
packages/tanstack-react-start/src/server/getAuth.ts
packages/**/*.{ts,tsx,d.ts}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Packages should export TypeScript types alongside runtime code
Files:
packages/tanstack-react-start/src/server/middlewareHandler.ts
packages/tanstack-react-start/src/server/getAuth.ts
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use proper TypeScript error types
**/*.{ts,tsx}
: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoidany
type - preferunknown
when type is uncertain, then narrow with type guards
Useinterface
for object shapes that might be extended
Usetype
for unions, primitives, and computed types
Preferreadonly
properties for immutable data structures
Useprivate
for internal implementation details
Useprotected
for inheritance hierarchies
Usepublic
explicitly for clarity in public APIs
Preferreadonly
for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Useconst assertions
for literal types:as const
Usesatisfies
operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports:import type { ... } from ...
Noany
types without justification
Proper error handling with typed errors
Consistent use ofreadonly
for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)
Files:
packages/tanstack-react-start/src/server/middlewareHandler.ts
packages/tanstack-react-start/src/server/getAuth.ts
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)
Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.
Files:
packages/tanstack-react-start/src/server/middlewareHandler.ts
packages/tanstack-react-start/src/server/getAuth.ts
**/*
⚙️ CodeRabbit Configuration File
If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes.
Files:
packages/tanstack-react-start/src/server/middlewareHandler.ts
packages/tanstack-react-start/src/server/getAuth.ts
🧬 Code Graph Analysis (1)
packages/tanstack-react-start/src/server/getAuth.ts (2)
packages/backend/src/tokens/types.ts (2)
AuthenticateRequestOptions
(19-75)GetAuthFn
(200-237)packages/backend/src/tokens/authObjects.ts (1)
getAuthObjectForAcceptedToken
(462-492)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: Integration Tests (generic, chrome)
- GitHub Check: Unit Tests (22, **)
- GitHub Check: Static analysis
- GitHub Check: Unit Tests (18, --filter=@clerk/astro --filter=@clerk/backend --filter=@clerk/express --filter=@c...
- GitHub Check: Formatting | Dedupe | Changeset
- GitHub Check: semgrep/ci
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (3)
packages/tanstack-react-start/src/server/getAuth.ts (1)
10-18
: Synchronous getAuth refactor approved – no Promise-based callsites found
Ran the provided ripgrep scan across the repository:
- 0 hits for
Promise.all|race|allSettled
wrappinggetAuth(...)
- 0 hits for
getAuth(...).then(...)
- All remaining
getAuth(...)
calls are either top‐level orawait
ed, which is safe when the function returns a non-Promise.Backward-compatibility risk is therefore very low. As suggested, please note this change in the CHANGELOG and documentation:
- Add a bullet under “Removed
authenticateRequest
call” clarifying thatgetAuth()
is now fully synchronous and that awaiting it remains benign.- Optional: mention that usage in promise combinators (e.g.,
Promise.all([getAuth(), …])
) no longer defers execution as before.packages/tanstack-react-start/src/server/middlewareHandler.ts (2)
23-24
: Correct use of getEvent within the request scopeCreating the event inside the handler ensures the ALS-backed context is request-scoped. This is the right place to wire Clerk’s context.
26-31
: acceptsToken: 'any' at the edge is appropriateAuthenticating with acceptsToken: 'any' and deferring narrowing to getAuth via getAuthObjectForAcceptedToken keeps the middleware generic and lets route handlers opt-in to stricter token types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
integration/templates/tanstack-react-start/package.json (1)
11-13
: Version bumps look aligned with the new context-based auth flow; verify PR summary vs. actual minimums.Pinned template deps to 1.131.27 is fine for reproducible scaffolds. However, the PR summary says “Sets minimum TanStack Start dependencies to ^1.130.0” while the code uses 1.131.x in templates and ^1.131.0 in peerDependencies elsewhere. Please reconcile the wording or the ranges to avoid confusion for integrators.
If the true minimum is 1.131.0, update the PR description and any docs/checklists. If 1.130.x should be supported, consider pinning to 1.130.y here or bumping peer ranges accordingly.
integration/templates/tanstack-react-start/src/routes/user.tsx (1)
6-11
: Switching the serverFn handler and getAuth to synchronous is correct and removes an extra authenticateRequest() call.This aligns with the new context-provided auth object and avoids redundant verification work.
You can optionally enforce auth at the source by redirecting when there’s no userId. Since redirect is already imported, add:
const fetchClerkAuth = createServerFn({ method: 'GET' }).handler(() => { const request = getWebRequest(); if (!request) throw new Error('No request found'); const { userId } = getAuth(request); + if (!userId) { + throw redirect({ to: '/sign-in' }); + } return { userId, }; });Consider simplifying the route’s beforeLoad to just
beforeLoad: fetchClerkAuth
(no extra async/await needed), and confirm the desired UX (redirect vs. returning undefined) for unauthenticated users in this template.packages/tanstack-react-start/package.json (1)
79-85
: Peer range bump to ^1.131.0 looks appropriate; double‑check release semantics and docs.Given the getAuth API was made synchronous in this package (types likely changed from Promise to Auth), TypeScript consumers who chained .then on getAuth may see compile-time breaks. At runtime
await getAuth()
keeps working, but types can still be a breaking change.
- Confirm whether this should be a semver-minor or semver-major for @clerk/tanstack-react-start. If types are breaking, consider a major bump or a temporary overload to ease migration.
- Ensure README and migration notes call out: “getAuth is now synchronous;
await getAuth()
continues to work but is no longer necessary.”If helpful, I can draft a short MIGRATION.md and a codemod recipe for removing unnecessary awaits.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (4)
integration/templates/tanstack-react-router/package.json
(1 hunks)integration/templates/tanstack-react-start/package.json
(1 hunks)integration/templates/tanstack-react-start/src/routes/user.tsx
(1 hunks)packages/tanstack-react-start/package.json
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use Prettier for consistent code formatting
Files:
integration/templates/tanstack-react-router/package.json
integration/templates/tanstack-react-start/package.json
integration/templates/tanstack-react-start/src/routes/user.tsx
packages/tanstack-react-start/package.json
integration/**
📄 CodeRabbit Inference Engine (.cursor/rules/global.mdc)
Framework integration templates and E2E tests should be placed under the integration/ directory
Files:
integration/templates/tanstack-react-router/package.json
integration/templates/tanstack-react-start/package.json
integration/templates/tanstack-react-start/src/routes/user.tsx
integration/**/*
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)
End-to-end tests and integration templates must be located in the 'integration/' directory.
Files:
integration/templates/tanstack-react-router/package.json
integration/templates/tanstack-react-start/package.json
integration/templates/tanstack-react-start/src/routes/user.tsx
**/*
⚙️ CodeRabbit Configuration File
If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes.
Files:
integration/templates/tanstack-react-router/package.json
integration/templates/tanstack-react-start/package.json
integration/templates/tanstack-react-start/src/routes/user.tsx
packages/tanstack-react-start/package.json
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
**/*.{js,jsx,ts,tsx}
: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels
Files:
integration/templates/tanstack-react-start/src/routes/user.tsx
**/*.{ts,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
Use proper TypeScript error types
**/*.{ts,tsx}
: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoidany
type - preferunknown
when type is uncertain, then narrow with type guards
Useinterface
for object shapes that might be extended
Usetype
for unions, primitives, and computed types
Preferreadonly
properties for immutable data structures
Useprivate
for internal implementation details
Useprotected
for inheritance hierarchies
Usepublic
explicitly for clarity in public APIs
Preferreadonly
for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Useconst assertions
for literal types:as const
Usesatisfies
operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports:import type { ... } from ...
Noany
types without justification
Proper error handling with typed errors
Consistent use ofreadonly
for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)
Files:
integration/templates/tanstack-react-start/src/routes/user.tsx
**/*.{jsx,tsx}
📄 CodeRabbit Inference Engine (.cursor/rules/development.mdc)
**/*.{jsx,tsx}
: Use error boundaries in React components
Minimize re-renders in React components
**/*.{jsx,tsx}
: Always use functional components with hooks instead of class components
Follow PascalCase naming for components:UserProfile
,NavigationMenu
Keep components focused on a single responsibility - split large components
Limit component size to 150-200 lines; extract logic into custom hooks
Use composition over inheritance - prefer smaller, composable components
Export components as named exports for better tree-shaking
One component per file with matching filename and component name
Use useState for simple state management
Use useReducer for complex state logic
Implement proper state initialization
Use proper state updates with callbacks
Implement proper state cleanup
Use Context API for theme/authentication
Implement proper state selectors
Use proper state normalization
Implement proper state persistence
Use React.memo for expensive components
Implement proper useCallback for handlers
Use proper useMemo for expensive computations
Implement proper virtualization for lists
Use proper code splitting with React.lazy
Implement proper cleanup in useEffect
Use proper refs for DOM access
Implement proper event listener cleanup
Use proper abort controllers for fetch
Implement proper subscription cleanup
Use proper HTML elements
Implement proper ARIA attributes
Use proper heading hierarchy
Implement proper form labels
Use proper button types
Implement proper focus management
Use proper keyboard shortcuts
Implement proper tab order
Use proper skip links
Implement proper focus traps
Implement proper error boundaries
Use proper error logging
Implement proper error recovery
Use proper error messages
Implement proper error fallbacks
Use proper form validation
Implement proper error states
Use proper error messages
Implement proper form submission
Use proper form reset
Use proper component naming
Implement proper file naming
Use proper prop naming
Implement proper...
Files:
integration/templates/tanstack-react-start/src/routes/user.tsx
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit Inference Engine (.cursor/rules/monorepo.mdc)
Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.
Files:
integration/templates/tanstack-react-start/src/routes/user.tsx
**/*.tsx
📄 CodeRabbit Inference Engine (.cursor/rules/react.mdc)
**/*.tsx
: Use proper type definitions for props and state
Leverage TypeScript's type inference where possible
Use proper event types for handlers
Implement proper generic types for reusable components
Use proper type guards for conditional rendering
Files:
integration/templates/tanstack-react-start/src/routes/user.tsx
packages/*/package.json
📄 CodeRabbit Inference Engine (.cursor/rules/global.mdc)
All publishable packages should be placed under the packages/ directory
packages/*/package.json
: All publishable packages must be located in the 'packages/' directory.
All packages must be published under the @clerk namespace on npm.
Semantic versioning must be used across all packages.
Files:
packages/tanstack-react-start/package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
- GitHub Check: Integration Tests (vue, chrome)
- GitHub Check: Integration Tests (nextjs, chrome, 14)
- GitHub Check: Integration Tests (nextjs, chrome, 15)
- GitHub Check: Integration Tests (machine, chrome)
- GitHub Check: Integration Tests (nuxt, chrome)
- GitHub Check: Integration Tests (react-router, chrome)
- GitHub Check: Integration Tests (billing, chrome)
- GitHub Check: Integration Tests (expo-web, chrome)
- GitHub Check: Integration Tests (astro, chrome)
- GitHub Check: Integration Tests (elements, chrome)
- GitHub Check: Integration Tests (tanstack-react-start, chrome)
- GitHub Check: Integration Tests (tanstack-react-router, chrome)
- GitHub Check: Integration Tests (ap-flows, chrome)
- GitHub Check: Integration Tests (sessions, chrome)
- GitHub Check: Integration Tests (express, chrome)
- GitHub Check: Integration Tests (localhost, chrome)
- GitHub Check: Integration Tests (quickstart, chrome)
- GitHub Check: Integration Tests (generic, chrome)
- GitHub Check: Unit Tests (18, --filter=@clerk/astro --filter=@clerk/backend --filter=@clerk/express --filter=@c...
- GitHub Check: Unit Tests (22, **)
- GitHub Check: Static analysis
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (1)
integration/templates/tanstack-react-router/package.json (1)
12-14
: Router and plugin versions are consistently pinned; good.The trio @tanstack/react-router, devtools, and router-plugin are in lockstep at 1.131.27, which keeps the template coherent with upstream APIs.
Please ensure any accompanying examples or docs in this repo mention the 1.131.x requirement to prevent mismatched installs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (5)
integration/templates/tanstack-react-start/src/server.tsx (1)
5-13
: Hoist the handler factory to avoid rebuilding on every request.createStartHandler and createClerkHandler appear stateless at construction time; the per-request work still happens when invoking the factory. Hoisting cuts some per-request overhead without changing behavior.
Apply this diff:
-import { createStartHandler, defineHandlerCallback, defaultStreamHandler } from '@tanstack/react-start/server'; +import { createStartHandler, defineHandlerCallback, defaultStreamHandler } from '@tanstack/react-start/server'; import { createRouter } from './router'; import { createClerkHandler } from '@clerk/tanstack-react-start/server'; -export default defineHandlerCallback(async event => { - const startHandler = await createClerkHandler( - createStartHandler({ - createRouter, - }), - )(defaultStreamHandler); - - return startHandler(event); -}); +// Build once; request-bound globals are captured when the factory is invoked. +const handlerFactory = createClerkHandler( + createStartHandler({ + createRouter, + }), +); + +export default defineHandlerCallback(async event => { + const startHandler = await handlerFactory(defaultStreamHandler); + return startHandler(event); +});packages/tanstack-react-start/src/server/authenticateRequest.ts (1)
6-33
: Return type change looks correct and simplifies the flow. Add JSDoc and guard for misconfiguration.The narrower Promise matches the new middleware flow. Minimal nits:
- Add JSDoc since this is a package-level exported API.
- Consider wrapping unexpected client creation errors with errorThrower for clearer diagnostics (consistent with loadOptions).
Proposed additions:
-export async function authenticateRequest(request: Request, opts: AuthenticateRequestOptions): Promise<RequestState> { +/** + * Authenticates the incoming Request and returns a RequestState that includes headers and `toAuth()`. + * Expects upstream caller to handle handshake redirects and error states. + */ +export async function authenticateRequest( + request: Request, + opts: AuthenticateRequestOptions, +): Promise<RequestState> { const { audience, authorizedParties } = opts; @@ - const requestState = await createClerkClient({ + // Consider try/catch if we want to wrap low-level errors with package-specific context. + const requestState = await createClerkClient({packages/tanstack-react-start/src/server/middlewareHandler.ts (3)
35-49
: Redirect handling for Netlify dev cache-bust is correct; consider adding debug logging.The 307 with requestState.headers mirrors other integrations. Optional: add debug-level log with the target location to aid troubleshooting in dev.
Example (pseudo-logging):
if (locationHeader) { + // debug('Clerk handshake redirect', { location: locationHeader }); handleNetlifyCacheInDevInstance({
22-70
: Add minimal types to event.context.auth for editor UX.If getEvent().context is typed loosely, a declaration merge can improve DX without impacting runtime.
Example ambient type augmentation (placed in a .d.ts within this package):
declare module '@tanstack/react-start/server' { interface ServerEventContext { auth?: () => import('@clerk/backend/internal').RequestState['toAuth'] extends () => infer R ? () => R : () => unknown; } }
22-70
: Add tests to cover the new behavior.Given the behavioral shift (single authenticate call and synchronous getAuth), add E2E/integration tests under integration/ that assert:
- getAuth() is synchronous in loaders and server functions.
- Only one authenticateRequest() occurs per request (can assert via a test hook/mocking).
- Handshake redirect returns 307 with Location and cache-busted URL on Netlify dev.
I can scaffold a minimal TanStack Start template test exercising these paths if helpful.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
integration/templates/tanstack-react-start/src/server.tsx
(1 hunks)packages/tanstack-react-start/src/server/authenticateRequest.ts
(1 hunks)packages/tanstack-react-start/src/server/middlewareHandler.ts
(2 hunks)
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
**/*.{js,jsx,ts,tsx}
: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels
Files:
packages/tanstack-react-start/src/server/authenticateRequest.ts
integration/templates/tanstack-react-start/src/server.tsx
packages/tanstack-react-start/src/server/middlewareHandler.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
Use Prettier for consistent code formatting
Files:
packages/tanstack-react-start/src/server/authenticateRequest.ts
integration/templates/tanstack-react-start/src/server.tsx
packages/tanstack-react-start/src/server/middlewareHandler.ts
packages/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
TypeScript is required for all packages
Files:
packages/tanstack-react-start/src/server/authenticateRequest.ts
packages/tanstack-react-start/src/server/middlewareHandler.ts
packages/**/*.{ts,tsx,d.ts}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
Packages should export TypeScript types alongside runtime code
Files:
packages/tanstack-react-start/src/server/authenticateRequest.ts
packages/tanstack-react-start/src/server/middlewareHandler.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
Use proper TypeScript error types
**/*.{ts,tsx}
: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoidany
type - preferunknown
when type is uncertain, then narrow with type guards
Useinterface
for object shapes that might be extended
Usetype
for unions, primitives, and computed types
Preferreadonly
properties for immutable data structures
Useprivate
for internal implementation details
Useprotected
for inheritance hierarchies
Usepublic
explicitly for clarity in public APIs
Preferreadonly
for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Useconst assertions
for literal types:as const
Usesatisfies
operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports:import type { ... } from ...
Noany
types without justification
Proper error handling with typed errors
Consistent use ofreadonly
for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)
Files:
packages/tanstack-react-start/src/server/authenticateRequest.ts
integration/templates/tanstack-react-start/src/server.tsx
packages/tanstack-react-start/src/server/middlewareHandler.ts
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)
Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.
Files:
packages/tanstack-react-start/src/server/authenticateRequest.ts
integration/templates/tanstack-react-start/src/server.tsx
packages/tanstack-react-start/src/server/middlewareHandler.ts
**/*
⚙️ CodeRabbit configuration file
If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes.
Files:
packages/tanstack-react-start/src/server/authenticateRequest.ts
integration/templates/tanstack-react-start/src/server.tsx
packages/tanstack-react-start/src/server/middlewareHandler.ts
**/*.{jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
**/*.{jsx,tsx}
: Use error boundaries in React components
Minimize re-renders in React components
**/*.{jsx,tsx}
: Always use functional components with hooks instead of class components
Follow PascalCase naming for components:UserProfile
,NavigationMenu
Keep components focused on a single responsibility - split large components
Limit component size to 150-200 lines; extract logic into custom hooks
Use composition over inheritance - prefer smaller, composable components
Export components as named exports for better tree-shaking
One component per file with matching filename and component name
Use useState for simple state management
Use useReducer for complex state logic
Implement proper state initialization
Use proper state updates with callbacks
Implement proper state cleanup
Use Context API for theme/authentication
Implement proper state selectors
Use proper state normalization
Implement proper state persistence
Use React.memo for expensive components
Implement proper useCallback for handlers
Use proper useMemo for expensive computations
Implement proper virtualization for lists
Use proper code splitting with React.lazy
Implement proper cleanup in useEffect
Use proper refs for DOM access
Implement proper event listener cleanup
Use proper abort controllers for fetch
Implement proper subscription cleanup
Use proper HTML elements
Implement proper ARIA attributes
Use proper heading hierarchy
Implement proper form labels
Use proper button types
Implement proper focus management
Use proper keyboard shortcuts
Implement proper tab order
Use proper skip links
Implement proper focus traps
Implement proper error boundaries
Use proper error logging
Implement proper error recovery
Use proper error messages
Implement proper error fallbacks
Use proper form validation
Implement proper error states
Use proper error messages
Implement proper form submission
Use proper form reset
Use proper component naming
Implement proper file naming
Use proper prop naming
Implement proper...
Files:
integration/templates/tanstack-react-start/src/server.tsx
integration/**
📄 CodeRabbit inference engine (.cursor/rules/global.mdc)
Framework integration templates and E2E tests should be placed under the integration/ directory
Files:
integration/templates/tanstack-react-start/src/server.tsx
integration/**/*
📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)
End-to-end tests and integration templates must be located in the 'integration/' directory.
Files:
integration/templates/tanstack-react-start/src/server.tsx
**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/react.mdc)
**/*.tsx
: Use proper type definitions for props and state
Leverage TypeScript's type inference where possible
Use proper event types for handlers
Implement proper generic types for reusable components
Use proper type guards for conditional rendering
Files:
integration/templates/tanstack-react-start/src/server.tsx
🧬 Code graph analysis (3)
packages/tanstack-react-start/src/server/authenticateRequest.ts (5)
packages/express/src/authenticateRequest.ts (1)
authenticateRequest
(24-64)packages/backend/src/tokens/request.ts (1)
authenticateRequest
(147-804)packages/react-router/src/ssr/authenticateRequest.ts (1)
authenticateRequest
(9-55)packages/remix/src/ssr/authenticateRequest.ts (1)
authenticateRequest
(9-55)packages/backend/src/tokens/types.ts (1)
AuthenticateRequestOptions
(19-75)
integration/templates/tanstack-react-start/src/server.tsx (1)
packages/tanstack-react-start/src/server/middlewareHandler.ts (1)
createClerkHandler
(18-71)
packages/tanstack-react-start/src/server/middlewareHandler.ts (5)
packages/tanstack-react-start/src/server/loadOptions.ts (1)
loadOptions
(14-68)packages/tanstack-react-start/src/server/authenticateRequest.ts (1)
authenticateRequest
(6-34)packages/shared/src/netlifyCacheHandler.ts (1)
handleNetlifyCacheInDevInstance
(43-65)packages/tanstack-react-start/src/utils/index.ts (1)
errorThrower
(7-9)packages/tanstack-react-start/src/server/utils/index.ts (1)
getResponseClerkState
(23-55)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (22)
- GitHub Check: Integration Tests (nextjs, chrome, 15)
- GitHub Check: Integration Tests (billing, chrome)
- GitHub Check: Integration Tests (machine, chrome)
- GitHub Check: Integration Tests (react-router, chrome)
- GitHub Check: Integration Tests (nextjs, chrome, 14)
- GitHub Check: Integration Tests (expo-web, chrome)
- GitHub Check: Integration Tests (nuxt, chrome)
- GitHub Check: Integration Tests (tanstack-react-router, chrome)
- GitHub Check: Integration Tests (astro, chrome)
- GitHub Check: Integration Tests (vue, chrome)
- GitHub Check: Integration Tests (generic, chrome)
- GitHub Check: Integration Tests (ap-flows, chrome)
- GitHub Check: Integration Tests (tanstack-react-start, chrome)
- GitHub Check: Integration Tests (localhost, chrome)
- GitHub Check: Integration Tests (quickstart, chrome)
- GitHub Check: Integration Tests (elements, chrome)
- GitHub Check: Integration Tests (sessions, chrome)
- GitHub Check: Integration Tests (express, chrome)
- GitHub Check: Publish with pkg-pr-new
- GitHub Check: Static analysis
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (5)
integration/templates/tanstack-react-start/src/server.tsx (1)
5-13
: Good switch to defineHandlerCallback and per-request handler creation.This aligns with the new flow and ensures the request-bound globals (getEvent/getWebRequest) are available when wiring auth via middleware. No functional issues spotted.
packages/tanstack-react-start/src/server/authenticateRequest.ts (1)
13-23
: Confirmed: PACKAGE_NAME and PACKAGE_VERSION are properly injected at build time
Both constants are defined via esbuild’sdefine
in tsup.config.ts and declared in src/global.d.ts, so they’re in scope for TS, ESLint, and runtime. No imports are needed.packages/tanstack-react-start/src/server/middlewareHandler.ts (3)
22-34
: Nice: wire auth into event context before any server code runs.Setting event.context.auth to requestState.toAuth() eliminates duplicate authenticateRequest() calls downstream (getAuth becomes synchronous). This is the right place to attach it.
50-53
: Explicit error on unexpected handshake without redirect.Good defensive check; message is clear and uses errorThrower for consistency.
55-67
: Seeding router context and propagating headers looks sound.
- Merges clerkInitialState into router context before router.load(), which is necessary for loaders.
- Copies headers from the requestState into responseHeaders.
No issues; ensure responseHeaders merging doesn’t drop pre-existing values upstream (looks fine as we only set/update keys).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/tanstack-react-start/README.md (1)
36-37
: Prerequisites versions are outdated vs. this PR’s dependency floor.Package versions were bumped to the 1.131.x range elsewhere in the PR; the README still lists ^1.49.1 for TanStack Start/Router. This mismatch will cause confusion for users following the README.
Please update both bullets to match the new minimums (e.g., ^1.131.0).
Here’s a minimal edit:
- TanStack Start
^1.131.0
or later- TanStack Router
^1.131.0
or later
♻️ Duplicate comments (1)
packages/tanstack-react-start/src/server/getAuth.ts (1)
15-21
: Prefer a dedicated “missing auth context” error and a type guard on getContext('auth').If getContext('auth') is present but not a function, calling authObjectFn() will throw a TypeError. Also, emitting a specific “auth context missing” error can be more actionable than “handler not configured.”
Apply this diff:
-import { clerkHandlerNotConfigured, noFetchFnCtxPassedInGetAuth } from '../utils/errors'; +import { clerkHandlerNotConfigured, noFetchFnCtxPassedInGetAuth } from '../utils/errors'; +// Consider adding: noAuthContextInGetAuth @@ - const authObjectFn = getContext('auth'); + const authObjectFn = getContext('auth'); - if (!authObjectFn) { - return errorThrower.throw(clerkHandlerNotConfigured); - } + if (!authObjectFn) { + return errorThrower.throw(clerkHandlerNotConfigured); + } + if (typeof authObjectFn !== 'function') { + // If you add a dedicated error (e.g., noAuthContextInGetAuth), use it here for clearer DX. + return errorThrower.throw(clerkHandlerNotConfigured); + // return errorThrower.throw(noAuthContextInGetAuth); + }If you want the clearer message, add a new error factory in utils/errors.ts:
export const noAuthContextInGetAuth = createErrorMessage(` Missing auth context. Ensure \`getAuth()\` is called within a TanStack Start server handler wired with \`createClerkHandler()\`, which sets \`event.context.auth\`. `);
🧹 Nitpick comments (1)
packages/tanstack-react-start/README.md (1)
30-30
: Use canonical “TanStack” casing throughout.Brand casing is inconsistent (“Tanstack” vs “TanStack”) in the README. Suggest standardizing to “TanStack” to match upstream naming.
Also applies to: 36-37
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
packages/tanstack-react-start/README.md
(1 hunks)packages/tanstack-react-start/src/server/getAuth.ts
(1 hunks)packages/tanstack-react-start/src/utils/errors.ts
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
Use Prettier for consistent code formatting
Files:
packages/tanstack-react-start/README.md
packages/tanstack-react-start/src/utils/errors.ts
packages/tanstack-react-start/src/server/getAuth.ts
packages/**/README.md
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
Maintain up-to-date README files for each package
Files:
packages/tanstack-react-start/README.md
**/*
⚙️ CodeRabbit configuration file
If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes.
Files:
packages/tanstack-react-start/README.md
packages/tanstack-react-start/src/utils/errors.ts
packages/tanstack-react-start/src/server/getAuth.ts
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
**/*.{js,jsx,ts,tsx}
: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels
Files:
packages/tanstack-react-start/src/utils/errors.ts
packages/tanstack-react-start/src/server/getAuth.ts
packages/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
TypeScript is required for all packages
Files:
packages/tanstack-react-start/src/utils/errors.ts
packages/tanstack-react-start/src/server/getAuth.ts
packages/**/*.{ts,tsx,d.ts}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
Packages should export TypeScript types alongside runtime code
Files:
packages/tanstack-react-start/src/utils/errors.ts
packages/tanstack-react-start/src/server/getAuth.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
Use proper TypeScript error types
**/*.{ts,tsx}
: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoidany
type - preferunknown
when type is uncertain, then narrow with type guards
Useinterface
for object shapes that might be extended
Usetype
for unions, primitives, and computed types
Preferreadonly
properties for immutable data structures
Useprivate
for internal implementation details
Useprotected
for inheritance hierarchies
Usepublic
explicitly for clarity in public APIs
Preferreadonly
for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Useconst assertions
for literal types:as const
Usesatisfies
operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports:import type { ... } from ...
Noany
types without justification
Proper error handling with typed errors
Consistent use ofreadonly
for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)
Files:
packages/tanstack-react-start/src/utils/errors.ts
packages/tanstack-react-start/src/server/getAuth.ts
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)
Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.
Files:
packages/tanstack-react-start/src/utils/errors.ts
packages/tanstack-react-start/src/server/getAuth.ts
🧬 Code graph analysis (1)
packages/tanstack-react-start/src/server/getAuth.ts (7)
packages/backend/src/tokens/types.ts (2)
AuthenticateRequestOptions
(19-75)GetAuthFn
(200-237)packages/nuxt/src/runtime/server/getAuth.ts (1)
getAuth
(10-20)packages/express/src/getAuth.ts (1)
getAuth
(18-26)packages/fastify/src/getAuth.ts (1)
getAuth
(14-22)packages/tanstack-react-start/src/utils/index.ts (1)
errorThrower
(7-9)packages/tanstack-react-start/src/utils/errors.ts (2)
noFetchFnCtxPassedInGetAuth
(10-19)clerkHandlerNotConfigured
(21-27)packages/backend/src/tokens/authObjects.ts (1)
getAuthObjectForAcceptedToken
(462-492)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Build Packages
- GitHub Check: Formatting | Dedupe | Changeset
- GitHub Check: semgrep/ci
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (4)
packages/tanstack-react-start/README.md (1)
44-45
: Nice doc simplification and clear pointers to official guides.The redirection to the Quickstart and Reference pages is concise and aligns with the new context-based auth flow. LGTM.
Also applies to: 46-47, 50-51
packages/tanstack-react-start/src/utils/errors.ts (1)
11-19
: Example reads well and matches the new request-first pattern.The guidance for calling getAuth(request) after getWebRequest() matches the updated API shape and will help avoid common “missing request” mistakes.
packages/tanstack-react-start/src/server/getAuth.ts (2)
10-13
: Parameter presence check is good; keep it for consistent DX across frameworks.Even though getAuth now reads from TanStack server context, retaining the request parameter and guarding nullish values keeps parity with other adapters and produces a clearer error.
21-22
: Return shaping via getAuthObjectForAcceptedToken is correct.This preserves the expected overload behavior for acceptsToken while keeping the implementation synchronous. Looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
.changeset/itchy-zoos-shake.md (4)
7-7
: State the minimum TanStack Start version explicitly in the Changeset body.You raised the template minimum to ^1.131.0. Surface that here to prevent copy/paste breakage for users on older versions.
-The `createClerkHandler` helper now returns a Promise and requires awaiting during setup to ensure authentication context is available at the earliest possible point in the request lifecycle, before any router loaders or server functions execute +The `createClerkHandler` helper now returns a Promise and requires awaiting during setup to ensure authentication context is available at the earliest possible point in the request lifecycle, before any router loaders or server functions execute. This requires `@tanstack/react-start` ≥ `1.131.0`.
21-25
: Clarify per-request invocation placement forhandlerFactory(...)
.Add a one-liner noting that
handlerFactory(defaultStreamHandler)
must be invoked inside the handler (per request) so it can bind to the current event context, and should not be hoisted to module scope.export default defineHandlerCallback(async event => { const startHandler = await handlerFactory(defaultStreamHandler); // awaited return startHandler(event); });
+Note: Call
handlerFactory(defaultStreamHandler)
inside the handler (per request) so it can bind to the current event context. Do not hoist this call to module scope.--- `27-27`: **Add an upgrade tip: `await getAuth()` still works for backward compatibility.** Since `await` on a non-Promise value resolves immediately, existing `await getAuth(request)` calls won’t break. Explicitly mentioning this eases upgrades. ```diff -`getAuth()` is now sync and no longer requires awaiting +`getAuth()` is now sync and no longer requires awaiting. + +Upgrade tip: Existing code using `await getAuth(request)` will continue to work; `await` on a non-Promise value resolves to the value unchanged.
29-39
: Make the snippet copy-pasteable and reflect the new API: add missing imports and prefergetAuth()
withoutrequest
.The example omits
createServerFn
/getWebRequest
imports and still fetches arequest
that’s not needed anymore. Showing the request-less form reinforces the new context-based behavior.```ts -import { getAuth } from '@clerk/tanstack-react-start/server' +import { getAuth } from '@clerk/tanstack-react-start/server'; +import { createServerFn } from '@tanstack/react-start/server'; -const authStateFn = createServerFn({ method: 'GET' }).handler(() => { - const request = getWebRequest() - - const auth = getAuth(request) // no await - - return { userId: auth.userId } -}) +const authStateFn = createServerFn({ method: 'GET' }).handler(() => { + // `getAuth` reads from the server context; the `request` argument is optional. + const auth = getAuth(); // no await + return { userId: auth.userId }; +});If you want to keep the `request`-accepting form for familiarity, also add: ```ts import { getWebRequest } from '@tanstack/react-start/server';
and add a note that
request
is ignored by the React Start integration.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
.changeset/itchy-zoos-shake.md
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
.changeset/**
📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)
Automated releases must use Changesets.
Files:
.changeset/itchy-zoos-shake.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Formatting | Dedupe | Changeset
- GitHub Check: semgrep/ci
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (2)
.changeset/itchy-zoos-shake.md (2)
1-3
: Confirm semver level: this looks breaking forcreateClerkHandler
.
createClerkHandler
now returns a Promise and requires awaiting. That’s an API break for consumers who didn’t previously await it. If@clerk/tanstack-react-start
is ≥1.0.0, this should be a major bump per semver. If it’s still 0.x, a minor bump can include breaking changes—please confirm the package’s current major before merging.If confirmed ≥1.0.0, apply:
--- -"@clerk/tanstack-react-start": minor +"@clerk/tanstack-react-start": major ---
5-5
: Good, concise headline.Accurately captures the core change (reuse of server handler
Auth
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (5)
.changeset/itchy-zoos-shake.md (1)
21-24
: Optional: add “top-level await” example for platforms that support itFor platforms supporting top-level await, showing an alternative can reduce per-request factory await overhead.
You could add after the current example:
// Alternative (environments with top-level await): // const startHandler = await createClerkHandler(createStartHandler({ createRouter }))(defaultStreamHandler); // export default defineHandlerCallback(event => startHandler(event));packages/tanstack-react-start/src/server/getAuth.ts (4)
15-19
: Strengthen context guard and add typing to getContext('auth')Ensure the retrieved context value is a function before invoking it and leverage generics for stronger typing. This improves DX and protects against accidental non-function context values.
Apply this diff:
-import { getContext } from '@tanstack/react-start/server'; +import { getContext } from '@tanstack/react-start/server'; +import type { AuthObject } from '@clerk/backend/internal'; @@ - const authObjectFn = getContext('auth'); + const authObjectFn = getContext<(() => AuthObject) | undefined>('auth'); - if (!authObjectFn) { + if (typeof authObjectFn !== 'function') { return errorThrower.throw(clerkHandlerNotConfigured); }
21-22
: Simplify to a direct await (if staying async)Promise.resolve around a possibly-sync result isn’t necessary in an async function; await handles both sync and async returns.
Apply this diff if you keep getAuth async:
- const authObject = await Promise.resolve(authObjectFn()); + const authObject = await authObjectFn();
10-10
: Remove redundant type assertion at the endYou’ve already declared the variable type on the left-hand side; the trailing “as GetAuthFn<Request, true>” is redundant and can be removed.
Apply this diff if you keep the async signature:
-export const getAuth: GetAuthFn<Request, true> = (async (request: Request, opts?: GetAuthOptions) => { +export const getAuth: GetAuthFn<Request, true> = (async (request: Request, opts?: GetAuthOptions) => { @@ -}) as GetAuthFn<Request, true>; +});Also applies to: 25-25
10-25
: Add/adjust tests for context-based getAuthThese changes alter how auth is sourced and filtered. Please add tests (or update existing ones) to cover:
- Throws clerkHandlerNotConfigured when getContext('auth') is missing.
- Returns the context-derived auth object (session token by default).
- Respects acceptsToken for:
- Single token type (e.g., 'api_key' -> MachineAuthObject)
- Array of types (matching and non-matching)
- 'any' passthrough
- Still throws noFetchFnCtxPassedInGetAuth when request is falsy.
I can scaffold test cases; let me know your test runner setup here (Vitest/Jest) and path conventions, and I’ll provide concrete specs.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
.changeset/itchy-zoos-shake.md
(1 hunks)packages/tanstack-react-start/src/server/getAuth.ts
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{js,jsx,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
**/*.{js,jsx,ts,tsx}
: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels
Files:
packages/tanstack-react-start/src/server/getAuth.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
Use Prettier for consistent code formatting
Files:
packages/tanstack-react-start/src/server/getAuth.ts
packages/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
TypeScript is required for all packages
Files:
packages/tanstack-react-start/src/server/getAuth.ts
packages/**/*.{ts,tsx,d.ts}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
Packages should export TypeScript types alongside runtime code
Files:
packages/tanstack-react-start/src/server/getAuth.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/development.mdc)
Use proper TypeScript error types
**/*.{ts,tsx}
: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoidany
type - preferunknown
when type is uncertain, then narrow with type guards
Useinterface
for object shapes that might be extended
Usetype
for unions, primitives, and computed types
Preferreadonly
properties for immutable data structures
Useprivate
for internal implementation details
Useprotected
for inheritance hierarchies
Usepublic
explicitly for clarity in public APIs
Preferreadonly
for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Useconst assertions
for literal types:as const
Usesatisfies
operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports:import type { ... } from ...
Noany
types without justification
Proper error handling with typed errors
Consistent use ofreadonly
for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)
Files:
packages/tanstack-react-start/src/server/getAuth.ts
**/*.{js,ts,tsx,jsx}
📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)
Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.
Files:
packages/tanstack-react-start/src/server/getAuth.ts
**/*
⚙️ CodeRabbit configuration file
If there are no tests added or modified as part of the PR, please suggest that tests be added to cover the changes.
Files:
packages/tanstack-react-start/src/server/getAuth.ts
.changeset/**
📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)
Automated releases must use Changesets.
Files:
.changeset/itchy-zoos-shake.md
🧬 Code graph analysis (1)
packages/tanstack-react-start/src/server/getAuth.ts (4)
packages/backend/src/tokens/types.ts (1)
AuthenticateRequestOptions
(19-75)packages/tanstack-react-start/src/utils/index.ts (1)
errorThrower
(7-9)packages/tanstack-react-start/src/utils/errors.ts (2)
noFetchFnCtxPassedInGetAuth
(10-19)clerkHandlerNotConfigured
(21-27)packages/backend/src/tokens/authObjects.ts (1)
getAuthObjectForAcceptedToken
(462-492)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Formatting | Dedupe | Changeset
- GitHub Check: semgrep/ci
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: semgrep-cloud-platform/scan
- GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (1)
packages/tanstack-react-start/src/server/getAuth.ts (1)
10-25
: No evidence of a synchronous refactor promise in the PR or changesets
I searched the PR body and all changeset files for any mention of “Refactors getAuth() to be synchronous” or similar wording and found nothing—there is no PR summary or changeset entry promising a sync API for getAuth, nor any references to dropping itsasync
signature. As such, the implementation (and its types) remainingasync
is consistent with the available code and docs. Please disregard the original comment unless there’s a missing changeset or documentation update that explicitly states a switch to a synchronous API.Likely an incorrect or invalid review comment.
.changeset/itchy-zoos-shake.md
Outdated
Reuses existing `Auth` object from the server handler | ||
|
||
The `createClerkHandler` helper now returns a Promise and requires awaiting during setup to ensure authentication context is available at the earliest possible point in the request lifecycle, before any router loaders or server functions execute |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Call out BREAKING CHANGES and add migration steps (clarify getAuth sync/async status)
Please add a clear “BREAKING CHANGES” section and explicit migration bullets. Also, the PR description claims “getAuth() is synchronous,” but current code still returns a Promise. Either adjust code to be sync or update the changeset to state it remains async for now.
Proposed wording to append below the header:
Reuses existing `Auth` object from the server handler
-The `createClerkHandler` helper now returns a Promise and requires awaiting during setup to ensure authentication context is available at the earliest possible point in the request lifecycle, before any router loaders or server functions execute
+BREAKING CHANGES
+- createClerkHandler now returns a Promise and must be awaited during setup. This change ensures the auth context is available before router loaders or server functions execute.
+- Minimum TanStack Start version is ^1.131.0.
+
+Migration
+1) Wrap your server entry with defineHandlerCallback and await the handler factory:
+ (see example below)
+2) Replace any direct invocations of createClerkHandler(...) that previously returned a handler with an awaited call.
+3) Verify your getAuth() usage. If getAuth() has been made synchronous in this release, remove any awaits. If it remains async, keep the await. (See release notes for the final status.)
Also applies to: 9-25
🏁 Script executed:
#!/bin/bash
set -e
# Display the changeset for review
cat .changeset/itchy-zoos-shake.md
# Search for createClerkHandler definition and imports
rg -n --type ts "createClerkHandler" -C3
# Search for getAuth definition or re-exports
rg -n --type ts "export.*getAuth" -C3 || rg -n --type ts "function getAuth" -C3
# Search for getAuth usages to see if callers await it
rg -n --type ts "getAuth\\(" -C3
Length of output: 61522
Add clear BREAKING CHANGES section and clarify getAuth async behavior
Please update .changeset/itchy-zoos-shake.md
to explicitly call out breaking changes and provide step-by-step migration guidance. For example:
Reuses existing `Auth` object from the server handler
+- BREAKING CHANGES
+- `createClerkHandler` now returns a factory whose invocation produces a Promise. You **must** `await` this factory during your server setup to ensure the auth context is populated before any router loaders or server functions run.
+- `getAuth()` in this package remains **asynchronous** and returns a Promise. All existing calls to `getAuth()` must continue to use `await`.
+Migration
+1. Update your server entry to `await` the handler factory:
+ ```ts
+ import { createClerkHandler } from '@clerk/tanstack-react-start/server';
+ import { createStartHandler, defineHandlerCallback, defaultStreamHandler } from '@tanstack/react-start/server';
+ import { createRouter } from './router';
+
+ const handlerFactory = createClerkHandler(
+ createStartHandler({ createRouter }),
+ );
+
+ export default defineHandlerCallback(async event => {
+ // Previously: const startHandler = handlerFactory(defaultStreamHandler);
+ const startHandler = await handlerFactory(defaultStreamHandler);
+ return startHandler(event);
+ });
+ ```
+2. Ensure all calls to `getAuth()` remain awaited:
+ ```diff
+ - const { userId } = getAuth(req);
+ + const { userId } = await getAuth(req);
+ ```
+3. Verify your surrounding code handles the async nature—no additional code changes to make `getAuth()` synchronous are needed at this time.
This makes the breaking changes explicit and gives developers exactly what they need to update.
🤖 Prompt for AI Agents
.changeset/itchy-zoos-shake.md around lines 5 to 7: add an explicit "BREAKING
CHANGES" section that states the handler factory now returns a Promise and must
be awaited during setup, include a short migration snippet showing replacing
synchronous handlerFactory(defaultStreamHandler) with awaiting the factory
before calling the resulting startHandler, list step-by-step guidance to (1)
update exports to await the handlerFactory in your request callback, (2) ensure
all calls to getAuth() are awaited throughout the codebase, and (3) verify
surrounding code accommodates the async behavior (no changes to make getAuth
synchronous), so consumers have clear, actionable migration steps.
const requestState = await authenticateRequest(request, { | ||
...loadedOptions, | ||
acceptsToken: 'any', | ||
}); | ||
|
||
const { clerkInitialState, headers } = getResponseClerkState(requestState, loadedOptions); | ||
// Set auth object here so it is available immediately in server functions via getAuth() | ||
event.context.auth = () => requestState.toAuth(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved authentication logic outside of eventHandler
to fix timing issues. Server functions would execute before eventHandler
ran, causing event.context.auth
to be undefined. By setting the auth context during handler setup, server functions can now access the auth object reliably.
This change requires awaiting createClerkHandler()
during setup.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just doing a minor bump here since the SDK is still in beta
Description
authenticateRequest()
call when invokinggetAuth()
by using the auth object shared from the event contextcreateClerkHandler
to be async to make auth object immediately available within server functions^1.131.0
Partially resolves USER-3141
Checklist
pnpm test
runs as expected.pnpm build
runs as expected.Type of change
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Refactor
Chores