next.js

How to get URL query string parameters in Next.js

Query parameters are used to pass data from the URL to the web server or browser. They are essential for customizing user experiences, filtering data, and tracking user actions.

Displaying the URL query parameters in a Next.js app.

Let’s learn how to easily get the query string parameters from a URL in a Next.js app.

In this article

Get URL query params in Next.js App Router client component

To get the URL query string parameters in the Next.js app directory, use the useSearchParams() hook from next/navigation.

app/amazing-url/page.tsx
'use client'; import { useSearchParams } from 'next/navigation'; export default function Home() { const searchParams = useSearchParams(); const query = searchParams.get('q'); return ( <> Welcome to Coding Beauty <br /> <br /> Your query: <b>{query}</b> </> ); }

We need ‘use client’ to use useSearchParams()

Notice the 'use client' statement at the top.

It’s there because all components in the new app directory are server components by default, so we can’t use any client-side specific functionality like hooks and animations.

We’ll get an error if we try to do anything interactive with useSearchParams or other hooks like useEffect, because it’s a server environment.

Get URL query params in Next.js Pages Router component

To get the URL query string parameters in pages directory component, use the query property of the useRouter() hook, which comes from the next/router module:

pages/coding-tips.tsx
import Head from 'next/head'; import { useRouter } from 'next/router'; export default function Home() { const router = useRouter(); const greeting = router.query.greeting; return ( <> <Head> <title>Coding Tips | Coding Beauty</title> <meta name="description" content="Generated by create next app" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.icon" /> </Head> <main> <h2>{greeting}</h2> <p>Appreciate the beauty of coding</p> </main> </> ); }

Get URL query params in Next.js middleware

To get the URL query string parameters in Next.js App or Pages Router middleware, use the request.nextUrl.searchParams property:

middleware.ts
import { NextResponse } from 'next/server'; import { NextRequest } from 'next/server'; export function middleware(request: NextRequest) { const continueUrl = request.nextUrl.searchParams.get('continue')!; return NextResponse.redirect(continueUrl); }

Get URL query params in Next.js server component

To get the URL query params in a server component, se the URL as a header in middleware, then parse this URL in the server component to get the query string and parameters:

middleware.ts
import { NextResponse } from 'next/server'; import { NextRequest } from 'next/server'; export function middleware(request: NextRequest) { const reqHeaders = new Headers(request.headers); // toLowerCase() to avoid 404 due to Next.js case-sensitivity const url = request.url.toLowerCase(); reqHeaders.set('x-url', url); return NextResponse.next({ request: { headers: reqHeaders, }, }); }
app/search/page.tsx
import { headers } from 'next/headers'; export default function Page() { const headerList = headers(); const url = headerList.get('x-url')!; const query = new URL(url).searchParams.get('q'); return ( <> <h2>Welcome to Coding Beauty.</h2> <p>Your query: {query}</p> </> ); }

Get URL query params in getServerSideProps()

To get the URL query string params in the Pages Router getServerSideProps() function, use the context.query property:

pages/random-lyrics.tsx
export async function getServerSideProps(context) { const { songId } = context.query; const res = await fetch(`https://api.example.com/lyrics?songId=${songId}`); const lyrics = await res.json(); return { props: { lyrics, }, }; } export default function LyricsPage({ lyrics }) { const { song, content } = lyrics; return ( <div> {song} lyrics<div>{content}</div> </div> ); }

Get URL query params in Next.js Pages Router API

To get the URL query string parameters in an API in the pages directory, use the request.query property:

pages/api/stock-prices.tsx
import type { NextApiRequest, NextApiResponse } from 'next'; export default async function handler( req: NextApiRequest, res: NextApiResponse ) { const { name } = req.query; const stockRes = await fetch(`api.example.com/stock-prices?name=${name}`); const stockData = await stockRes.json(); res.status(200).json({ stockData }); }

Get URL query params in Next.js App Router API

To get the URL query string params in an API in the Next.js 13 app directory, use the request.nextUrl.searchParams property:

app/api/forecast/route.ts
import { NextRequest, NextResponse } from 'next/server'; const data = { 'new-york': { summary: 'sunny' } // ... } export async function GET(req: NextRequest) { const location = req.nextUrl.searchParams.get('location'); const weatherData = data[location]; return NextResponse.json({ weatherData }); }

How to easily add a favicon to a Next.js app

Adding a favicon to a website enhances usability and branding. It helps identify the website in browser tabs and bookmarks, improving user recognition and trust.

Let’s learn how to quickly add a favicon image to a Next.js app

In this article

Add favicon automatically in Next.js 13 App Router

To add a favicon in Next.js 13 App Router, add a favicon.ico file to the app/ directory. Next.js will automatically detect favicon.ico and display it on the page.

Here we’ve added the favicon.ico to our VS Code Next.js project.

favicon.ico is the app directory in Visual Studio Code.

And this is all we need to do – here’s layout.tsx:

src/app/layout.tsx
import { Metadata } from 'next'; import './globals.css'; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body>{children}</body> </html> ); }

And we’ll instantly see the image next to the page title in the browser tab:

The favicon shows up next to the page title in the browser-tab

Apart from favicon and .ico, Next.js also auto-discovers the following file name and extension combinations in the app/ directory

  • icon with .ico, .jpg, .jpeg, .png, or.svg extension.
  • app-icon with .jpg, .jpeg, .png extension.

You can rename PNGs to .ico files and they will still work.

Add favicon automatically in Next.js Pages Router

To add a favicon automatically in the Next.js pages directory, place a favicon.ico file in your public/ directory, and your browser will automatically detect the file for the site icon.

favicon.ico is the public directory in Visual Studio Code.

If your image file isn’t a .ico, you’ll need to either rename it to favicon.ico, or manually specify the filename.

Set Next.js favicon statically in Next.js 13 App Router

To add a favicon to a Next.js 13 app, you can also export a Metadata object with an icons property in your layout.tsx file:

src/app/layout.tsx
import { Metadata } from 'next'; import './globals.css'; export const metadata: Metadata = { icons: { icon: '/icon.png', }, }; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body>{children}</body> </html> ); }

