Rewrite and redirect in Next.js



Rewrite
In Next.js, the rewrite method is a way to change the URL of a request before it is handled by the application. It can be used to redirect the request to a different URL, or to modify the pathname or other parts of the URL to match a specific pattern.
The rewrite method is a part of the NextResponse object, which is an object that represents the HTTP response that will be sent to the client. To use the rewrite method, you can import the NextResponse object from the next/server module and then call the rewrite method on it, passing in a new URL object as an argument.
Here's an example of how the rewrite method can be used to redirect a request to a different URL:
import { NextResponse } from 'next/server'
export async function middleware(request) {
if (request.nextUrl.pathname === '/old-page') {
return NextResponse.rewrite(new URL('/new-page', request.url))
}
}
In this example, the middleware function is a middleware function that runs on the server side of a Next.js application. It checks the pathname of the request and, if it is /old-page, it redirects the request to /new-page using the NextResponse.rewrite method.
You can also use the redirect method of the NextResponse object to redirect a request to a different URL. The redirect method is similar to the rewrite method, but it sends an HTTP redirect response to the client, telling the client's browser to navigate to a different URL. Here's an example of how the redirect method can be used:
import { NextResponse } from 'next/server'
export async function middleware(request) {
if (request.nextUrl.pathname === '/old-page') {
return NextResponse.redirect('/new-page')
}
}
In this example, the middleware function is again checking the pathname of the request, and if it is /old-page, it redirects the request to /new-page using the NextResponse.redirect method.
import { NextResponse } from 'next/server'
import getAllCategories from "@/util/bigCommerce/getAllCategories";
// import { getSession } from "next-auth/client"
export async function middleware(request) {
/* http://localhost:3000/testRedirect */
if (request.nextUrl.pathname.startsWith('/testRedirect')) {
return NextResponse.rewrite(new URL('/', request.url))
}
const allCategories = await getAllCategories();
const paths = allCategories.map((cat) => "/" + cat.custom_url.url.substring(1));
if(paths.find(path => request.nextUrl.pathname.startsWith(path))) {
return NextResponse.rewrite(new URL('/category' + request.nextUrl.pathname, request.url))
}
}
- he first thing that was changed was the removal of an
ifstatement that checked if the pathname of the request started with/testRedirect. This part of the code was removed entirely. - The
getAllCategoriesfunction was called and its result was stored in theallCategoriesvariable. This function retrieves a list of categories from a BigCommerce store. - The
allCategoriesarray was filtered to remove any category with a custom URL of/store. This was done using thefiltermethod, which creates a new array with all elements that pass the provided test function. - The
substringmethod was called on thecustom_url.urlproperty of each category, with an argument of1, to remove the leading/character. This was done to create an array of paths that can be used to match against the pathname of the request. - The final change was to the
ifstatement that checks if the pathname of the request starts with any of the paths in thepathsarray. If it does, the request is rewritten using theNextResponse.rewritemethod to add the/categoryprefix to the pathname.
Overall, the changes made to the code involve a refactoring of the logic used to handle requests for category pages. Instead of using a catch-all route at the root level of the application, the code uses middleware to rewrite the request and place it inside a /category directory. This allows the application to handle category pages without affecting other pages or the SEO URL structure.
import { NextResponse } from "next/server";
import getAllCategories from "@/util/bigCommerce/getAllCategories";
export async function middleware(request) {
// Problem: Cannot place Catch-All route for category urls in root directory without affecting other pages.
// Cannot move Catch-All route inside a directory natively without affecting SEO URL structure.
// Solution: Use middleware to rewrite Catch ALL Routes inside a category directory.
const allCategories = await getAllCategories();
// Remove store category. Handled differently with dynamic routes
const noStore = allCategories.filter(
(cat) => cat.custom_url.url !== "/store"
);
//
const paths = noStore.map((cat) => "/" + cat.custom_url.url.substring(1));
if (paths.find((path) => request.nextUrl.pathname.startsWith(path)))
return NextResponse.rewrite(
new URL("/category" + request.nextUrl.pathname, request.url)
);
}
