Next.js Discord

Discord Forum

Shallow Routing with dynamic routes

Unanswered
Sloth bear posted this in #help-forum
Open in Discord
Sloth bearOP
Recently, due to some requirements of the project, we created some middleware to force all url paths within the app to lowercase, however, with dynamic paths, the links end up producing something along the lines of: /user/test?username=test, if we modify next/link to enable shallow routing, it strips the extra stuff from the url, but causes page flickers;

What would be the proper way to resolve it, rather than just doing
<Link href={`/user/${username.toLowerCase()}`}>profile</Link>


middleware:

export function middleware(request: NextRequest) {
    const pathname = request.nextUrl.pathname
    // Check if the pathname is not lowercase
    if (pathname !== pathname.toLowerCase()) {
        // Create a new URL with the lowercase pathname
        const url = request.nextUrl.clone()
        url.pathname = pathname.toLowerCase()

        // Redirect to the lowercase URL
        return NextResponse.redirect(url)
    }
}

12 Replies

Ojos Azules
in middleware you arent preserve search parameters (query params) when constructing the new URL. The issue occurs because request.nextUrl.clone() does not automatically retain the search parameters when modifying the pathname.
so something like this ??
const url = new URL(request.nextUrl.origin + pathname.toLowerCase() + request.nextUrl.search);
@Ojos Azules is it? that sounds strange , can you create a short sandbox and reproduce the issue
Sloth bearOP
Reproduction is just using that middleware with next/link on a dynamic route;

I can “fix” it by just putting toLowerCase() on every dynamic path but that seems relatively hacky
Ojos Azules
yeah, putting lowerCase() and producing extra search parameters seems not related at all, all i can say
 (pathname !== pathname.toLowerCase()) {
this line is checking for not lower case and if you explicitly put lower case then it will bypass this condition.
I dont understand what you mean by next/link on a dynamic route, is it like when you add link inside of pages/user/[id]/page.tsx ?
I would recommend reproducing it on Sandbox and screen record of it .
using a standard html link works fine though with the expected behavior of forcing everything lowercase, so not sure where the random query parameter comes from lol, if I remove that middleware stuff, links work fine again
@Sloth bear it's particularly using dynamic links yeah: ts <Link href={`/user/${user.username}`>{user.username}</Link> when utilizing links in this fashion, all dynamic links, if a username results in something like `Limbo_Anj`, it'll return `/user/Limbo_anj?username=Limbo_Anj`
Ojos Azules
https://codesandbox.io/p/devbox/3h47mj?file=%2Fapp%2F_components%2Fdynamic-links.tsx%3A12%2C15 check this sandbox, i added your middleware, add links for user object like this and for me, it isnt adding any search param, can you console user, username and see what you are having?
@Ojos Azules https://codesandbox.io/p/devbox/3h47mj?file=%2Fapp%2F_components%2Fdynamic-links.tsx%3A12%2C15 check this sandbox, i added your middleware, add links for user object like this and for me, it isnt adding any search param, can you console user, username and see what you are having?
Sloth bearOP
it works fine when you visit the path name through the physical linking of it in the address bar, it seems to only be an issue with clicking a link to a dynamic page;

if shallow is enabled as true it works properly, but causes page flickering due to SSR not being re-triggered, so my thought is it's something else?

for more context this projet is also utilizing pages router
Ojos Azules
you see when i hover on the button Limbo_anj. and see the URL on left bottom, it has not added any search params, and user/[username]/page.tsx is a dynamic page right
Sloth bearOP
import { NextRequest, NextResponse } from "next/server";

export function middleware(request: NextRequest) {
  if (request.nextUrl.pathname === request.nextUrl.pathname.toLocaleLowerCase())
    return NextResponse.next();
  return NextResponse.redirect(
    `${request.nextUrl.origin}${request.nextUrl.pathname.toLocaleLowerCase()}`
  );
}


this seems to have solved it, otherwise I guess I just add toLowerCase() on all instances of user.username