The image file should be in your public directory.

Set Next.js favicon with HTML in Pages Router

To add a site icon in the Next.js pages or app directory, use the HTML <link> tag in your _document.tsx or _document.js file, just like in vanilla HTML:

pages/_document.tsx
import { Html, Head, Main, NextScript } from 'next/document'; export default function Document() { return ( <Html lang="en"> <Head> <link rel="icon" href="/favicon.png" /> </Head> <body> <Main /> <NextScript /> </body> </Html> ); }

The favicon should be in your public directory.

Add favicon with HTML in Next.js 13 App Router

You can also use the HTML <link> tag to add a favicon in a project using the Next.js app directory, in your layout.tsx file:

src/app/layout.tsx
import './globals.css'; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <head> <link rel="icon" href="/app-icon.jpg" /> </head> <body>{children}</body> </html> ); }

The favicon should be in your public directory.

Next.js: How to set page title and meta description

Setting the page title and meta description helps improve search engine visibility, increase click-through rates, and provide concise summaries of webpage content.

In this article, we’re going to learn how we easily set the page title and meta description in a Next.js project.

In this article

Set static page title and meta description in Next.js App Router

To set page title and meta description statically in Next.js 13’s app directory, create a Metadata object in a page.tsx file and export it:

src/app/page.tsx
import React from 'react'; import { Metadata } from 'next'; export const metadata: Metadata = { title: 'Coding Beauty', description: 'wp.codingbeautydev.com: Coding - the art, the science, and the passion.', }; export default function Page() { return ( <main> <h1>Welcome to Coding Beauty</h1> </main> ); }

The tab will have this title, and the page will have a meta tag containing this description:

A Next.js page with a title and meta description.

We can also do this in a layout.tsx to make every page using this layout have this title and meta description by default – if the page doesn’t have its own.

