Problem
There is no error.tsx, not-found.tsx, or global-error.tsx anywhere under src/app:
$ find src/app -iname "error.tsx" -o -iname "not-found.tsx" -o -iname "global-error.tsx"
# (no output)
The app already has a custom PWA offline fallback (src/app/offline/page.tsx) and a custom map-error-boundary.tsx scoped to the map, but nothing for the App Router's own error/404 boundaries, so:
-
An invalid route (or notFound() calls, e.g. src/app/city/[slug]/page.tsx and src/app/competitions/[slug]/page.tsx both call it for an unknown slug) falls back to Next.js's generic unstyled 404 page instead of the site's own design.
-
A thrown error during rendering falls back to Next's generic unstyled error page. This is a real, reachable path: the three /docs/awesome-* pages (awesome-student-resources, awesome-study-resources, awesome-skills-plugins) call fetchAwesomeList() with no try/catch:
$ grep -rn "fetchAwesomeList" "src/app/docs/(article)/awesome-skills-plugins/page.tsx" "src/app/docs/(article)/awesome-student-resources/page.tsx" "src/app/docs/(article)/awesome-study-resources/page.tsx"
src/app/docs/(article)/awesome-skills-plugins/page.tsx:15: const sections = await fetchAwesomeList("awesome-skills-plugins-for-students");
src/app/docs/(article)/awesome-student-resources/page.tsx:15: const sections = await fetchAwesomeList("awesome-student-resources");
src/app/docs/(article)/awesome-study-resources/page.tsx:15: const sections = await fetchAwesomeList("awesome-study-resources");
and fetchAwesomeList() (src/lib/awesome-list.ts) throws whenever the GitHub raw-content fetch isn't res.ok (rate-limited, repo renamed, transient outage during the 24h ISR revalidation). Any of those makes the whole docs page crash to the default error screen.
Fix
Add src/app/error.tsx (client component, matches the site's theme/design) and src/app/not-found.tsx for a themed 404. Optionally wrap fetchAwesomeList() calls in a try/catch that renders a "couldn't load this list right now" EmptyState instead of crashing the page (the app already has an EmptyState component used elsewhere, e.g. results-list.tsx).
Acceptance criteria
Problem
There is no
error.tsx,not-found.tsx, orglobal-error.tsxanywhere undersrc/app:The app already has a custom PWA offline fallback (
src/app/offline/page.tsx) and a custommap-error-boundary.tsxscoped to the map, but nothing for the App Router's own error/404 boundaries, so:An invalid route (or
notFound()calls, e.g.src/app/city/[slug]/page.tsxandsrc/app/competitions/[slug]/page.tsxboth call it for an unknown slug) falls back to Next.js's generic unstyled 404 page instead of the site's own design.A thrown error during rendering falls back to Next's generic unstyled error page. This is a real, reachable path: the three
/docs/awesome-*pages (awesome-student-resources,awesome-study-resources,awesome-skills-plugins) callfetchAwesomeList()with notry/catch:and
fetchAwesomeList()(src/lib/awesome-list.ts) throws whenever the GitHub raw-content fetch isn'tres.ok(rate-limited, repo renamed, transient outage during the 24h ISR revalidation). Any of those makes the whole docs page crash to the default error screen.Fix
Add
src/app/error.tsx(client component, matches the site's theme/design) andsrc/app/not-found.tsxfor a themed 404. Optionally wrapfetchAwesomeList()calls in atry/catchthat renders a "couldn't load this list right now"EmptyStateinstead of crashing the page (the app already has anEmptyStatecomponent used elsewhere, e.g.results-list.tsx).Acceptance criteria
src/app/not-found.tsxrenders a themed 404 (verify by visiting a nonexistent route)src/app/error.tsxrenders a themed error screen