160

I have a signin page and layout component.Layout component has header.I don't want to show header in signin .and for that I want to get url pathname.based on pathname show the header .

import * as constlocalStorage from '../helpers/localstorage';
import Router from 'next/router';

export default class MyApp extends App {
    componentDidMount(){
        if(constlocalStorage.getLocalStorage()){
            Router.push({pathname:'/app'});
        } else{
            Router.push({pathname:'/signin'});
        }

    }

    render() {
        const { Component, pageProps } = this.props
        return (
//I want here pathname for checking weather to show header or not
                <Layout>
                    <Component {...pageProps} />
                </Layout>
        )
    }
}

please help

1

19 Answers 19

160

If you want to access the router object inside any functional component in your app, you can use the useRouter hook, here's how to use it:

import { useRouter } from 'next/router'

export default function ActiveLink({ children, href }) {
  const router = useRouter()
  const style = {
    marginRight: 10,
    color: router.pathname === href ? 'red' : 'black',
  }

  const handleClick = e => {
    e.preventDefault()
    router.push(href)
  }

  return (
    <a href={href} onClick={handleClick} style={style}>
      {children}
    </a>
  )
}

If useRouter is not the best fit for you, withRouter can also add the same router object to any component, here's how to use it:

import { withRouter } from 'next/router'

function Page({ router }) {
  return <p>{router.pathname}</p>
}

export default withRouter(Page)

https://nextjs.org/docs/api-reference/next/router#userouter

Sign up to request clarification or add additional context in comments.

1 Comment

What about API routes? How to access router instance in Next.js API route?
69

You can use asPath property, that will give you the path (including the query) shown in the browser without the configured basePath or locale:

const { asPath } = useRouter()

Comments

58

Suppose the complete URL of a page is 'abc.com/blog/xyz' and the component file name matching with this route is './pages/blog/[slug].js'

useRouter() hook returns a route object, which has two properties to get the pathname.

  1. One is asPath property, and

  2. Another one is pathname property.

asPath property contains pathname extracted from the URL i.e. /blog/xyz

but pathname property contains the pathname of your project directory i.e. /blog/[slug].

Example Implementation

// .pages/blog/[slug].js

import { useRouter } from 'next/router';

const BlogSlug = () => {
  const { asPath, pathname } = useRouter();
  console.log(asPath); // '/blog/xyz'
  console.log(pathname); // '/blog/[slug]'
  return (
    <div></div>
  );
}

export default BlogSlug;

Comments

35

If you are using Next.js 13

usePathname instead useRouter

'use client';

import { usePathname } from 'next/navigation';

export default function MyComponent() {
  const currentPage = usePathname();
  return <div>{currentPage}</div>;
}

3 Comments

Any idea how to do this with server components?
get url from server components: import { headers } from 'next/headers' stackoverflow.com/a/76312149/3212572
every other solution gave me a "router is not mounted" error except this. it worked perfectly, thank you.
9

To fully use the SSR out-of-the-box provided by Next.js, you can use the context object provided in getInitialProps and which contains the pathname. You can then pass this pathname to be used as a props by your component.

For example:

class Page extends React.Component {
 static getInitialProps({ pathname }){
  return { pathname }
 }
 render() {
  return <div>{this.props.pathname === 'login' ? 'good' : 'not good'}</div>
 }
}

Comments

9

Might be late but just use router.pathname

function MyComp() {
    const router = useRouter();

    return (
        <a className={router.pathname === '/some-path' ? 'currentCSS' : 'defaultCSS'}>
            Some link
        </a>
    );
}

Comments

6

In Client Components, you can use 'usePathname' is a Client Component hook that lets you read the current URL's pathname.

'use client'
import { usePathname } from 'next/navigation'
 
export default function ExampleClientComponent() {
  const pathname = usePathname()
  return <p>Current pathname: {pathname}</p>
}

In your Api's, Get query params and pathname:

export async function GET(req){
 const pathname = req.path
 console.log(pathname )

 const {searchParams} = new URL(req.url);
 const param1 = searchParams.get('param1');
 console.log(param1 )
}

Comments

5

For those who are migrating from Nextjs Page-Router to App-outer V13+

I was searching for the method to get the full URL

Hers is how it should be done as recommended by Nextjs Documentation

    'use client'
 
import { useEffect } from 'react'
import { usePathname, useSearchParams } from 'next/navigation'
 

    export function NavigationEvents() {
  const pathname = usePathname()
  const searchParams = useSearchParams()
 
  useEffect(() => {
    const url = `${pathname}?${searchParams}`
    console.log(url)
    // You can now use the current URL
    // ...
  }, [pathname, searchParams])
 
  return null
}

Notice that you should use this in a client component, not a server component which means you will need to add "use client" on the top of your component page.

In case you want to do this in a server component, you will need to pass the server component to a client component as props.

Scenario: You need the URL in a server component and you can't use the usePathname and useSearchParams as they are only allowed in client components So what do the docs recommend in this case (and any case where you want to do something in a server component that requires only a client component.

You do what you want in the client component and then pass the server component to the client component with a prop this prop value will be the value of the URL for example or any other data you want to pass to the server component)

Simple Explanation: you will add a prop to the server component called URL and in the client component you will pass the URL which you get using the usePathname and useSearchParams as a prop value to the URL prop.

And if you are thinking why not import the Server Component directly:

From the docs:

Unsupported Pattern: Importing Server Components into Client Components The following pattern is not supported. You cannot import a Server Component into a Client Component:

Here's an explanation from the Docs:

Passing Server Components to Client Components as Props

Links:

Docs about the new router updates: https://nextjs.org/docs/app/api-reference/functions/use-router

