next.jsserver-side-rendering

In next.js server side page component (in the app directory), how do you get the current url?


I am using next.js version 13. experimental app directory, which does not have access to getServerSideProps()

Pages in the "app" directory are server side by default.

Inside page.js, I am trying to get the url of the current page.

How would I do that?

export default async function myPage(props) {
    const prot =  // HTTP or HTTPS
    const domain = //www.myserver.com
    const port = //3000
    ... and so on.
    
    
}


I saw this solution: Get URL pathname in nextjs

But 'next\router' that doesn't work on server components.

I get this error when compiling: You have a Server Component that imports next/router. Use next/navigation instead.


Solution

  • I don't know what your use case is, but I needed to get the current url so I could redirect unauthenticated users to the login page with a redirectTo param.

    Per the Next.js documentation:

    Layouts do not have access to the current route segment(s)

    Instead this can be implemented using middleware:

    import { NextResponse } from 'next/server';
    import type { NextRequest } from 'next/server';
    
    export async function middleware(req: NextRequest) {
    
      if (req.nextUrl.pathname.startsWith('/protected/path') && userIsUnauthenticated()) {
        const currentUrl = req.nextUrl;
        const redirectTo =
          currentUrl.pathname + currentUrl.search + currentUrl.hash;
    
        const redirect = new URL('/login', req.url);
        redirect.searchParams.set('redirectTo', redirectTo);
        return NextResponse.redirect(redirect);
      }
    
      return NextResponse.next();
    }
    

    The key here is NextRequest.nextUrl which

    Extends the native URL API with additional convenience methods, including Next.js specific properties.

    Example:

    const protocol = req.nextUrl.protocol // HTTP or HTTPS
    const domain = req.nextUrl.hostname // www.myserver.com
    const port = req.nextUrl.port // 3000