Reputation: 3489
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
Upvotes: 160
Views: 413100
Reputation: 1848
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>
)
}
Upvotes: 1
Reputation: 21
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
Upvotes: 1
Reputation: 77
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 )
}
Upvotes: 6
Reputation: 1
import { usePathname } from "next/navigation";
const pathName = usePathname();
Upvotes: 0
Reputation: 216
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 "";
}
Upvotes: 2
Reputation: 2042
for client side another way is
example url: https://www.example.com/some-page?param1=value1¶m2=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);
}
}, [])
Upvotes: 2
Reputation: 25367
For next 13 server-side, I imported headers
fn from next/headers
and then did headers.get('x-invoke-path')
Upvotes: 1
Reputation: 109
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
Upvotes: 5
Reputation: 39
Next.js v13.4.3
This worked for me
import { usePathname} from 'next/navigation'
const pathname = usePathname();
console.log(pathname)
Upvotes: 3
Reputation: 4711
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>;
}
Upvotes: 35
Reputation: 11
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
:)
Upvotes: 1
Reputation: 3423
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>
);
}
Upvotes: 9
Reputation: 857
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.
One is asPath
property, and
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]
.
// .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;
Upvotes: 58
Reputation: 31
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.
Upvotes: 3
Reputation: 20584
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
Upvotes: 160
Reputation: 5131
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()
Upvotes: 70
Reputation: 651
Probably to avoid use import Router from 'next/router' in nextjs you may use
import {useRouter} from 'next/router';
Upvotes: -5
Reputation: 1440
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);
Upvotes: -1
Reputation: 1569
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>
}
}
Upvotes: 9