Modals let you show extra info without leaving the page. URL query parameters help open modals while keeping the main page visible.
Modal pattern with intercepting routes in NextJS
import { useRouter, usePathname, useSearchParams } from 'next/navigation'; import { useState, useEffect } from 'react'; export default function Page() { const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); const [modalOpen, setModalOpen] = useState(false); useEffect(() => { const modalParam = searchParams.get('modal'); setModalOpen(modalParam === 'true'); }, [searchParams]); function openModal() { router.push(`${pathname}?modal=true`, { scroll: false }); } function closeModal() { router.push(pathname, { scroll: false }); } return ( <> <main> <h1>Main Page Content</h1> <button onClick={openModal}>Open Modal</button> </main> {modalOpen && ( <div role="dialog" aria-modal="true" aria-labelledby="modal-title" tabIndex={-1} className="modal"> <h2 id="modal-title">Modal Content</h2> <p>This is a modal opened via URL query parameter.</p> <button onClick={closeModal}>Close Modal</button> </div> )} </> ); }
The modal state is controlled by a URL query parameter (e.g., ?modal=true).
Using router.push with scroll: false keeps the page position stable.
router.push(`${pathname}?modal=true`, { scroll: false });
router.push(pathname, { scroll: false });const modalParam = searchParams.get('modal'); setModalOpen(modalParam === 'true');
This Next.js component shows a main page with a button. Clicking the button adds ?modal=true to the URL and opens a modal. Closing the modal removes the query parameter. The modal uses ARIA roles for accessibility and a semi-transparent background overlay.
import { useRouter, usePathname, useSearchParams } from 'next/navigation'; import { useState, useEffect } from 'react'; export default function ModalPage() { const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); const [modalOpen, setModalOpen] = useState(false); useEffect(() => { const modalParam = searchParams.get('modal'); setModalOpen(modalParam === 'true'); }, [searchParams]); function openModal() { router.push(`${pathname}?modal=true`, { scroll: false }); } function closeModal() { router.push(pathname, { scroll: false }); } return ( <> <main> <h1>Welcome to the Main Page</h1> <button onClick={openModal} aria-haspopup="dialog" aria-expanded={modalOpen}>Open Modal</button> </main> {modalOpen && ( <div role="dialog" aria-modal="true" aria-labelledby="modal-title" tabIndex={-1} className="modal" style={{ position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', backgroundColor: 'white', padding: '1rem', boxShadow: '0 4px 6px rgba(0,0,0,0.1)', zIndex: 1000 }}> <h2 id="modal-title">Modal Window</h2> <p>This modal opened using URL query parameters keeps the main page visible.</p> <button onClick={closeModal}>Close Modal</button> </div> )} {modalOpen && <div aria-hidden="true" style={{ position: 'fixed', top: 0, left: 0, width: '100vw', height: '100vh', backgroundColor: 'rgba(0,0,0,0.3)', zIndex: 999 }} />} </> ); }
Always use ARIA roles like role="dialog" and aria-modal="true" for accessibility.
Keep the background page visible but inert by using an overlay with aria-hidden="true".
Using the Next.js router with query parameters lets you change the URL without full page reload, improving user experience.
Modals with URL query parameters show popups without leaving the page.
Use URL query parameters to control modal open/close state.
Ensure accessibility with proper ARIA roles and keyboard focus management.
Practice
Solution
Step 1: Understand modal with intercepting routes
This pattern lets you open a modal that overlays the current page content without navigating away.Step 2: Identify the benefit
Because the modal is shown on top, the user stays on the same page, improving user experience.Final Answer:
It allows showing a popup without leaving the current page. -> Option BQuick Check:
Modal pattern = popup without page change [OK]
- Thinking the page reloads when modal opens
- Assuming URL never changes
- Believing keyboard navigation is disabled
Solution
Step 1: Identify modal control method
Next.js modals with intercepting routes often use URL query parameters to track if modal is open or closed.Step 2: Eliminate incorrect options
React class components are outdated; server-side rendering doesn't control modal visibility dynamically; CSS hover is unrelated to routing.Final Answer:
Using URL query parameters to toggle modal state -> Option AQuick Check:
Modal visibility = URL query param [OK]
- Confusing client state with URL state
- Using class components instead of hooks
- Relying on CSS hover for modal control
?modal=open:
const router = useRouter();
const isModalOpen = router.query.modal === 'open';
return (
<>
{isModalOpen && <ModalComponent />}
<MainPageContent />
</>
);
What happens when the URL changes from /page to /page?modal=open?Solution
Step 1: Understand the code logic
The code checks if the query parameter 'modal' equals 'open'. If yes, it renders the modal component alongside the main content.Step 2: Analyze URL change effect
Changing URL to include '?modal=open' setsisModalOpentrue, so modal appears over the main page without replacing it.Final Answer:
The modal component appears over the main page content. -> Option DQuick Check:
Query param 'modal=open' = modal visible [OK]
- Thinking modal replaces main content
- Ignoring query parameters in rendering
- Assuming page reloads on query change
const router = useRouter();
const isModalOpen = router.query.modal === 'open';
function closeModal() {
router.push('/page');
}
return (
<>
{isModalOpen && <Modal onClose={closeModal} />}
<PageContent />
</>
);
What is a likely bug in this code regarding accessibility?Solution
Step 1: Review modal accessibility needs
When a modal opens, keyboard focus should move inside it for screen reader and keyboard users.Step 2: Check code for focus management
The code changes URL and renders modal but does not handle moving keyboard focus to modal.Final Answer:
Keyboard focus is not moved to the modal when it opens. -> Option CQuick Check:
Modal accessibility = move keyboard focus [OK]
- Ignoring keyboard focus management
- Assuming URL push closes modal automatically
- Confusing rendering with accessibility
/gallery?modal=photo123 and closes by removing the query param, without losing the gallery scroll position. Which approach best achieves this?Solution
Step 1: Understand shallow routing in Next.js
Shallow routing updates the URL without running data fetching methods or reloading the page, preserving scroll and state.Step 2: Apply shallow routing to modal open/close
Usingrouter.pushwithshallow: truechanges query params to open/close modal without losing scroll position.Final Answer:
Use router.push with shallow: true to update URL without full reload and keep scroll. -> Option AQuick Check:
Shallow routing = URL change without reload [OK]
- Using router.replace without shallow reloads page
- Using window.location.href causes full reload
- Ignoring URL for modal state control
Ready to prove it?
Pass the test and this pattern moves unknown
