Skip to content

Conversation

@spegoraro
Copy link
Contributor

@spegoraro spegoraro commented Nov 24, 2025

Description

When using the clerkMiddleware function with options, the original function correctly extracts them using loadOptions but then calls clerkClient with args only and doesn't pass on the options. In the case where options are passed in manually (e.g. using react-router middleware) this led to incorrect behaviour.

For my specific use-case, I was attaching environment variables to the router context then pulling those in the middleware function to pass on to clerkMiddleware. Despite passing my secret key, this would still fail. Now, by passing the options on to clerkClient it works correctly.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • Refactor
    • Routing middleware now accepts and forwards optional configuration, ensuring middleware options provided via the router are applied consistently throughout the authentication pipeline. This enables customizable middleware behavior and more predictable auth handling.

✏️ Tip: You can customize this high-level summary in your review settings.

@changeset-bot
Copy link

changeset-bot bot commented Nov 24, 2025

🦋 Changeset detected

Latest commit: 6422dc3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@clerk/react-router Minor

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

@vercel
Copy link

vercel bot commented Nov 24, 2025

@spegoraro is attempting to deploy a commit to the Clerk Production Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 24, 2025

Walkthrough

clerkClient now accepts an optional overrides: ClerkMiddlewareOptions parameter (default {}) and forwards it to loadOptions. clerkMiddleware passes its options object into clerkClient, allowing middleware-provided options to propagate to client initialization.

Changes

Cohort / File(s) Change Summary
Client initialization
packages/react-router/src/server/clerkClient.ts
Added optional overrides parameter (ClerkMiddlewareOptions = {}) to clerkClient signature and forwarded it to loadOptions(args, overrides). Added import for ClerkMiddlewareOptions.
Middleware integration
packages/react-router/src/server/clerkMiddleware.ts
Updated call site to pass middleware options through: clerkClient(args, options) (was clerkClient(args)).
Release metadata
.changeset/khaki-cows-sell.md
Added changeset noting the forwarding of options from middleware to client.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant RouterMiddleware as Router Middleware
    participant clerkClient as clerkClient
    participant loadOptions as loadOptions

    RouterMiddleware->>clerkClient: clerkClient(args, options)
    rect rgba(76,175,80,0.08)
      clerkClient->>loadOptions: loadOptions(args, overrides=options)
      loadOptions-->>clerkClient: resolved config
      clerkClient-->>RouterMiddleware: initialized client
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Small, localized signature change and one call-site update.
  • Items to check:
    • Correct import and type usage of ClerkMiddlewareOptions.
    • No call sites elsewhere that still call clerkClient(args) without considering defaults.
    • Tests or typings that may require updating for the new parameter.

Poem

🐰 A hop, a tweak, a gentle nudge,

Options travel, no more fudge.
From middleware to client they stream,
Configurations link like a dream.
Hooray — the rabbit gives a gleam! 🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly summarizes the main change: forwarding options from clerkMiddleware to clerkClient, which is the core fix addressed in this PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 63bd0a6 and 6422dc3.

📒 Files selected for processing (1)
  • .changeset/khaki-cows-sell.md (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .changeset/khaki-cows-sell.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). (32)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 14)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (machine, chrome, RQ)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 16)
  • GitHub Check: Integration Tests (nextjs, chrome, 15, RQ)
  • GitHub Check: Integration Tests (quickstart, chrome, 16)
  • GitHub Check: Integration Tests (billing, chrome, RQ)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome, 15)
  • GitHub Check: Integration Tests (expo-web, chrome)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (handshake, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (sessions:staging, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (handshake:staging, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (elements, chrome)
  • GitHub Check: Publish with pkg-pr-new
  • GitHub Check: Static analysis
  • GitHub Check: Unit Tests (22, **)
  • GitHub Check: Unit Tests (22, shared, clerk-js, RQ)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 (1)
packages/react-router/src/server/clerkMiddleware.ts (1)

36-58: Consider refactoring to eliminate duplicate loadOptions calls.

The current implementation calls loadOptions(args, options) twice:

  1. Line 36: to get options for authenticateRequest
  2. Line 58: inside clerkClient, which calls loadOptions again (line 7 of clerkClient.ts)

While this achieves the correct behavior, calling loadOptions twice with identical arguments is inefficient. Consider refactoring to call loadOptions once and reuse the result:

const loadedOptions = loadOptions(args, options);

// ... extract properties ...

const requestState = await createClerkClient({
  apiUrl: loadedOptions.apiUrl,
  secretKey: loadedOptions.secretKey,
  jwtKey: loadedOptions.jwtKey,
  proxyUrl: loadedOptions.proxyUrl,
  isSatellite: loadedOptions.isSatellite,
  domain: loadedOptions.domain,
  publishableKey: loadedOptions.publishableKey,
  machineSecretKey: loadedOptions.machineSecretKey,
  userAgent: `${PACKAGE_NAME}@${PACKAGE_VERSION}`,
}).authenticateRequest(clerkRequest, {
  // ... authenticateRequest options ...
});

This would require clerkClient to either accept pre-loaded options or be restructured, but it would eliminate redundant computation and validation.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 337430b and 63bd0a6.

📒 Files selected for processing (2)
  • packages/react-router/src/server/clerkClient.ts (1 hunks)
  • packages/react-router/src/server/clerkMiddleware.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
packages/react-router/src/server/clerkClient.ts (2)
packages/react-router/src/server/loadOptions.ts (2)
  • DataFunctionArgs (14-14)
  • loadOptions (16-90)
packages/react-router/src/server/types.ts (1)
  • ClerkMiddlewareOptions (20-51)
packages/react-router/src/server/clerkMiddleware.ts (2)
packages/react-router/src/server/clerkClient.ts (1)
  • clerkClient (6-22)
packages/react-router/src/server/index.ts (1)
  • clerkClient (5-5)
⏰ 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). (2)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (2)
packages/react-router/src/server/clerkClient.ts (1)

4-7: LGTM! Options are now correctly forwarded.

The addition of the overrides parameter and its forwarding to loadOptions correctly implements the fix described in the PR objectives. The parameter is properly typed, has a sensible default, and maintains backward compatibility.

packages/react-router/src/server/clerkMiddleware.ts (1)

58-58: Options are now correctly passed to clerkClient.

The change fixes the reported bug by forwarding the options parameter to clerkClient, ensuring that manually supplied configuration (e.g., secret keys attached to router context) is honored.

Copy link
Member

@wobsoriano wobsoriano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@wobsoriano wobsoriano changed the title Pass options from clerkMiddleware to clerkClient chore(react-router): Pass options from middleware to clerkClient Nov 24, 2025
@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 24, 2025

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@7292

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@7292

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@7292

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@7292

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@7292

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@7292

@clerk/elements

npm i https://pkg.pr.new/@clerk/elements@7292

@clerk/clerk-expo

npm i https://pkg.pr.new/@clerk/clerk-expo@7292

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@7292

@clerk/express

npm i https://pkg.pr.new/@clerk/express@7292

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@7292

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@7292

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@7292

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@7292

@clerk/clerk-react

npm i https://pkg.pr.new/@clerk/clerk-react@7292

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@7292

@clerk/remix

npm i https://pkg.pr.new/@clerk/remix@7292

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@7292

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@7292

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@7292

@clerk/themes

npm i https://pkg.pr.new/@clerk/themes@7292

@clerk/types

npm i https://pkg.pr.new/@clerk/types@7292

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@7292

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@7292

commit: 6422dc3

@jacekradko jacekradko merged commit 2813fa4 into clerk:main Nov 24, 2025
12 of 39 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants