What can be done to stop the caching of the route that router.push() redirects to in Next.js middleware?

Encountering an issue with client-side navigation and middleware in the router. It seems that the router is storing the initial redirect path and subsequent navigations bypass the middleware.

This behavior ceases upon browser refresh and does not occur in a development environment.

I aim to have the router consistently pass through the middleware for redirection evaluation each time.

To recreate this issue:

  1. Repeatedly go to / from the browser search bar. There's a 50% chance of being redirected to /dashboard or /profile due to middleware.ts
  2. Access /login and click on Login button. This triggers a router.push('/') which redirects to either /dashboard or /profile.
  3. Click Logout button, initiating a router.push('/login').
  4. Subsequent Logins will always direct to the same route.

My middleware function in middleware.ts:

export function middleware(request: NextRequest) {
  if (request.nextUrl.pathname === '/') {
    if (Math.random() > 0.5) {
      return NextResponse.redirect(new URL('/dashboard', request.url))
    } else {
      return NextResponse.redirect(new URL('/profile', request.url))
    }
  }
}

My login.tsx file:

import { NextPage } from 'next'
import { useRouter } from 'next/router'

const LoginPage: NextPage<{}> = () => {

  const router = useRouter()
  const login = () => {
    router.push('/')
  }

  return (
    <div>
      <h1>Login</h1>
      <button onClick={login}>Login</button>
    </div>
  )
}

export default LoginPage

Dashboard/Profile Page code:

import { NextPage } from 'next'
import { useRouter } from 'next/router'

const DashboardPage: NextPage<{}> = () => {
  const router = useRouter()

  const logout = () => {
    router.push('/login')
  }

  return (
    <div>
      <h1>DashboardPage</h1>
      <button onClick={logout}>Logout</button>
    </div>
  )
}

export default DashboardPage

Vercel site demo:

Full code available at: https://github.com/LautaroRiveiro/nextjs-router-clientside-test

Answer №1

According to a discussion on GitHub issue #30938, the default behavior described is expected.

