OAuth Callback Route Not Matching After Deployment (Vite + React on Vercel, Express Backend on Render)

1 week ago 5
ARTICLE AD BOX

I’m building a dynamic form builder using Airtable’s OAuth PKCE flow. My stack is:

Frontend: React + Vite on Vercel

Backend: Node.js + Express on Render

OAuth provider: Airtable

The OAuth flow works locally, but after deployment the callback URL fails with the following error:

Error: Cannot match any routes. URL Segment: 'oauth/airtable/callback'

Instead of loading my Callback.jsx, Vercel shows a 404 and the React router doesn’t recognize the route.

Frontend env:

VITE_CLIENT_ID=xxx VITE_AIRTABLE_REDIRECT_URI=https://dynamic-form-builder.vercel.app/oauth/airtable/callback VITE_API_URL=https://dynamic-form-builder-2l3f.onrender.com

Backend env:

CLIENT_ID=xxx CLIENT_SECRET=xxx AIRTABLE_REDIRECT_URI=https://dynamic-form-builder.vercel.app/oauth/airtable/callback API_URL=https://dynamic-form-builder-2l3f.onrender.com MONGODB_URI=...

Callback component

import { useState, useEffect } from "react"; export default function Callback() { const [status, setStatus] = useState("Processing..."); useEffect(() => { const params = new URLSearchParams(window.location.search); const code = params.get("code"); const codeVerifier = sessionStorage.getItem("pkce_code_verifier"); const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:4000'; fetch(`${API_URL}/oauth/token`, { method: "POST", headers: { "Content-Type": "application/json" }, credentials: "include", body: JSON.stringify({ code, code_verifier: codeVerifier }), }) .then(res => res.json()) .then(data => { if (data.success) { window.location.href = "/bases"; } }); }, []); return <div>{status}</div>; }

Locally, visiting:

http://localhost:5173/oauth/airtable/callback?code=...

correctly loads the component and exchanges the token.

But on Vercel, when Airtable redirects to:

https://dynamic-form-builder.vercel.app/oauth/airtable/callback?code=...

I get the router error above.

Question: How can I configure Vercel or Vite so that deep links to client-side routes like /oauth/airtable/callback load the index.html and allow React Router to handle the route?

Read Entire Article