Skip to content

Instantly share code, notes, and snippets.

@Lasalot
Last active January 6, 2026 13:52
Show Gist options
  • Select an option

  • Save Lasalot/c64cfa4ef3c1fecd8a670999321f445c to your computer and use it in GitHub Desktop.

Select an option

Save Lasalot/c64cfa4ef3c1fecd8a670999321f445c to your computer and use it in GitHub Desktop.
NextJS Middleware.js
import { NextResponse } from "next/server";
export async function middleware(request) {
const userAgent = request.headers.get("user-agent");
const bots = [
"googlebot",
"yahoo! slurp",
"bingbot",
"yandex",
"baiduspider",
"facebookexternalhit",
"twitterbot",
"rogerbot",
"linkedinbot",
"embedly",
"quora link preview",
"showyoubot",
"outbrain",
"pinterest/0.",
"developers.google.com/+/web/snippet",
"slackbot",
"vkshare",
"w3c_validator",
"redditbot",
"applebot",
"whatsapp",
"flipboard",
"tumblr",
"bitlybot",
"skypeuripreview",
"nuzzel",
"discordbot",
"google page speed",
"qwantify",
"pinterestbot",
"bitrix link preview",
"xing-contenttabreceiver",
"chrome-lighthouse",
"telegrambot",
"oai-searchbot",
"chatgpt",
"gptbot",
"perplexity",
"claudeBot",
"amazonbot",
"integration-test", // Integration testing
];
const IGNORE_EXTENSIONS = [
".js",
".css",
".xml",
".less",
".png",
".jpg",
".jpeg",
".gif",
".pdf",
".doc",
".txt",
".ico",
".rss",
".zip",
".mp3",
".rar",
".exe",
".wmv",
".doc",
".avi",
".ppt",
".mpg",
".mpeg",
".tif",
".wav",
".mov",
".psd",
".ai",
".xls",
".mp4",
".m4a",
".swf",
".dat",
".dmg",
".iso",
".flv",
".m4v",
".torrent",
".woff",
".ttf",
".svg",
".webmanifest",
];
const isBot =
userAgent && bots.some((bot) => userAgent.toLowerCase().includes(bot));
const isPrerender = request.headers.get("X-Prerender");
const pathname = new URL(request.url).pathname;
const extension = pathname.slice(((pathname.lastIndexOf(".") - 1) >>> 0) + 1);
if (
isPrerender ||
!isBot ||
(extension.length && IGNORE_EXTENSIONS.includes(extension))
) {
return NextResponse.next();
} else {
// Check if request is coming from a bot
if (isBot) {
const newURL = `http://service.prerender.io/${request.url}`;
const newHeaders = new Headers(request.headers);
newHeaders.set("X-Prerender-Token", process.env.PRERENDER_TOKEN);
newHeaders.set("X-Prerender-Int-Type", "NextJS");
try {
const res = await fetch(new Request(newURL, {
headers: newHeaders,
redirect: "manual",
}));
const responseHeaders = new Headers(res.headers);
responseHeaders.set("X-Redirected-From", request.url);
// Create a ReadableStream from the response body
const { readable, writable } = new TransformStream();
res.body.pipeTo(writable);
const response = new NextResponse(readable, {
status: res.status,
statusText: res.statusText,
headers: responseHeaders,
});
return response;
} catch (error) {
return NextResponse.next();
}
} else {
console.log('Not a bot, proceeding normally');
}
return NextResponse.next();
}
}
@Lasalot
Copy link
Author

Lasalot commented Aug 22, 2024

for next 12.2+ how can i replace the return new Response (line 118~122) to NextResponse.rewrite or NextResponse.redirect ?

import { NextResponse } from 'next/server';

export function middleware(request) {
  // Your own logic
  if (someCondition) {
    // Rewrite request to a different URL
    const url = request.nextUrl.clone();
    url.pathname = '/new-path'; // The new path you want to redirect to

    return NextResponse.rewrite(url);
  }

//Default response
  return NextResponse.next();
}

For redirect:

import { NextResponse } from 'next/server';

export function middleware(request) {
  // Your own logic
  if (someCondition) {
    // Redirect to a different URL
    const url = new URL('/new-path', request.url);
    return NextResponse.redirect(url, 301); // 301 for permanent redirect
  }

  // Default response
  return NextResponse.next();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment