.claude/skills/github-pages-spa-redirect-prerender/SKILL.md
Fix broken redirects on GitHub Pages SPAs when renaming routes. Use when: (1) Old URLs return 404 instead of redirecting after a route rename/rebrand, (2) React Router <Navigate> redirects only work after clicking a link but not on direct URL access, (3) GitHub Pages serves raw 404 for old routes because no prerendered HTML exists. Covers prerendering redirect routes and handling trailing-slash variants.
npx skillsauth add Dbochman/dotfiles github-pages-spa-redirect-prerenderInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
When renaming routes in a GitHub Pages SPA (e.g., /projects/andre to /projects/echonest),
adding <Navigate to="/projects/echonest" replace /> in React Router is not enough. Direct
URL access to the old path returns a raw 404 from GitHub Pages because no index.html exists
at that path. The SPA shell never loads, so the client-side redirect never executes.
<Navigate> redirect works when navigating within the SPA but 404s on direct access<Route path="/projects/andre" element={<Navigate to="/projects/echonest" replace />} />
Add old paths to your prerender script so GitHub Pages has an index.html at each path.
The prerendered HTML loads the SPA shell, which then performs the client-side redirect.
// scripts/prerender.mjs
const redirectRoutes = [
'/projects/andre',
'/projects/andre/',
'/blog/2026-02-04-andre-collaborative-music-queue',
'/blog/2026-02-04-andre-collaborative-music-queue/',
];
const routes = [
...dynamicRoutes,
...redirectRoutes, // Include old routes so they get HTML files
];
Analytics data often shows traffic to both /path and /path/. Add redirect routes
and prerender entries for both variants.
<Route path="/projects/andre" element={<Navigate to="/projects/echonest" replace />} />
<Route path="/projects/andre/" element={<Navigate to="/projects/echonest" replace />} />
dist/projects/andre/index.html exists (the prerendered file)After rebranding Andre to EchoNest:
/projects/andre -> prerendered HTML loads SPA -> <Navigate> redirects to /projects/echonest/projects/andre/ -> same flow with trailing-slash variant/blog/2026-02-04-andre-collaborative-music-queue -> redirects to new blog slug_redirects files or server-side rules, making prerendering unnecessarysitemap.xml to use the new URLs (old URLs should not remain in sitemap)tools
Use exact configured Reolink cameras through the local Home Hub for availability and power status, fresh stills, visual commentary, protected Dylan/Julia/household sharing, and reversible spotlight control. Supports trusted owner tasks and explicitly scoped proactive automations; not for Nest or Ring cameras, arbitrary recipients, recordings, account changes, or raw camera APIs.
data-ai
Privately manage Dylan and Julia's household plant inventory and care history by physical location, bed, and exact Flower Cam view. Use for confirmed plant onboarding from camera conversations, camera- or bed-filtered inventory, record corrections, individual or whole-bed care, and private filtered exports. Pair with reolink-camera when an owner asks about plants visible in Flower Cam images.
testing
Inspect and control the physically secured Reachy Mini at Crosstown through ClawBody. Use for requests to check Reachy, look around, express an emotion, play any official emotion or dance preset, speak proactively, mute or unmute its microphone, stop movement, or describe what its camera sees.
tools
Handle Reachy/iMessage handoffs, selective durable memory, forgetting, and diagnostics; automatic context comes from the gateway plugin.