NextJS App Router: redirect all routes to two nested dynamic routes as root

366 views Asked by At

was wondering if anyone could help with this issue I'm having learning the app router in regards to deeply nested dynamic routes.

Lets say I have an ecommerce shop which hosts multiple stores with their own available shopping modes (pickup and delivery) and would like to have the store id and shopping mode in the url: www.shop.com/store/STOREID/sm/SHOPPINGMODE.

When first time users visit www.shop.com they are first asked which shop they want and shopping mode (saved locally as a cookie for example) and any future visits it will redirect them from the root to the /store/STOREID/sm/SHOPPINGMODE url as mentioned.

The other thing is that if the user has a store selected and they decide to go www.shop.com/products it will redirect them to www.shop.com/store/STOREID/sm/SHOPPINGMODE/products instead.

So basically any url should have store/STOREID/sm/SHOPPINGMODE appended to it:

  • If first time visit: www.shop.com -> choose store -> www.shop.com/store/STOREID/sm/SHOPPINGMODE
  • If proceeding visit: www.shop.com -> www.shop.com/store/STOREID/sm/SHOPPINGMODE
  • If first time visit any url (such as products): www.shop.com/products -> choose store -> www.shop.com/store/STOREID/sm/SHOPPINGMODE/products
  • If proceeding visit any url (such as products): www.shop.com/products -> www.shop.com/store/STOREID/sm/SHOPPINGMODE/products

Hopefully that makes sense. What would be the most efficient way to implement this scenario? Middlewares? Redirects via config or in page? Something else?

Any help would be greatly appreciated!

1

There are 1 answers

0
Rafael Fernandes On BEST ANSWER

I think using the scenario that you have mentioned, it's more efficient to use SHOPPINGMODE and STOREID in the same way to validate whether a user is logged in or not. Whoever your e-commerce needs to have this information, like app functionality, validating cookies in the middleware can guarantee it, like:

// config matcher to not catch routes of static content or api and with store id and shopping mode

export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)',
  '/((?!(store\/[0-9]*\/sm\/(pickup|delivery))).*)'
  ],
}
export function middleware(request: NextRequest) {

  const HOME = '/'

    // First verify if this cookies exist
  
  const HAS_STORE_ID = request.cookies.has('X_STORE_ID')
  const HAS_SHOPPING_MODE =          request.cookies.has('X_SHOPPING_MODE')
  
  if(HAS_STORE_ID && HAS_SHOPPING_MODE) {
  
  // Get values
  
  const STORE_ID = request.cookies.get('X_STORE_ID')
  const SHOPPING_MODE = request.cookies.get('X_SHOPPING_MODE')
  
  // You can verify if are valid values on database here or redirect later catching the error of page not found
  
  verifyValidStoreCookies(STORE_ID,SHOPPING_MODE)
  
  const url = `/store/${STORE_ID}/sm/${SHOPPING_MODE}`
  
  return NextResponse.rewrite(new URL(url, request.url))
    const { pathname } = req.nextUrl

  }
  
  if (HAS_STORE_ID) {
    response.cookies.delete('X_STORE_ID')

    return NextResponse.rewrite(new URL(HOME, request.url))

  }
   if (HAS_SHOPPING_MODE) {
        response.cookies.delete('X_SHOPPING_MODE')

    return NextResponse.rewrite(new URL(HOME, request.url))

  }
  
    return NextResponse.rewrite(new URL(HOME, request.url))

}

You can use path search to append any paths to the end of the request URL and to verify if they are applicable or not, like:

const prefixes = ['/shop', '/products']

const { pathname } = request.nextUrl
 
  if (prefixes.some((prefix) => pathname.startsWith(prefix))) {
    const url = `/store/${STORE_ID}/sm/${SHOPPING_MODE}` + pathname
    return NextResponse.rewrite(new URL(url, request.url))
    ...
  }
 
  if (
    !pathname.endsWith('/') &&
    !pathname.match(/((?!\.products(?:\/.*)?)(?:[^/]+\/)*[^/]+\.\w+)/)
  ) {
   ...
  }

You can view more methods here: https://nextjs.org/docs/app/building-your-application/routing/middleware

But it is always only one approach; it can change and be improved depending on your business rules. I hope it helps in some way.