next.js

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://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 Quickly Get the Current Route in Next.js

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

src/pages/index.tsx
import Head from 'next/head'; import { useRouter } from 'next/router'; export default function Home() { 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> <br /> URL: <b>{currentUrl}</b> </main> </> ); }
Displaying the current route on a Next.js page

Get current route in Next.js app router component

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

src/app/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> ); }
Displaying the current route in a 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.

This means we can’t access client-side specific APIs.

We can’t do anything interactive with useEffect or other hooks.

If we try, we’ll get an error.

Because it’s a server environment.

We get an error if we try to use hooks in a server component

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 Home({ 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
The current route displayed on the page

Get full 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/index.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()

Get full URL in Next.js component

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

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 /> Route: <b>{pathname}</b> URL: <b>{currentUrl}</b> <br /> </main> </> ); }
Displaying the full URL on a React component

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

Here are some of them:

  • search: the URL’s query parameters. Includes the ?
  • hash: the fragment identifier, the part after the #.
  • 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.
src/pages/amazing-url.tsx
import { NextPageContext } from 'next'; import Head from 'next/head'; import { useUrl } from 'nextjs-current-url'; export default function Home() { const { pathname, href, protocol, hostname, search, hash } = useUrl() ?? {}; 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> </> ); }
Displaying various URL properties on the page

Key takeaways

  • You can use useRouter hook in Next.js to know the current route. It’s like your navigation compass!
  • For getting the current route in a Next.js app router component, usePathname hook from next/navigation is the way to go. But remember, these components are server-side by default.
  • To find out the current route in getServerSideProps, just use req.url from the context. It’s as simple as that!
  • To get the current URL in getServerSideProps, use the getUrl function from nextjs-current-url library. Just pass in the context.req, and you’re good to go!
  • Want to get the full URL? useUrl hook from nextjs-current-url library is your friend. It tells you everything about the URL.

How to Quickly Get the Current URL in Next.js

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.

We use the useState hook to create state that’ll we store in the current URL.

We set the state in the useEffect hook.

window.location

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 a demo 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> </> ); }
Displaying various URL segments on the page

We need useEffect to get the current URL

In Next.js, pages render on both the server and client.

So when the server renders the page, there’s no window object available!

Just like in normal Node.js right? Yes – the server environment.

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.

Hope that’s clear?

Note: 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.

This means we can’t access client-side specific APIs.

We can’t do anything interactive with useEffect or other hooks, like useUrl.

If we try, we’ll get an error.

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/index.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()

getUrl uses info from context.req object to form the complete current URL.

The URL is not serializable, so we pass href, which is a string.

In the client, we create a URL object again with URL().

We get the pathname with the pathname property.

Let’s check out some more properties of URL:

JavaScript
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 URL are displayed on the page.

Note: It’s not possible to get the 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.

Key takeaways

  • To get the current URL in a Next.js component, we can use useUrl hook from the nextjs-current-url package.
    Or useState and window.location.href in a client component.
  • The window.location has properties like protocol, hostname, and pathname that give more information about the URL.
  • In Next.js pages, use useEffect to wait until mounting/hydration is done to access client-side specific APIs.
  • All components in the new app directory are server components by default.
    To access client-side-specific APIs, set the 'use client' statement at the top.
  • To get the current URL in Next.js getServerSideProps, use getUrl() from the nextjs-current-url package, i.e., getUrl({ req: context.req }).
    The URL is not serializable, so we pass href, which is a string.