Skip to content
masterclassBuddyTech Buzz5 fresh blogs · 5:00 AM IST

Next.js 16+ · Function

permanentRedirect

permanentRedirect permanently sends users to another relative or absolute URL. It is available in App Router components and server APIs, normally producing a 308 redirect and stopping rendering immediately.

How it works

Import permanentRedirect from next/navigation and call it when a route should permanently move to another URL. The call throws a NEXT_REDIRECT error and stops rendering the current route segment; the resulting behavior depends on the execution context.

Syntax

permanentRedirect(path, type)

Parameters

NameTypeDescription
pathstringThe relative or absolute URL to redirect to.
type'replace' | 'push'History behavior: 'replace' or 'push'. Defaults to 'push' in Server Actions and 'replace' elsewhere.

Returns

Does not return a value; calling it throws a NEXT_REDIRECT error and terminates rendering.

Key points

  • Use permanentRedirect when a URL has been permanently replaced by another destination.
  • The API is available across the listed App Router server and client execution contexts.
  • During streaming, the redirect is delivered through a client-side meta tag rather than only an HTTP response.
  • With JavaScript enabled, a Server Action uses client-side navigation for this redirect.
  • A no-JavaScript progressive-enhancement form submission receives a 303 response in a Server Action.
  • Outside the Server Action progressive-enhancement case, the function returns a permanent 308 redirect response.
  • Server Actions default to push, adding the destination as a new history entry.
  • Other contexts default to replace, removing the current URL from the browser history stack.

Common mistakes

  • Call permanentRedirect outside a try block when using try/catch in Server Actions or Route Handlers, because the function throws an error.
  • Do not expect execution after the call to continue: it throws NEXT_REDIRECT and terminates rendering of the route segment.

Example: Redirect to a canonical profile URL

import { permanentRedirect } from 'next/navigation'

export default async function Page({
  params,
}: {
  params: Promise<{ username: string }>
}) {
  const { username } = await params
  const profile = await getProfile(username)

  if (profile.canonicalUsername !== username) {
    permanentRedirect(`/profile/${profile.canonicalUsername}`)
  }

  return <h1>{profile.name}</h1>
}

async function getProfile(username: string) {
  return { name: username, canonicalUsername: username }
}

Redirects a profile request to its canonical username when the requested URL is outdated.

When to use it

Move to a new canonical URL

An entity's canonical URL changes after a mutation, such as a username update.

Redirect during streaming

A streamed route must redirect while rendering UI.

Navigate after a Server Action

A Server Action needs navigation after a form submission.

Interview questions

QWhat does permanentRedirect do, and what status codes can it produce?

permanentRedirect permanently sends the user to another URL and accepts a path plus an optional history-navigation type. In ordinary contexts it produces a 308 response; in Server Actions, progressive-enhancement form submissions use 303 and JavaScript can perform client-side navigation.

Follow-up: How does it differ from redirect? permanentRedirect is intended for permanent moves and normally uses 308, whereas redirect is the temporary counterpart and normally uses 307.

QWhat arguments does permanentRedirect accept?

The signature is permanentRedirect(path, type). path is a relative or absolute URL, while type is replace or push; replace is the default outside Server Actions, and push is the default in Server Actions.

Follow-up: Why might type matter? It controls whether the destination replaces the current browser-history entry or adds a new one.

QWhere can permanentRedirect be called, and how does it terminate rendering?

It can be used in Server Components, Client Components, Route Handlers, and Server Functions. In a streaming context, Next.js inserts a meta tag so the client performs the redirect.

Follow-up: What happens if it is called inside a try block? Its thrown NEXT_REDIRECT error can be caught, so the call should be placed outside the try block in Server Actions and Route Handlers.

  • redirect
  • notFound
  • NextResponse.redirect
  • Route Handlers
  • Server Functions

Source: Functions: permanentRedirect - Next.js. Checked 2026-10-15.