Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/spooky-developer/llms.txt

Use this file to discover all available pages before exploring further.

Spooky Developer uses React Router v6 (react-router-dom) for all client-side navigation. There are ten registered routes — nine visible pages and a wildcard 404 catch-all — all rendered inside a shared Layout parent. The navigation bar is driven by a LINKS array that mirrors these routes, minus the catch-all.

Provider Nesting

The component tree at the application root is:
// From the App component in assets/main.js
<HauntProvider>           {/* Global haunted state */}
  <BrowserRouter>         {/* React Router history context */}
    <Routes>
      <Route path="/" element={<Layout />}>   {/* Shared shell */}
        {/* ...child routes */}
      </Route>
    </Routes>
  </BrowserRouter>
</HauntProvider>
HauntProvider sits outside BrowserRouter so that scare components and page components can both read context without restriction. BrowserRouter uses the HTML5 History API — URLs are clean paths like /about, not hash-based like /#/about.

Route Table

All routes are defined as children of the root "/" route whose element is <Layout />. React Router renders Layout for every URL and fills its <Outlet /> with the matching child route component.
// Route definitions (from assets/main.js)
[
  { path: "/",             element: <HomePage /> },       // index route
  { path: "about",         element: <AboutPage /> },
  { path: "projects",      element: <ProjectsPage /> },
  { path: "skills",        element: <SkillsPage /> },
  { path: "work",          element: <WorkPage /> },
  { path: "case-studies",  element: <CaseStudiesPage /> },
  { path: "articles",      element: <ArticlesPage /> },
  { path: "contact",       element: <ContactPage /> },
  { path: "testimonials",  element: <TestimonialsPage /> },
  { path: "*",             element: <NotFoundPage /> },   // 404 catch-all
]
The root "/" child uses the index prop (i.e., no path) so it matches exactly when the URL is /.

The Layout Outlet

Layout.js is the parent route element. It renders the full page shell and uses React Router’s <Outlet /> to inject the active page component:
// components/layout/Layout.js (simplified)
const Layout = () => (
  <div className="min-h-screen flex flex-col relative ...">
    <Background />
    <CursorTrail />
    <SpiderScare />
    <IdleGhost />
    <header className="sticky top-0 z-40 ...">
      <Nav />
    </header>
    <main className="flex-grow container mx-auto ...">
      <Outlet />   {/* ← active page renders here */}
    </main>
    <Footer />
  </div>
);
Every navigation action swaps only the <Outlet /> content; the Nav, Background, Footer, and scare components remain mounted. The Nav component drives its tombstone buttons from a static LINKS array (internally Tp in the compiled output). It contains the nine user-facing routes — the wildcard "*" is intentionally excluded:
// components/layout/Nav.js — LINKS array
const LINKS = [
  { path: "/",            label: "Home" },
  { path: "/about",       label: "About" },
  { path: "/projects",    label: "Projects" },
  { path: "/skills",      label: "Skills" },
  { path: "/work",        label: "Work" },
  { path: "/case-studies",label: "Cases" },
  { path: "/articles",    label: "Articles" },
  { path: "/testimonials",label: "Praise" },
  { path: "/contact",     label: "Contact" },
];
Each entry is rendered as a <NavLink> styled as a tombstone. React Router’s NavLink receives an isActive boolean via its className callback, which is used to apply the raised / glowing active state (-translate-y-4, border-haunt-moon/50 text-haunt-moon).

Adding a New Route

1

Create the page component

Add a new component in assets/main.js (or a separate file). For example:
const BlogPage = () => (
  <div className="py-12">
    <h1 className="text-5xl text-haunt-moon mb-8 text-center">From the Crypt</h1>
    {/* your content */}
  </div>
);
2

Register the route

Add a <Route> child inside the root "/" route in the App function:
<Route path="blog" element={<BlogPage />} />
3

Add a nav link

Append an entry to the LINKS array in Nav.js:
{ path: "/blog", label: "Blog" },
A new tombstone button will appear in the navigation bar automatically.
React Router v6 resolves child route path values relative to the parent. Because the parent route is "/", child paths like "about" and "blog" resolve to /about and /blog respectively — no leading slash is needed on child routes.

Build docs developers (and LLMs) love