Docs about usePathname: https://nextjs.org/docs/app/api-reference/functions/use-pathname

Docs about useSearchParams: https://nextjs.org/docs/app/api-reference/functions/use-search-params

1 Comment

The server/client component docs are currently a WIP, so don't hold your breath.
3

One cannot access the Router or the useRouter() options to access the current path in app.js file. This is not client side rendered and hence the only way to access you current path would be to pass it from your getInitialProps() or the getServerSideProps() call to your App component, and then access it there to develop your logic based on the current route.

Comments

3

Next.js v13.4.3

This worked for me

import { usePathname} from 'next/navigation'

const pathname = usePathname();

console.log(pathname)

4 Comments

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
when use npm build this page cannot be route, how can you solve it?
Looks like a thank you answer: stackoverflow.com/a/75926922/6126373
What about accessing the properties of URL object from here? This returns a string.
2

for client side another way is

example url: https://www.example.com/some-page?param1=value1&param2=value2

...
useEffect(() => {
    if (window) {
      const currentURL = new URL(window.location.href);

      // host (domain)
      const host = currentURL.host;
      console.log('Host:', host);

      // path (path dari URL)
      const path = currentURL.pathname;
      console.log('Path:', path);

      // query (parameter dari URL)
      const query = currentURL.search;
      console.log('Query:', query);
    }
  }, [])

Comments

2

With Next 13 above

If you want to get the url from the server side.

Refer to this https://nextjs.org/docs/app/building-your-application/data-fetching/patterns

In my use-case, I have multi-tenant application that renders different styles based on the tenantId.

To retrieve this id, I run a function to fetch the tenantId from the url before passing it to the components.

Example below:

async function getSearchParams() {
  const headersInstance = headers();
  const pathname = headersInstance.get("referer");
  if (!pathname) return new URLSearchParams();
  const urlSearchParams = new URLSearchParams(pathname.split("?")[1]);
  return urlSearchParams;
}
async function getTenantId() {
  const searchParams = await getSearchParams();
  const tenantId = searchParams.get("tenantId");

  if (tenantId) {
    return tenantId;
  }
  return "";
}

1 Comment

This is very helpful, however a warning to folks trying this. If you navigate directly to a page the referer will be null.
1

My app needed to have multiple documents, so I also was looking for a way to get the path name, with nextjs, default document This is a way that I found, which works for me.

import Document, { Html, Head, Main, NextScript } from 'next/document'
import { LandingPage, WithSidePanels } from '../documents'

class MyDocument extends Document {
    static async getInitialProps(ctx) {
        const initialProps = await Document.getInitialProps(ctx)
        return { ...initialProps }
    }
    
    
    render() {
        console.log(this.props.__NEXT_DATA__.page)
        if(this.props.__NEXT_DATA__.page === "/") return <LandingPage />


        return (
           <WithSidePanels />
        )
    }
}

export default MyDocument

So this.props.__NEXT_DATA__.page this is going to give you, the path name, "/", or "/contact" or whatever, from the _document.js :)

Comments

1

For next 13 server-side, I imported headers fn from next/headers and then did headers.get('x-invoke-path')

1 Comment

This header is no longer available in Nextjs v14.
1

This is how i just fetched the url and added active nav item feature in navbar

'use client'
import Link from 'next/link'
import React from 'react'
import Image from 'next/image'
import LogoImg from '../../assets/logo.png'
import classes from './main-header.module.css'
import { usePathname } from 'next/navigation'

const MainHeader = () => {
  const pathname = usePathname();

  return<>
    <header className={classes.header} >
      <nav className={classes.nav}>
        <ul className={classes.navList}>
          <li >
        <Link href="/meals/" className={pathname.startsWith('/meals') ? classes.active : ''}>BrowseMeal</Link>
      </li>
      <li>
        <Link href="/community/" className={pathname.startsWith('/community') ? classes.active : ''}>community</Link>
      </li>
        </ul>
      </nav>
    </header>
   
  </>
  
}

export default MainHeader

Comments

1

If you want to get url pathname in Server Component of app router in nextjs 13 or above, you can create a middleware in src or app or whatever root directory are you using like below:

import {NextRequest, NextResponse} from "next/server";

export function middleware(request: NextRequest) {
    request.headers.set("x-current-path", request.nextUrl.pathname);
    return NextResponse.next({ request });
}
export const config = {
    matcher: [
        // match all routes except static files and APIs
        "/((?!api|_next/static|_next/image|favicon.ico).*)",
    ],
};

Then use the following code in any layout or page file:

export default async function Layout() {
    const headerList = await headers();
    const pathname = headerList.get("x-current-path");
    return (
       <div>....</div>
    )
}

Comments

0
import { usePathname } from "next/navigation";

const pathName = usePathname();

1 Comment

Welcome to Stack Overflow! Thank you for your answer. Please provide more details about your solution. Code snippets, high quality descriptions, or any relevant information would be great. Clear and concise answers are more helpful and easier to understand for everyone. Edit your answer with specifics to raise the quality of your answer. For more information: How To: Write good answers. Happy coding!
-1

For whom who are searching for an example:

import React, { Component } from "react";
import { withRouter } from 'next/router'

class Login extends Component {


    constructor(props) {
        super(props);
    }


    onClickHandler = (event) => {
        this.props.router.push('/newPage')

    }

    render() {
        return (

            <div>
                <p>Hello, {this.props.router.pathname}</p>
                <button onClick={this.onClickHandler}>Click me!</button>
            </div>
        );
    }
}

export default withRouter(Login);

Comments

-5

Probably to avoid use import Router from 'next/router' in nextjs you may use

import {useRouter} from 'next/router';

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.