/** * This middleware looks at the URL if it's something like: * * /_next/data/oOIffMZgfjR6sR9pa50O9/en/free-pro-team%40latest/pages.json?... * * And from that, it compares that oOIffMZgfjR6sR9pa50O9 with the content * of the .next/BUILD_ID file. If they don't match, then it's going to 404. * But instead of letting the nextApp.render404() handle it, we're going to * manually handle it here. * This makes sure the response is a short and fast plain text 404 response. * And we can force it to be served with a cache-control which allows * the CDN to cache it a bit. * * Note that when you start the local server with `npm run dev` and * do client-side navigation in the app, NextJS will send XHR requests for... * * /_next/data/development/en/free-pro-team%40latest/pages.json?... * * Relying on that test is easier than to try to parse the * value of `process.env.NODE_ENV`. */ import fs from 'fs' import type { Response, NextFunction } from 'express' import { ExtendedRequest } from '@/types' import { errorCacheControl } from '@/frame/middleware/cache-control' export default function handleOldNextDataPaths( req: ExtendedRequest, res: Response, next: NextFunction, ) { if (req.path.startsWith('/_next/data/') && !req.path.startsWith('/_next/data/development/')) { const requestBuildId = req.path.split('/')[3] if (requestBuildId !== getCurrentBuildID()) { errorCacheControl(res) res.status(404).type('text').send('build ID mismatch') return } } return next() } let _buildId: string function getCurrentBuildID() { // Simple memoization if (!_buildId) { _buildId = fs.readFileSync('.next/BUILD_ID', 'utf-8').trim() } return _buildId }