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.comBackend 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?
