Skip to content

Instantly share code, notes, and snippets.

@studentIvan
Created October 10, 2023 23:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save studentIvan/4a9d765900a63552ec898f826c7116dc to your computer and use it in GitHub Desktop.
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
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