src/app/layout.tsx
import { Metadata } from 'next'; import '@/styles/globals.css'; export const metadata: Metadata = { title: 'Coding Beauty', description: 'The official Coding Beauty home page.', icons: { icon: '/favicon.png', }, }; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( <html lang="en"> <body>{children}</body> </html> ); }

Set title and meta description dynamically in Next.js App Router

You can use the generateMetadata() function to set the page title and meta description using dynamic information we don’t know beforehand, like data from an API.

TypeScript
export function generateMetadata({ params }: Props): Promise<Metadata> { // fetch data with `params` // return a `Metadata` object return { title: post.name, description: post.description, } }

Let’s look at a full example, where we fetch API data for a post in our hypothetical social media app, and we use generateMetadata() to set the page title and meta description for the page based on what we get from the endpoint URL.

src/pages/posts/[id]/page.tsx
import { Metadata } from 'next'; type Props = { params: { id: string }; }; export async function generateMetadata({ params, }: Props): Promise<Metadata> { const id = params.id; const url = `https://api.mysocialapp.com/posts/${id}`; const post = await fetch(url).then((res) => res.json()); return { title: post.title, description: post.description, }; } export default async function Page({ params }: Props) { const { id } = params; const url = `https://api.mysocialapp.com/posts/${id}`; // fetch again! // But don't worry, Next.js caches the `fetch()` calls const post = await fetch(url).then((res) => res.json()); return ( <> <h1>{post.title}</h1> <div>{post.content}</div> </> ); }

We fetch data from the same endpoint twice, one for the title and meta description, and another to display the title and other information to the actual users on the page.

Next.js caches the results of the fetch in generateMetadata() for use in Page to prevent multiple requests and avoid performance hits.

If you export a Metadata object and also have generateMetadata() function, Next.js will use generateMetadata()‘s return value.

Set page title and meta description in Next.js Pages Router (<= 12)

To set the page title and meta description in the Next.js pages directory, create a Head component, and place meta and title tags in it, like you would in vanilla HTML:

pages/index.tsx
import Head from 'next/head'; export default function Home() { return ( <> <Head> <title>Coding Beauty</title> <meta name="description" content="A brand all about coding passion and success" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.png" /> </Head> <main> <h1>Welcome to Coding Beauty</h1> </main> </> ); }

We can also set the page title and meta description in your _app.tsx or _app.jsx file to make each page without a title or description use this as a default.

pages/_app.tsx
import '@/styles/globals.css'; import type { AppProps } from 'next/app'; import Head from 'next/head'; export default function App({ Component, pageProps }: AppProps) { return ( <> <Head> <title>Coding Beauty</title> <meta name="description" content="A page on the Coding Beauty website" /> </Head> <Component {...pageProps} /> </> ); }

Set page title and meta description dynamically in Next.js Pages Router (<= 12)

You can also set the page title and meta description in the pages directory based on some data not known ahead of time.

For instance, to set the meta information based on API data, you’ll fetch the data in getServerSideProps and display it in the title and meta tags that are in the Head tag.

pages/[id].tsx
import { GetServerSideProps } from 'next'; import Head from 'next/head'; export const getServerSideProps: GetServerSideProps = async (context) => { const { params } = context; const { id } = params!; const result = await fetch(`api.mystore.com/books/${id}`); const { title, description, details } = await result.json(); return { props: { title, description, details, }, }; }; export default function Home(props: any) { const { title, description, details } = props; return ( <> <Head> {/* 👇 set page title and meta description dynamically */} <title>{title}</title> <meta name="description" content={description} /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.png" /> </Head> <main> <h1>{title}</h1> <p>{details}</p> </main> </> ); }

How to quickly redirect to another page URL in Next.js

To easily redirect to another page URL in Next.js:

  • Static redirect: use the redirects key in next.config.js.
  • In App Router server component: use redirect() from the next/navigation.
  • In pages Router: use useRouter() from next/navigation.
  • In middleware: use NextResponse.redirect() from next/server.
Redirecting to another page or URL in Next.js.
Redirecting to another page URL in Next.js.

To easily redirect to another page URL in Next.js, use the redirects key in your next.config.js file:

next.config.js
// ... const nextConfig = { // ... async redirects() { return [ { source: '/blog', destination: '/', permanent: true, }, ]; }, }; module.exports = nextConfig;

redirects is an async function that returns an array with items that have source, destination, and permanent properties:

  • source: A pattern matching the path of the incoming request.
  • destination: The path you want to redirect to.
  • permanent: If true, Next sets a 308 status code in the redirection response, which tells clients like search engines to cache the redirect from that point onwards. If false, Next will set a 307 status code (temporary redirect) instead, making sure that redirect doesn’t get cached.

Note: While 301 and 302 are the popular status codes for permanent and temporary redirects, Next.js uses 307 and 308 because many browsers changed the request method to GET for the destination URL, regardless of the method the client set in the original request to the source. So if POST v1/posts returned a 302 with v2/posts, the next request to v2/posts may end up GET v2/posts instead of POST v2/posts. But with 307 and 308, the browsers are guaranteed to preserve the request method.

Redirect statically with path parameter to page URL

You can use a path parameter like :path to match any path in the source URL and pass it on to the destination URL.

Here, /news/:slug/ will match /news/codingbeauty and redirect to /blog/codingbeauty.

next.config.js
// ... const nextConfig = { // ... async redirects() { return [ { source: '/news/:slug', destination: '/blog/:slug', permanent: true, }, ]; }, }; module.exports = nextConfig;

It doesn’t work for nested paths though.

Redirect statically with wildcard path to page URL

To match nested routes, query parameters, and anything else in the source path, use the * character after the path parameter.

next.config.js
// ... const nextConfig = { // ... async redirects() { return [ { source: '/articles/:slug*', destination: '/blog/:slug*', permanent: true, }, ]; }, }; module.exports = nextConfig;

Redirect to another page URL dynamically in Next.js App Router server component

To redirect to another page URL dynamically in a Next.js 13 server component, use the redirect() function from the next/navigation module:

JavaScript
import React from 'react'; import { Metadata } from 'next'; import { redirect } from 'next/navigation'; export const metadata: Metadata = { title: 'Next.js - Coding Beauty', description: 'Tutorials by Coding Beauty', }; export default function Page() { if (process.env.NEXT_PUBLIC_HOME) redirect('/home'); return <main>Welcome to Coding Beauty.</main>; }

The redirect() function redirects the browser to another URL; /home in this case.

Here this happens conditionally, but if the redirect is guaranteed to happen, it will surely prevent any JSX in the page from rendering, and editors like VS Code are smart enough to detect this:

Visual Studio Code can detect when the JSX in a page is unreachable due to a redirect.

Redirect to another page URL dynamically in App Router client component

To redirect to another page URL dynamically in a Next.js client component in the Next.js 13 app directory, use the push() method of the object returned by the useRouter hook from the next/navigation module:

Here we’re redirecting from from the /blog path to an external URL:

src/app/blog/page.tsx
'use client'; import React, { useEffect } from 'react'; import { useRouter } from 'next/navigation'; export default function Page() { const router = useRouter(); useEffect(() => { router.push('https://wp.codingbeautydev.com'); }, []); return <main>Welcome to Coding Beauty.</main>; }

The useRouter hook returns a Router object that we use to programmatically change the route, resulting in a client-side redirect.

Redirect to another page URL dynamically in Pages Router component

It’s like in the App router, but useRouter comes from next/router instead of next/navigation.

To redirect to another page URL dynamically in a Next.js client component in the Pages router, use the push() method of the object returned by the useRouter hook from the next/router module.

src/pages/amazing-url.tsx
import Head from 'next/head'; import { useEffect } from 'react'; import { useRouter } from 'next/router'; export default function Home() { const router = useRouter(); useEffect(() => { router.push('/fantastic-url'); }, []); return ( <> <Head> <title>Amazing URL | Coding Beauty</title> <meta name="description" content="Generated by create next app" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.png" /> </Head> <main> <p>Coding Beauty</p> <h2>Amazing URL</h2> </main> </> ); }

The useRouter hook returns a Router object that we use to programmatically change the route to perform a redirect on the client side.

Next.js >= 12: Redirect to another page URL in middleware

To redirect to another page URL using middleware in Next.js 12.1 and above, use the NextResponse.redirect method from the next/server module in a middleware.ts file.

src/middleware.ts
import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; export function middleware(request: NextRequest) { const url = request.nextUrl.clone(); if (url.pathname === '/old-blog') { url.pathname = '/new-blog'; return NextResponse.redirect(url); } }

Here we use request.nextUrl to get the current URL in the Next.js middleware.

You’ll place middleware.ts file in the same level as your pages directory – which could be the root directory, or src, if enabled.

middleware.ts is at the same level as the pages directory.
middleware.ts is at the same level as the pages directory.

The reason why this only works in Next.js 12.1 above is because starting from Next.js 12.1, relative URLs are not allowed in redirects with NextResponse.redirect() or NextResponse.rewrite().

Next.js 12: Redirect to another page URL in middleware

To redirect to another page URL dynamically using middleware in Next.js 12, use the NextResponse.redirect() method from the next/server module in a _middleware.js file inside the pages folder or a subfolder where you want the middleware to work:

pages/_middleware.js
import { NextResponse, NextRequest } from 'next/server'; export async function middleware(request, event) { const { pathname } = request.nextUrl; if (pathname == '/') { return NextResponse.redirect('/hello-nextjs'); } return NextResponse.next(); }

Key takeaways

  • In Next.js, there are several ways to quickly redirect to another page URL.
  • For static redirects, you can use the redirects key in the next.config.js file. It allows you to define source and destination paths with options for temporary or permanent redirects.
  • Path parameters (e.g., /blog/:slug) and wildcard paths (e.g., /blog/:slug*) can be used to match and redirect nested routes or query parameters.
  • In a Next.js App Router server component, you can use the redirect() function from the next/navigation module to dynamically redirect to another URL.
  • In the Next.js client component, you can use the push() method from the useRouter hook in the next/navigation (Next.js 13) or next/router (Next.js 12 and below) module to programmatically change the route and perform a client-side redirect.
  • For middleware in Next.js 12.1 and above, you can use the NextResponse.redirect() method from the next/server module in a middleware.ts file.
  • In Next.js 12 middleware, you can use the NextResponse.redirect() method in a _middleware.js file inside the pages folder or a subfolder.

How to easily get the current route in Next.js

Getting the current route in a web application is important for managing user sessions, handling authentication, and dynamically displaying UI elements.

Let’s how see how easy it is to get the current route or pathname in our Next.js app.

In this article

Get current route in Next.js Pages Router component

We can get the current route in a Next.js component with the useRouter hook:

src/pages/blog.tsx
import Head from 'next/head'; import { useRouter } from 'next/router'; export default function Page() { const { pathname } = useRouter(); return ( <> <Head> <title>Next.js - Coding Beauty</title> <meta name="description" content="Next.js Tutorials by Coding Beauty" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.ico" /> </Head> <main> Welcome to Coding Beauty <br /> <br /> Pathname: <b>{pathname}</b> </main> </> ); }

Get current route in Next.js App Router component

To get the current route in a Next.js app router component, use the usePathname hook from next/navigation:

src/app/amazing-url/page.tsx
'use client'; import React from 'react'; import { Metadata } from 'next'; import { usePathname } from 'next/navigation'; export const metadata: Metadata = { title: 'Next.js - Coding Beauty', description: 'Next.js Tutorials by Coding Beauty', }; export default function Page() { const pathname = usePathname(); return ( <main> Welcome to Coding Beauty 😄 <br /> <br /> Route: <b>{pathname}</b> </main> ); }

We need 'use client' in Next.js 13 App Router

Notice the 'use client' statement at the top.

It’s there because all components in the new app directory are server components by default, which means we can’t access client-side specific APIs.

We’ll get an error if we try to do anything interactive with useEffect or other hooks, as it’s a server environment.

Get current route in Next.js getServerSideProps

To get the current route in getServerSideProps, use req.url from the context argument.

src/pages/amazing-url.tsx
import { NextPageContext } from 'next'; import Head from 'next/head'; export function getServerSideProps(context: NextPageContext) { const route = context.req!.url; console.log(`The route is: ${route}`); return { props: { route, }, }; } export default function Page({ route }: { route: string }) { return ( <> <Head> <title>Next.js - Coding Beauty</title> <meta name="description" content="Generated by create next app" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.png" /> </Head> <main> Welcome to Coding Beauty 😃 <br /> Route: <b>{route}</b> </main> </> ); }
The current route printed in the console

How to easily get the current URL in Next.js

We use the current URL in a web app to track user activity, maintain history, or modify displayed elements based on route. So, let’s see how to quickly get the current URL in a Next.js app.

In this article

Get current URL in Next.js Pages Router component

To get the current URL in a Next.js component, use the useUrl hook from the nextjs-current-url package:

With pages directory:

src/pages/index.tsx
import { useUrl } from 'nextjs-current-url'; import Head from 'next/head'; export default function Home() { const { href: currentUrl, pathname } = useUrl() ?? {}; return ( <> <Head> <title>Next.js - Coding Beauty</title> <meta name="description" content="Next.js Tutorials by Coding Beauty" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.png" /> </Head> <main> Welcome to Coding Beauty 😄 <br /> <br /> URL: <b>{currentUrl}</b> <br /> pathname: <b>{pathname}</b> </main> </> ); }
The current URL is displayed on the Next.js page.

useUrl() returns a URL object that gives us more info on the current URL.

Get current URL with useState and window.location.href

We can also get the current URL in a client component using useState and window.location.href.

src/pages/index.tsx
import Head from 'next/head'; import { useRouter } from 'next/router'; import { useEffect } from 'react'; export default function Home() { const [currentUrl, setCurrentUrl] = useState<string | null>(null); const { pathname } = useRouter(); useEffect(() => { setCurrentUrl(window.location.href); }, []); return ( <> <Head> <title>Next.js - Coding Beauty</title> <meta name="description" content="Next.js Tutorials by Coding Beauty" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.ico" /> </Head> <main> Welcome to Coding Beauty 😄 <br /> <br /> URL: <b>{currentUrl}</b> <br /> pathname: <b>{pathname}</b> </main> </> ); }

The window.location.href property returns a string containing the entire page URL, and we use the useState and useEffect hooks to create and set state for storing the current URL.

window.location property

window.location has other properties that tell you more about the URL. Like:

  • pathname: the path of the URL after the domain name and any optional port number. Query and fragment identifier not included.
  • protocol: URL‘s protocol scheme, like https: or mailto:. Doesn’t include the //.
  • hostname: the URL‘s domain name without the port number.

Here’s an example where we use some of these properties:

src/pages/index.tsx
import { getUrl } from '@/lib/utils/get-url'; import { NextPageContext } from 'next'; import Head from 'next/head'; import { useEffect, useState } from 'react'; export function getServerSideProps(context: NextPageContext) { return { props: { currentUrl: getUrl({ req: context.req! })?.href, }, }; } export default function Home() { const [myLocation, setMyLocation] = useState<Location | null>(null); useEffect(() => { setMyLocation(window.location); }); return ( <> <Head> <title>Next.js - Coding Beauty</title> <meta name="description" content="Next.js Tutorials by Coding Beauty" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.png" /> </Head> <main> You are currently accessing <b>{myLocation?.href}</b> 😃 <br /> Pathname: <b>{myLocation?.pathname}</b> <br /> Protocol: <b>{myLocation?.protocol}</b> <br /> Hostname: <b>{myLocation?.hostname}</b> </main> </> ); }
Display various segments of the current URL in a Next.js page.

We need useEffect to get the current URL

Pages render on both the server and client in Next.js, so when the server renders the page, there’s no window object available.

So you’ll get a “window is not defined” error if you try to use window before hydration:

"window is not defined" error in Next.js page

That’s why we use useEffect – to wait till mounting/hydration is done.

What’s hydration?

Hydration is when a server-generated web page gets extra client-side features added by the user’s web browser. Features like event listeners, client-side routing, etc.

Get current URL in Next.js App Router component

To get the current URL in a Next.js app router component, we can also use the useUrl hook from the nextjs-current-url library.

src/app/page.tsx
'use client'; import React from 'react'; import { useUrl } from 'nextjs-current-url'; import { Metadata } from 'next'; export const metadata: Metadata = { title: 'Next.js - Coding Beauty', description: 'Next.js Tutorials by Coding Beauty', }; export default function Page() { const { pathname, href } = useUrl() ?? {}; return ( <main> Welcome to Coding Beauty <br /> <br /> URL: <b>{href}</b> <br /> route: <b>{pathname}</b> </main> ); }
The current URL is displayed on the Next.js app router component

Next.js App Router: We need 'use client'

Notice the 'use client' statement at the top.

It’s there because all components in the new app directory are server components by default, so we can’t use any client-side specific APIS.

We’ll get an error if we try to do anything interactive with useEffect or other hooks like useUrl, because it’s a server environment.

Get current URL in Next.js getServerSideProps

To get the current URL in getServerSideProps of a Next.js page, use the getUrl function from the nextjs-current-url library.

src/pages/amazing-url.tsx
import { NextPageContext } from 'next'; import Head from 'next/head'; import { getUrl } from 'nextjs-current-url/server'; export function getServerSideProps(context: NextPageContext) { const url = getUrl({ req: context.req }); return { props: { url: url.href, }, }; } export default function Home({ url }: { url: string }) { const urlObj = new URL(url); const { pathname } = urlObj; return ( <> <Head> <title>Next.js - Coding Beauty</title> <meta name="description" content="Generated by create next app" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.png" /> </Head> <main> Welcome to Coding Beauty 😃 <br /> <br /> URL: <b>{url}</b> <br /> Route: <b>{pathname}</b> </main> </> ); }
The current URL is displayed on the Next.js page from getServerSideProps()

Let’s check out some more properties of URL:

src/pages/amazing-url.tsx
import { NextPageContext } from 'next'; import Head from 'next/head'; import { getUrl } from 'nextjs-current-url/server'; export function getServerSideProps(context: NextPageContext) { const url = getUrl({ req: context.req }); return { props: { url: url.href, }, }; } export default function Home({ url }: { url: string }) { const urlObj = new URL(url); const { pathname, href, protocol, hostname, search, hash } = urlObj; return ( <> <Head> <title>Next.js - Coding Beauty</title> <meta name="description" content="Generated by create next app" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="icon" href="/favicon.png" /> </Head> <main> Welcome to Coding Beauty 😃 <br /> <br /> URL: <b>{href}</b> <br /> Pathname: <b>{pathname}</b> <br /> Protocol: <b>{protocol}</b> <br /> Hostname: <b>{hostname}</b> <br /> Search: <b>{search}</b> <br /> Hash: <b>{hash}</b> </main> </> ); }

Here’s what these properties do:

  • href: the complete URL, including the protocol, hostname, port number, path, query parameters, and fragment identifier.
  • protocol: URL’s protocol scheme, like https: or mailto:. Doesn’t include the //.
  • hostname: the URL’s domain name without the port number.
  • pathname: the URL’s path and filename without the query and fragment identifier.
  • search: the URL’s query parameters. Includes the ?
  • hash: the fragment identifier, the part after the #.
Various properties of the current URL are displayed on the Next.js page.

Note: As you can see it’s not possible to get the hash/fragment in getServerSideProps because the browser never sends the part after the # to the server. That’s why there’s no hash here. We’d have to get the current URL in the client-side to access the fragment identifier.