138

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

Karthi
  • 3,019
  • 9
  • 36
  • 54
  • Possible duplicate of [Getting the current url on the client side in next.js](https://stackoverflow.com/questions/54846133/getting-the-current-url-on-the-client-side-in-next-js) – imjared Sep 20 '19 at 07:24

16 Answers16

150

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

imjared
  • 19,492
  • 4
  • 49
  • 72
63

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()
Ruslan Korkin
  • 3,973
  • 1
  • 27
  • 23
52

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;
Suraj Sharma
  • 777
  • 6
  • 10
13

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>;
}
GMKHussain
  • 3,342
  • 1
  • 21
  • 19
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>
 }
}

Gaël S
  • 1,598
  • 6
  • 15
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>
    );
}
deadcoder0904
  • 7,232
  • 12
  • 66
  • 163
acmoune
  • 2,981
  • 3
  • 24
  • 41
3

Next.js v13.4.3

This worked for me

import { usePathname} from 'next/navigation'

const pathname = usePathname();

console.log(pathname)
Omanaite
  • 31
  • 2
  • 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](/help/how-to-answer). – Community Jul 05 '23 at 00:33
  • when use npm build this page cannot be route, how can you solve it? – Man Man Yu Jul 16 '23 at 09:54
2

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.

Orlyyn
  • 2,296
  • 2
  • 20
  • 32
maiprasadr
  • 21
  • 2
2

In Nextjs 13.4+ it is preferred to use usePathName from next/navigation

import { usePathname } from "next/navigation";

export function Component() {
    const pathname = usePathname();
    console.log(pathname); // Your path name ex: /product
}

Based on pathName if you want to show the active links refer the below link:

Target Active Link when the route is active in Next.js

krishnaacharyaa
  • 14,953
  • 4
  • 49
  • 88
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 :)

1

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

  • The server/client component docs are currently a [WIP](https://github.com/vercel/next.js/pull/51579), so don't hold your breath. – morganney Aug 19 '23 at 16:58
0

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

Devin Rhode
  • 23,026
  • 8
  • 58
  • 72
0

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);
    }
  }, [])
malik kurosaki
  • 1,747
  • 15
  • 9
0
usePathname() //returns string of path name.
Hamid Mohamadi
  • 141
  • 2
  • 4
-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);
M Fuat
  • 1,330
  • 3
  • 12
  • 24
-5

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

import {useRouter} from 'next/router';
Wilker
  • 551
  • 2
  • 6
  • 21