Skip to main content

Documentation Index

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

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

Systems Witch uses React Router’s HashRouter rather than the more common BrowserRouter. This is a deliberate choice for static hosting compatibility: hash-based URLs (/#/about, /#/projects) are resolved entirely in the browser. The server only ever receives a request for the HTML file itself; the fragment after # is never sent to the server, so no rewrite rules, _redirects files, or server configuration are needed. The app works identically on GitHub Pages, Netlify static, any CDN, or a plain nginx file server.

Static Page Route Injection

Each HTML shell sets a window.__STATIC_PAGE_ROUTE__ variable and includes a small redirect script that ensures the URL fragment is correct when a page is loaded directly (e.g. someone bookmarks pages/About.html or arrives via a shared link). For example, pages/About.html contains:
<script>
  window.__STATIC_PAGE_ROUTE__ = "/about";

  (function () {
    if (!window.location.hash || window.location.hash === "#") {
      window.location.replace(
        window.location.pathname +
        window.location.search +
        "#/about"
      );
    }
  })();
</script>
If the page loads without a hash (or with only #), the script immediately replaces the URL with the correct #/about fragment before React mounts. This means every static HTML shell is a valid direct-access entry point for its route.

Route Table

PathHTML ShellPage ComponentDescription
#/index.htmlHomeViewBoot animation + hero sigil
#/aboutpages/About.htmlAboutViewBio, env vars, profile
#/projectspages/Projects.htmlProjectsViewFilterable project grid
#/skillspages/Skills.htmlSkillsViewAnimated skill cards
#/articlespages/Articles.htmlArticlesViewls-style article listing
#/contactpages/Contact.htmlContactViewSigil contact form
#/testimonialspages/Testimonials.htmlTestimonialsViewTransmission-style testimonials

AnimatePresence and Route Transitions

Route changes are gated by AnimatePresence mode="wait" wrapping the <Routes> component. The key prop on <Routes> is set to location.pathname, which tells AnimatePresence that a new child has mounted whenever the route changes. With mode="wait", the outgoing page’s exit animation must complete before the incoming page begins its entrance animation — preventing two pages from animating simultaneously. Each page component wraps its content in <PageTransition>, which supplies the Framer Motion initial, animate, and exit variants (a CRT-style scaleY + opacity + filter brightness sequence). See the PageTransition component reference for the full animation spec.

Route Definitions

The full route tree as defined in the application entry point:
<HashRouter>
  <AnimatePresence mode="wait">
    <Routes location={location} key={location.pathname}>
      <Route path="/" element={<Layout />}>
        <Route index element={<HomeView />} />
        <Route path="about" element={<AboutView />} />
        <Route path="projects" element={<ProjectsView />} />
        <Route path="skills" element={<SkillsView />} />
        <Route path="articles" element={<ArticlesView />} />
        <Route path="contact" element={<ContactView />} />
        <Route path="testimonials" element={<TestimonialsView />} />
      </Route>
    </Routes>
  </AnimatePresence>
</HashRouter>
The <Layout /> component renders ScanlineOverlay, FilesystemNav, the <main> content area (which contains the <Outlet /> for child routes), and TerminalFooter. All seven page routes are children of this single layout route so that the shell remains mounted and only the content slot re-renders on navigation.

Adding a New Route

To add an eighth route to the site, follow these four steps:
  1. Create the page component. Build a new component (e.g. ServicesView) that uses <PageTransition> as its outermost wrapper and follows the same space-y-12 structure with a <header> containing <SectionSigil /> and <GlitchHeading />.
  2. Register the route. Add a <Route> entry inside the layout route in the app entry point:
    <Route path="services" element={<ServicesView />} />
    
  3. Create an HTML shell. Add pages/Services.html by copying any existing page shell and updating the <title> tag and the window.__STATIC_PAGE_ROUTE__ value:
    <script>
      window.__STATIC_PAGE_ROUTE__ = "/services";
      (function () {
        if (!window.location.hash || window.location.hash === "#") {
          window.location.replace(
            window.location.pathname + window.location.search + "#/services"
          );
        }
      })();
    </script>
    
  4. Add the link to the sidebar. Append an entry to the $p route array in FilesystemNav:
    { path: "/services", label: "~/services" }
    
For a full walkthrough with code examples for each step, see Adding Pages.

Build docs developers (and LLMs) love