Question presented to candidate:
"We have a dashboard with Overview, Activity and Settings tabs. Product wants the selected tab in the URL, as ?tab=settings, so a link opens the right tab, a reload keeps it, and the browser Back button goes to the previous tab. Activity loads data, so its panel should not be created until someone opens it, but once opened it should keep its state. We do not use a router on this page; use the platform APIs."
Requirements:
- Tabs come from a config array (
id,label, panel component). The accessible tabs pattern (roles,aria-selected, roving tabindex) is assumed; arrow keys, Home and End move focus, and Enter or Space selects (manual activation). - The URL is the source of truth: the selected tab is read from
?tab=on load and validated; an unknown value falls back to the default and is corrected withhistory.replaceState(no extra history entry). - Selecting a tab calls
history.pushState, keeping every other query parameter and the hash; selecting the tab that is already selected does nothing. - Back and Forward (
popstate) switch tabs without pushing new entries. - Panels are mounted lazily on first visit and stay mounted afterwards, so a loaded list or typed text survives switching away and back.
What a strong answer should cover:
- Why the URL, not component state, is the source of truth, and the read, validate, write, listen loop with
URLSearchParams,pushState,replaceStateandpopstate. - When to push versus replace, and why arrow-key focus movement must not create history entries (hence manual activation).
- Lazy mounting with a "mounted so far" set plus hiding, versus eager rendering or unmounting, and the effect on data fetching and panel state.
- Cleaning up the
popstatelistener, and fetch effects that survive React StrictMode's double invocation. - How the same model maps to a router (
useSearchParams, Vue Router query, AngularqueryParamMap) when one exists.
Clarifying questions expected:
- "Should every tab change create a history entry, or should switching tabs replace the current entry?"
- "What should an invalid or missing
?tab=do: fall back silently, or rewrite the URL?" - "Should a panel that was visited and left be kept alive, or re-created on the next visit?"
Code / implementation expected: Yes. A working tabs component with URL sync and lazy panels, plus a way to demonstrate Back, Forward and a reload.