Dialog with Next.js App Router

Using Next.js Parallel Routes to create an accessible modal Dialog that is rendered on the server and controlled by the URL, with built-in focus management.

Open in new tab
import Link from "next/link.js";
export default function Page() {
return (
<Link href="/previews/dialog-next-router/login" className="button">


Controlling the Dialog state

To control the open state, you can pass the open and onClose props to the Dialog component. These props allow you to synchronize the dialog state with other state sources, such as the browser history.

In this example, since the dialog is only rendered when the route matches, we can pass open={true} to the Dialog component so that the dialog is always open. Then, we can use onClose to navigate back when the dialog is closed:

const router = useRouter();
<Dialog open onClose={() => router.push("/previews/dialog-next-router")}>

Restoring focus on hide

When the dialog is closed, the focus is automatically returned to the element that was previously focused before opening the dialog. Typically, this is the element that triggered the dialog. However, in cases where a user navigates to the modal URL directly, there is no element to focus on hide.

To handle this scenario, the autoFocusOnHide prop can be used to specify a fallback element to focus on hide:

const pathname = usePathname();
autoFocusOnHide={(element) => {
if (!element) {
return true;

Stay tuned

Join 1,000+ subscribers and receive monthly tips & updates on new Ariakit content.

No spam. Unsubscribe anytime. Read latest issue