skip to Main Content

I have this project migrating from AngularJS, so there is some requirements that need to be met. And I am having lots of problems with routing using NextJS

Let me explain the problem. The URL to this app will be something like:
https://some_domain/wafrToken/step1 or https://some_domain/step1.

wafrToken is just a placeholder for a 56 hexadecimal string, like ex:56e6a6d7bacd4db14eadbd7bf4eeee550ec13853c64c946f490aa574

This string varies. The above is just one example, and it’s always different.

So the actual URL might be like https://some_domain/ex:56e6a6d7bacd4db14eadbd7bf4eeee550ec13853c64c946f490aa574/step1

And the step1 is the actual route, that will change depending on where the user "is" on the application, so it can be step1, or step2, or step3, or viewer, well you get the ideia.

And in the other situation the URL might just be like https://some_domain/step1. In this case no wafrToken, just domain and the route.

So I need to have a routing solution in place that allows me to navigate to step1, or step2 whether we have wafrToken in the URL or not.

Dynamic routes doesn’t seem to work because wafrToken is not always available. Dynamic Optional routes also seem to not work because they must be the last part of the URL.

So my question is: how can I achieve this using NextJS App router or Page router?

Thx in advance for your help.

2

Answers


  1. There are a few ways to do this. Here is what I would recommend:

    Dynamic routes

    You can use dynamic routes a feature built in to both the Next.js pages and app router. Then you can nest these in a similar structure to this [slug-1]/[slug-2].

    Setup your project like so:

    |app
       |components
          |Steps.tsx //this is your page you want to display
       |[slug-1]
          page.tsx
          |[slug-2]
             page.tsx
    

    Then setup each page as shown:

    import Steps from "../components/Steps";
    
    export default function Page({
      params,
    }: {
      "slug-1": string;
      "slug-2": string;
    }) {
      return <Steps />;
    }
    
    

    See the code sandbox for more info.

    This follows the exact plan that you had in mind with what you were doing with Angular.

    Query strings

    Only in the app router

    Personally I think this a more ideal approach it is simpler and produces more dry code. Instead of using a dynamic route for wafrToken use a query string. This will follow this url structure: https://some_domain/step1?wafrToken=56e6a6d7bacd4db14eadbd7bf4eeee550ec13853c64c946f490aa574.

    Setup your project like so:

    |app
       |components
          |Steps.tsx //this is your page you want to display
       |[slug-1]
         page.tsx
    

    Each page as shown:

    import Steps from "../components/Steps";
    
    export default function Page({ params }: { "slug-1": string }) {
      console.log(params);
      return <Steps />;
    }
    
    

    And the Steps component:

    "use client";
    
    import { useSearchParams } from "next/navigation";
    
    export default function Steps() {
      const query = useSearchParams();
      console.log(query);
      return <h1>Steps</h1>;
    }
    
    

    Important: the Steps component must be a client component as it uses a React hook. Learn more.

    See the code sandbox for more info.

    Further considerations

    • Consider a more consistent url structure. Maybe always require a token and if there is no token encode null.
    • Consider not using Next.js for this portion of your app. Maybe Angular is better suited here. You could try a monorepo like Nx and have a steps directory written in Angular and everything else in Next (this however will add more complexity).

    App router vs pages

    So my question is: how can I achieve this using NextJS App router or Page router?

    In case you were unsure of which to use I thought I would include this bonus section.

    The short answer is: almost always use the app router for new codebases. Since you are migrating start on the new app router.

    Here is a more in depth comparison:

    Feature App Router Pages Router
    Routing type Server-centric Client-side
    Support for Server Components Yes No
    Complexity More complex Simpler
    Performance Better Worse
    Flexibility More flexible Less flexible

    Credit krishnaacharyaa

    As a general rule if you are unsure use the app router.

    Conclusion

    Circling back to the original scope of the question I would recommend using the query string approach using the app router.

    Login or Signup to reply.
  2. @Ethan answer should be an ideal solution here and its best for you to go with NextJS 14 App router … Use your token as url query string and it should do your job
    If you want to do Server side rendering then it is not possible to get URL query parameter in SSR (fetching SearchParams works only in client component read here). But you can still get your ‘query string’ by importing a child component(client) and doing all ‘query string’ related operation in the child component without compromising SSR.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search