A response carrying Cache-Control with s-maxage and stale-while-revalidate is cached by the Vercel CDN as instructed, but those directives are removed from the header delivered to the browser. That is deliberate, and it means one header cannot configure both layers.
To control them independently, use CDN-Cache-Control, which conforming CDNs honor and which is forwarded downstream, or Vercel-CDN-Cache-Control, which only Vercel reads and which is not forwarded, alongside a plain Cache-Control aimed at the browser.
Verify what actually happened with the x-vercel-cache response header, whose values are HIT, MISS, STALE, BYPASS, PRERENDER and REVALIDATED. When a route with correct-looking cache headers reports MISS on every request, the usual cause is a Set-Cookie header on the response, since responses that set cookies are not cached. Session middleware that refreshes a cookie on every request disables caching for the entire site this way.