This caching of HEAD requests is done intentionally to minimize the number of requests, although it can still pose issues (#30901).

If you wish to disable caching of HEAD requests and trigger revalidation upon client-side navigation, you can set the x-middleware-cache header with a value of no-cache (refer to PR #32767) before redirecting in the middleware.

export function middleware(request: NextRequest) {
    if (request.nextUrl.pathname === '/') {
        const redirectUrl = Math.random() > 0.5 ? '/dashboard' : '/profile'
        const response = NextResponse.redirect(new URL(redirectUrl, request.url))
        response.headers.set('x-middleware-cache', 'no-cache') // Disables middleware caching
        return response;
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issues with Parameters in JavaScript Functions

I have been researching online and every website I visit suggests that a function would take a parameter if declared, but for some reason it's not working in my case. It works fine like this: <script type='text/javascript'> function ...

Tick the box to activate the ability to uncheck multiple boxes when there are already a certain number of boxes checked

I am currently developing a multiple-choice form in my MVC5 app and I am struggling to find a way to disable unchecked boxes once a specific number of boxes have been checked. For example, if 3 out of 5 boxes are checked, the remaining 2 should be disabled ...

When the component is initialized, the computed property is not being evaluated

My maps component initializes a Google map, adds markers based on props passed from the parent, and sets the correct bounds of the map. However, the markers are added through a computed property to make it reactive. Everything seems to be working fine, exc ...

Adding a MTL texture to an OBJ in your three.js project is a simple process that can enhance

Hello! I am currently working on adding an MTL file to my OBJ in three.js. I had successfully loaded my OBJ and went back to address this issue. However, after adding the code to load the MTL file using MTLLoader, the code seems to be getting stuck at mt ...

Is there a way for me to determine the specific link that I have clicked on

I am implementing a table where users can edit the columns. Each cell contains an <a> tag that triggers a modal to change the value in the database and refresh the page. The issue I'm facing is that once the modal appears, the code doesn't ...

I am currently transferring cross-site forgery tokens through jQuery strings. However, on the subsequent page, I create a fresh token which means their original tokens will no longer align

Alright, so I've been storing the tokens in a session: Session::get('token', 'randomtokenstringhere'); Every time a form is submitted, whether successfully or not, I generate a new token and update their session token. But let&ap ...

Looking for a specific phrase in the data entered by the user

I am dealing with data in ckeditor that looks like this: <p>test 1</p> <p>test 2</p> <p><img src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQODwwQFxQYGBcUFhYaHSUfGhsjHBYWICw ...

Exploring the power of TypeScript for authenticating sessions with NextJS

Utilizing next-auth's getSession function in API routes looks something like this for me: const mySession = await getSession({ req }); I have confirmed that the type of the mySession is outlined as follows: type SessionType = { user: { email: s ...

"What is the best way to use jQuery to create a toggle effect where one button controls the state

I'm looking to improve the efficiency of my code, but I'm not sure where to start in terms of making it more concise and organized. Any suggestions on how to streamline this code and keep it neat would be greatly appreciated. $(document).ready(fu ...

Expo app crashes when using React Native/Expo combined with Next.js (Error: Variable "React" not found in withExpoRoot.js)

I am facing an issue with my React Native/Expo + Next.js app that I built using the command npx create-next-app -e with-expo. To view the full code, visit: https://github.com/tomsoderlund/reactnative-nextjs-template The app functions properly as a web ap ...

Creating a Copy of an Object in JavaScript that Automatically Updates When the Original is Changed

I am in the process of developing a planner/calendar website with a repeat feature. var chain = _.chain(state.items).filter({'id': 1}).head().value(); console.log(chain); After filtering one object, I am wondering how to create a duplicate of c ...

Merge the values of two select tags into a single textbox

There are two select Tags along with a text box included. <select name="select1"> <option>1</option> <option>2</option> </select> <select name="select2"> <option>1</option> <option>2 ...

Ways to determine the current page I am viewing

I am working with a list of tabs and I need to track my current location every time I click on a specific tab. My MainCTRL controller, which is the parent of all tab controllers, needs to be aware of the active tab at any given moment. I attempted to use n ...

There seems to be an issue with .ENV functionality in Razzle JS

Attempting to deploy a Razzle project on an Ubuntu server has been challenging. I have created a .env file with two variables: port=80 and host=192.168.1.5. However, when running the project, it defaults to localhost:3000. I've tried exporting PORT=80 ...

Getting the selected value from a dropdown menu in ReactJS

I am working on creating a form that resembles the following structure: var BasicTaskForm = React.createClass({ getInitialState: function() { return { taskName: '', description: '', emp ...

Prevent the bottom row from being sorted

I have implemented sortable table rows in my angular project, however the sorting functionality also affects some query-ui code elements. Now I am looking to exclude the last row from being sortable. HTML <div ng:controller="controller"> <ta ...

Is there a way to enclose an element with two other elements using JavaScript/jQuery

Is it possible to create a wrapping element for content located between two existing elements? Here's a code snippet to illustrate: <p> Some text some text <span class="foo">some more text</span> additional text. </p> <p> ...

Setting up Webhook for Clerk in a Next.js and Prisma (T3 stack) environment

I am facing a challenge in my personal project using Next.js (T3 stack) where I need to synchronize Clerk users with a user table in my Supabase DB. My goal is to have a Users table, defined in my schema.prisma, that includes the user_id from Clerk along ...

Steering clear of using relative paths for requiring modules in Node.js

When it comes to importing dependencies, I like to avoid using excessive relative filesystem navigation such as ../../../foo/bar. In my experience with front-end development, I have found that using RequireJS allows me to set a default base path for "abso ...

Ways to increase the values in a textbox

My task involves handling checkboxes that are populated with data from a database. The goal is to have certain checkboxes pre-checked based on the retrieved data, and if any are not checked, their values should be entered into a textbox. For instance, con ...