Episode 2 — React Frontend Architecture NextJS / 2.11 — Routing and Application Structure

2.11.c — Dynamic routing & URL parameters

<< 2.11 Overview


Learning outcomes

  1. Define dynamic segments with :param syntax.
  2. Read params with useParams safely.
  3. Use search params when the UI state should be shareable as query string.

Dynamic segment

import { Route, Routes, useParams } from "react-router-dom";

export function AppRoutes() {
  return (
    <Routes>
      <Route path="/users/:userId" element={<UserProfile />} />
    </Routes>
  );
}

function UserProfile() {
  const { userId } = useParams();
  return <h1>User {userId}</h1>;
}

Search params

import { useSearchParams } from "react-router-dom";

function Filters() {
  const [params, setParams] = useSearchParams();
  const q = params.get("q") ?? "";
  return <input value={q} onChange={(e) => setParams({ q: e.target.value })} />;
}

Validation mindset

Params are strings from the URL—treat them as untrusted input and validate before fetching private data.



Appendix — Scenario bank (basic → advanced)

Drill format: broken URL / UX → root cause → fix → interview phrase.

RR2-001 — Dynamic routes #1

  • Level: Beginner
  • Symptom: 404 on refresh at depth 13 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-002 — Dynamic routes #2

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 26 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-003 — Dynamic routes #3

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 39 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-004 — Dynamic routes #4

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 52 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-005 — Dynamic routes #5

  • Level: Advanced
  • Symptom: 404 on refresh at depth 65 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-006 — Dynamic routes #6

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 78 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-007 — Dynamic routes #7

  • Level: Beginner
  • Symptom: 404 on refresh at depth 91 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-008 — Dynamic routes #8

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 104 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-009 — Dynamic routes #9

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 117 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-010 — Dynamic routes #10

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 130 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-011 — Dynamic routes #11

  • Level: Advanced
  • Symptom: 404 on refresh at depth 143 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-012 — Dynamic routes #12

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 156 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-013 — Dynamic routes #13

  • Level: Beginner
  • Symptom: 404 on refresh at depth 169 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-014 — Dynamic routes #14

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 182 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-015 — Dynamic routes #15

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 195 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-016 — Dynamic routes #16

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 8 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-017 — Dynamic routes #17

  • Level: Advanced
  • Symptom: 404 on refresh at depth 21 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-018 — Dynamic routes #18

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 34 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-019 — Dynamic routes #19

  • Level: Beginner
  • Symptom: 404 on refresh at depth 47 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-020 — Dynamic routes #20

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 60 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-021 — Dynamic routes #21

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 73 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-022 — Dynamic routes #22

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 86 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-023 — Dynamic routes #23

  • Level: Advanced
  • Symptom: 404 on refresh at depth 99 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-024 — Dynamic routes #24

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 112 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-025 — Dynamic routes #25

  • Level: Beginner
  • Symptom: 404 on refresh at depth 125 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-026 — Dynamic routes #26

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 138 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-027 — Dynamic routes #27

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 151 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-028 — Dynamic routes #28

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 164 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-029 — Dynamic routes #29

  • Level: Advanced
  • Symptom: 404 on refresh at depth 177 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-030 — Dynamic routes #30

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 190 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-031 — Dynamic routes #31

  • Level: Beginner
  • Symptom: 404 on refresh at depth 3 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-032 — Dynamic routes #32

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 16 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-033 — Dynamic routes #33

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 29 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-034 — Dynamic routes #34

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 42 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-035 — Dynamic routes #35

  • Level: Advanced
  • Symptom: 404 on refresh at depth 55 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-036 — Dynamic routes #36

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 68 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-037 — Dynamic routes #37

  • Level: Beginner
  • Symptom: 404 on refresh at depth 81 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-038 — Dynamic routes #38

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 94 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-039 — Dynamic routes #39

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 107 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-040 — Dynamic routes #40

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 120 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-041 — Dynamic routes #41

  • Level: Advanced
  • Symptom: 404 on refresh at depth 133 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-042 — Dynamic routes #42

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 146 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-043 — Dynamic routes #43

  • Level: Beginner
  • Symptom: 404 on refresh at depth 159 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-044 — Dynamic routes #44

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 172 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-045 — Dynamic routes #45

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 185 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-046 — Dynamic routes #46

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 198 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-047 — Dynamic routes #47

  • Level: Advanced
  • Symptom: 404 on refresh at depth 11 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-048 — Dynamic routes #48

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 24 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-049 — Dynamic routes #49

  • Level: Beginner
  • Symptom: 404 on refresh at depth 37 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-050 — Dynamic routes #50

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 50 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-051 — Dynamic routes #51

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 63 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-052 — Dynamic routes #52

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 76 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-053 — Dynamic routes #53

  • Level: Advanced
  • Symptom: 404 on refresh at depth 89 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-054 — Dynamic routes #54

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 102 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-055 — Dynamic routes #55

  • Level: Beginner
  • Symptom: 404 on refresh at depth 115 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-056 — Dynamic routes #56

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 128 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-057 — Dynamic routes #57

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 141 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-058 — Dynamic routes #58

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 154 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-059 — Dynamic routes #59

  • Level: Advanced
  • Symptom: 404 on refresh at depth 167 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-060 — Dynamic routes #60

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 180 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-061 — Dynamic routes #61

  • Level: Beginner
  • Symptom: 404 on refresh at depth 193 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-062 — Dynamic routes #62

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 6 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-063 — Dynamic routes #63

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 19 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-064 — Dynamic routes #64

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 32 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-065 — Dynamic routes #65

  • Level: Advanced
  • Symptom: 404 on refresh at depth 45 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-066 — Dynamic routes #66

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 58 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-067 — Dynamic routes #67

  • Level: Beginner
  • Symptom: 404 on refresh at depth 71 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-068 — Dynamic routes #68

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 84 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-069 — Dynamic routes #69

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 97 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-070 — Dynamic routes #70

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 110 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-071 — Dynamic routes #71

  • Level: Advanced
  • Symptom: 404 on refresh at depth 123 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-072 — Dynamic routes #72

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 136 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-073 — Dynamic routes #73

  • Level: Beginner
  • Symptom: 404 on refresh at depth 149 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-074 — Dynamic routes #74

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 162 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-075 — Dynamic routes #75

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 175 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-076 — Dynamic routes #76

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 188 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-077 — Dynamic routes #77

  • Level: Advanced
  • Symptom: 404 on refresh at depth 1 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-078 — Dynamic routes #78

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 14 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-079 — Dynamic routes #79

  • Level: Beginner
  • Symptom: 404 on refresh at depth 27 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-080 — Dynamic routes #80

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 40 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-081 — Dynamic routes #81

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 53 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-082 — Dynamic routes #82

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 66 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-083 — Dynamic routes #83

  • Level: Advanced
  • Symptom: 404 on refresh at depth 79 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-084 — Dynamic routes #84

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 92 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-085 — Dynamic routes #85

  • Level: Beginner
  • Symptom: 404 on refresh at depth 105 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-086 — Dynamic routes #86

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 118 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-087 — Dynamic routes #87

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 131 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-088 — Dynamic routes #88

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 144 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-089 — Dynamic routes #89

  • Level: Advanced
  • Symptom: 404 on refresh at depth 157 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-090 — Dynamic routes #90

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 170 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-091 — Dynamic routes #91

  • Level: Beginner
  • Symptom: 404 on refresh at depth 183 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-092 — Dynamic routes #92

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 196 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-093 — Dynamic routes #93

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 9 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-094 — Dynamic routes #94

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 22 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-095 — Dynamic routes #95

  • Level: Advanced
  • Symptom: 404 on refresh at depth 35 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-096 — Dynamic routes #96

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 48 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-097 — Dynamic routes #97

  • Level: Beginner
  • Symptom: 404 on refresh at depth 61 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-098 — Dynamic routes #98

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 74 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-099 — Dynamic routes #99

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 87 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-100 — Dynamic routes #100

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 100 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-101 — Dynamic routes #101

  • Level: Advanced
  • Symptom: 404 on refresh at depth 113 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-102 — Dynamic routes #102

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 126 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-103 — Dynamic routes #103

  • Level: Beginner
  • Symptom: 404 on refresh at depth 139 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-104 — Dynamic routes #104

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 152 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-105 — Dynamic routes #105

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 165 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-106 — Dynamic routes #106

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 178 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-107 — Dynamic routes #107

  • Level: Advanced
  • Symptom: 404 on refresh at depth 191 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-108 — Dynamic routes #108

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 4 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-109 — Dynamic routes #109

  • Level: Beginner
  • Symptom: 404 on refresh at depth 17 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-110 — Dynamic routes #110

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 30 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-111 — Dynamic routes #111

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 43 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-112 — Dynamic routes #112

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 56 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-113 — Dynamic routes #113

  • Level: Advanced
  • Symptom: 404 on refresh at depth 69 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-114 — Dynamic routes #114

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 82 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-115 — Dynamic routes #115

  • Level: Beginner
  • Symptom: 404 on refresh at depth 95 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-116 — Dynamic routes #116

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 108 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-117 — Dynamic routes #117

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 121 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-118 — Dynamic routes #118

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 134 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-119 — Dynamic routes #119

  • Level: Advanced
  • Symptom: 404 on refresh at depth 147 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-120 — Dynamic routes #120

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 160 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-121 — Dynamic routes #121

  • Level: Beginner
  • Symptom: 404 on refresh at depth 173 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-122 — Dynamic routes #122

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 186 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-123 — Dynamic routes #123

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 199 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-124 — Dynamic routes #124

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 12 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-125 — Dynamic routes #125

  • Level: Advanced
  • Symptom: 404 on refresh at depth 25 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-126 — Dynamic routes #126

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 38 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-127 — Dynamic routes #127

  • Level: Beginner
  • Symptom: 404 on refresh at depth 51 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-128 — Dynamic routes #128

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 64 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-129 — Dynamic routes #129

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 77 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-130 — Dynamic routes #130

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 90 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-131 — Dynamic routes #131

  • Level: Advanced
  • Symptom: 404 on refresh at depth 103 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-132 — Dynamic routes #132

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 116 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-133 — Dynamic routes #133

  • Level: Beginner
  • Symptom: 404 on refresh at depth 129 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-134 — Dynamic routes #134

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 142 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-135 — Dynamic routes #135

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 155 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-136 — Dynamic routes #136

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 168 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-137 — Dynamic routes #137

  • Level: Advanced
  • Symptom: 404 on refresh at depth 181 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-138 — Dynamic routes #138

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 194 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-139 — Dynamic routes #139

  • Level: Beginner
  • Symptom: 404 on refresh at depth 7 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-140 — Dynamic routes #140

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 20 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-141 — Dynamic routes #141

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 33 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-142 — Dynamic routes #142

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 46 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-143 — Dynamic routes #143

  • Level: Advanced
  • Symptom: 404 on refresh at depth 59 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-144 — Dynamic routes #144

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 72 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-145 — Dynamic routes #145

  • Level: Beginner
  • Symptom: 404 on refresh at depth 85 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-146 — Dynamic routes #146

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 98 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-147 — Dynamic routes #147

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 111 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-148 — Dynamic routes #148

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 124 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-149 — Dynamic routes #149

  • Level: Advanced
  • Symptom: 404 on refresh at depth 137 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-150 — Dynamic routes #150

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 150 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-151 — Dynamic routes #151

  • Level: Beginner
  • Symptom: 404 on refresh at depth 163 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-152 — Dynamic routes #152

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 176 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-153 — Dynamic routes #153

  • Level: Intermediate
  • Symptom: 404 on refresh at depth 189 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Loader not validating param causing empty UI after bad slug.
  • Primary remediation: Validate + notFound pattern for unknown ids.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-154 — Dynamic routes #154

  • Level: Intermediate+
  • Symptom: 404 on refresh at depth 2 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Search params parsed manually without decoding edge cases.
  • Primary remediation: Prefer explicit routes until you truly need splat.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-155 — Dynamic routes #155

  • Level: Advanced
  • Symptom: 404 on refresh at depth 15 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Optional param segment not modeled; empty string vs undefined confusion.
  • Primary remediation: Use template helpers or encodeURIComponent for untrusted input.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-156 — Dynamic routes #156

  • Level: Advanced+
  • Symptom: 404 on refresh at depth 28 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: useParams returns strings; math breaks without Number().
  • Primary remediation: Normalize types at boundary: zod parse params in loader or page.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-157 — Dynamic routes #157

  • Level: Beginner
  • Symptom: 404 on refresh at depth 41 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Link to dynamic route built with string concat XSS risk.
  • Primary remediation: Model optional segments explicitly; redirect unknown slugs.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

RR2-158 — Dynamic routes #158

  • Level: Beginner+
  • Symptom: 404 on refresh at depth 54 or wrong active nav highlight.
  • Structure symptom: duplicated layout or import cycles after refactor.
  • Root cause class: Catch-all splat used when specific routes would be clearer.
  • Primary remediation: Use useSearchParams or URLSearchParams with care for encoding.
  • Verify: direct URL load, back/forward, deep link from email, mobile share sheet.
  • Interview one-liner: Treat URL params as untrusted input: validate, then render.

<< 2.11 Overview