Created
October 20, 2025 17:16
-
-
Save gabimoncha/a90bd5b150e33973d538a5dfb6d450d8 to your computer and use it in GitHub Desktop.
expo middleware with clerk auth
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { type ImmutableRequest } from 'expo-server'; | |
| import { createClerkClient } from '@clerk/backend'; | |
| import type { MiddlewareFunction } from 'expo-router/server'; | |
| const clerkClient = createClerkClient({ | |
| secretKey: process.env.CLERK_SECRET_KEY, | |
| publishableKey: process.env.CLERK_PUBLISHABLE_KEY, | |
| }); | |
| // https://docs.expo.dev/router/reference/middleware/#configure-middleware-matchers-optional | |
| export const unstable_settings = { | |
| matcher: { | |
| // Only run on API routes and specific paths | |
| patterns: ['/api/[...path]'], | |
| }, | |
| }; | |
| // You can only have one root-level +middleware.ts in your app. | |
| const middleware: MiddlewareFunction = async (request) => { | |
| const patchedRequest = patchRequestForClerk(request); | |
| const { isAuthenticated } = await clerkClient.authenticateRequest(patchedRequest); | |
| if (!isAuthenticated) { | |
| new Response('Unauthorized', { status: 401 }); | |
| } | |
| }; | |
| export default middleware; | |
| /** | |
| * Patches request to avoid duplex issues with unidici | |
| * For more information, see: | |
| * https://github.com/nodejs/node/issues/46221 | |
| * https://github.com/whatwg/fetch/pull/1457 | |
| * | |
| * source: https://github.com/clerk/javascript/blob/main/packages/tanstack-react-start/src/server/utils/index.ts#L61 | |
| */ | |
| export const patchRequestForClerk = (request: ImmutableRequest) => { | |
| const clonedRequest = new Request(request.url, { | |
| headers: request.headers, | |
| method: request.method, | |
| redirect: request.redirect, | |
| cache: request.cache, | |
| signal: request.signal, | |
| }); | |
| // If duplex is not set, set it to 'half' to avoid duplex issues with unidici | |
| if ( | |
| clonedRequest.method !== 'GET' && | |
| clonedRequest.body !== null && | |
| !('duplex' in clonedRequest) | |
| ) { | |
| (clonedRequest as unknown as { duplex: 'half' }).duplex = 'half'; | |
| } | |
| return clonedRequest; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment