Created
October 10, 2023 23:53
-
-
Save studentIvan/4a9d765900a63552ec898f826c7116dc to your computer and use it in GitHub Desktop.
Example next.js custom server with headers taken from the page meta tags to solve the problem https://github.com/vercel/next.js/issues/50914
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createServer, type IncomingMessage, type ServerResponse } from "http"; | |
import { StringDecoder } from "string_decoder"; | |
import { parse } from "url"; | |
import next from "next"; | |
import nextConfig from "../next.config"; | |
const decoder = new StringDecoder("utf-8"); | |
const port = parseInt(process.env.PORT || "", 10) || 8080; | |
const app = next({ dev: process.env.NODE_ENV !== "production", ...nextConfig }); | |
const handle = app.getRequestHandler(); | |
const parseMetaContent = (tagName: string, decodedBuffer: string) => { | |
const [, result] = | |
decodedBuffer.match( | |
new RegExp(`name=(?:")?${tagName}(?:")? content=(?:")?([a-z0-9-, ]+)(?:")?`) | |
) || []; | |
return result; | |
}; | |
const setHeaderIfPresents = ( | |
res: ServerResponse<IncomingMessage>, | |
name: string, | |
value?: string | |
) => { | |
if (value) res.setHeader(name, value); | |
}; | |
app.prepare().then(() => { | |
createServer(async (req, res) => { | |
const parsedUrl = parse(req.url!, true); | |
if (!req.url?.includes(".")) { | |
/** save the link to the res.write function */ | |
const write = res.write.bind(res); | |
let i = 0; | |
/** hack the res.write function and wrap it with the custom one */ | |
res.write = (buffer: Buffer) => { | |
/** meta tags are placed only in the first frame */ | |
if (++i === 1) { | |
const decoded = decoder.write(buffer); // with GZIP disabled decoder able to decode the buffer to string | |
/** is ok to set the header here with transfer-encoding: chunk */ | |
setHeaderIfPresents(res, "Cache-Tag", parseMetaContent("cacheTag", decoded)); | |
setHeaderIfPresents(res, "X-Robots-Tag", parseMetaContent("robots", decoded)); | |
} | |
return write(buffer); | |
}; | |
} | |
await handle(req, res, parsedUrl); | |
}) | |
.once("error", (err) => { | |
console.error(err); | |
process.exit(1); | |
}) | |
.listen(port, () => { | |
console.log(`> Ready on http://localhost:${port}`); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment