mirror of
https://github.com/netbirdio/docs.git
synced 2026-08-24 16:51:26 +02:00
Serve props JSON for /api data requests via middleware rewrite (#902)
* fix: serve props JSON for /api data requests via middleware rewrite The /api/:path* -> /ipa/:path* rewrite in next.config.mjs is applied by Vercel's routing to client-side props fetches (/_next/data/<buildId>/api/....json), but the data-request context is lost and the prerendered page HTML is returned instead of JSON (vercel/next.js#39669). The router then never receives pageProps, so the API sidebar stays collapsed and the tab title shows undefined until a full reload. This half of the bug only occurs on Vercel infrastructure; the dev server and next start resolve rewrites for data requests correctly, and #900 fixed only the /ipa redirect half. Middleware rewrites preserve data-request semantics, so rewrite /api/* to /ipa/* in middleware for data requests only (x-nextjs-data header). Regular page requests fall through to the existing config rewrites, and the /ipa -> /api canonical redirect is unchanged. * fix: move /api data-request rewrite into existing proxy.js Next 16 uses proxy.js and rejects builds where both middleware.js and proxy.js exist; this repo already had src/proxy.js for the /docs-static/_next asset rewrite. Fold the /api -> /ipa data-request rewrite into it and drop middleware.js. Verified the proxy intercepts: data responses now carry x-middleware-rewrite: /ipa/... and JSON bodies. * fix: map bare api.json data requests to ipa/introduction.json The raw data-path fallback rewrote /_next/data/<build>/api.json to /_next/data/<build>/ipa.json, but there is no /ipa index page; mirror the /api -> /ipa/introduction rewrite instead.
This commit is contained in:
40
src/proxy.js
40
src/proxy.js
@@ -1,10 +1,46 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
// Client-side navigations fetch page props from /_next/data/<buildId>/api/....json.
|
||||
// Vercel's routing applies the /api/:path* -> /ipa/:path* rewrite from
|
||||
// next.config.mjs to those requests but loses the data-request context and
|
||||
// serves the page HTML instead of the props JSON
|
||||
// (https://github.com/vercel/next.js/issues/39669), so the router never
|
||||
// receives pageProps. Proxy rewrites keep data-request semantics, so map
|
||||
// /api/* to /ipa/* here for data requests only; regular page requests fall
|
||||
// through to the config rewrites, and the /ipa -> /api canonical redirect
|
||||
// is unchanged.
|
||||
function rewriteApiDataRequest(req) {
|
||||
const isDataRequest =
|
||||
req.headers.get('x-nextjs-data') !== null ||
|
||||
req.nextUrl.pathname.startsWith('/_next/data/');
|
||||
if (!isDataRequest) return null;
|
||||
|
||||
const url = req.nextUrl.clone();
|
||||
if (url.pathname.startsWith('/_next/data/')) {
|
||||
// Raw data-request path, in case the runtime matches it un-normalized.
|
||||
// Bare api.json maps to ipa/introduction.json to mirror the /api ->
|
||||
// /ipa/introduction rewrite; there is no /ipa index page.
|
||||
url.pathname = url.pathname
|
||||
.replace(
|
||||
/^(\/_next\/data\/[^/]+)\/api\.json$/,
|
||||
'$1/ipa/introduction.json',
|
||||
)
|
||||
.replace(/^(\/_next\/data\/[^/]+)\/api\//, '$1/ipa/');
|
||||
} else if (url.pathname === '/api') {
|
||||
url.pathname = '/ipa/introduction';
|
||||
} else if (url.pathname.startsWith('/api/')) {
|
||||
url.pathname = url.pathname.replace(/^\/api\//, '/ipa/');
|
||||
}
|
||||
|
||||
if (url.pathname === req.nextUrl.pathname) return null;
|
||||
return NextResponse.rewrite(url);
|
||||
}
|
||||
|
||||
export function proxy(req) {
|
||||
if (req.nextUrl.href.includes('/docs-static/_next/'))
|
||||
return NextResponse.rewrite(
|
||||
req.nextUrl.href.replace('/docs-static/_next/', '/_next/'),
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
return rewriteApiDataRequest(req);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user