Skip to main content

Documentation Index

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

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

Full Moon is a single-page application built with React Router configured in hash mode. Instead of relying on a server to resolve /about or /projects to the correct bundle, every URL encodes the route in the hash fragment — for example, https://your-site.com/#/about. This means the browser always loads the same index.html (or a per-page shell), and React Router takes over navigation entirely on the client side.

How It Works

React Router runs in hash mode, so all routes take the form /#/route. To support direct URL access and bookmarking on static hosts, each page in the pages/ directory has its own lightweight HTML shell. When a visitor lands on pages/about.html directly, the shell script fires before React mounts and ensures the hash is set correctly before the app boots. Each static shell does three things in order:
  1. Sets window.__STATIC_PAGE_ROUTE__ to the canonical route string for that page
  2. Inspects window.location.hash and redirects to the correct hash if it is missing or still at the root
  3. Loads the same compiled main.js bundle shared by every page
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>About | full-moon</title>
    <script type="module" crossorigin src="../assets/main.js"></script>
    <link rel="modulepreload" crossorigin href="../assets/proxy.js">
    <link rel="modulepreload" crossorigin href="./components/Navigation.js">
    <link rel="modulepreload" crossorigin href="./components/Cursor.js">
    <link rel="modulepreload" crossorigin href="./components/Layout.js">
    <link rel="modulepreload" crossorigin href="./components/SVGs.js">
    <link rel="stylesheet" crossorigin href="../assets/main.css">
    <script>
  window.__STATIC_PAGE_ROUTE__ = "/about";
  if (!window.location.hash || window.location.hash === "#/" || window.location.hash === "#") {
    window.location.hash = "/about";
  }
</script>
</head>
  <body>
    <div id="root"></div>
  </body>
</html>
Because the redirect happens synchronously before the React bundle parses, the app always boots with a well-formed hash and never shows a blank screen or a 404.

Route Table

Every route in the application has a corresponding static HTML shell under pages/.
RouteStatic ShellPage Title
/index.htmlHome
/aboutpages/About.htmlAbout
/skillspages/Skills.htmlSkills
/workpages/Work.htmlWork
/projectspages/Projects.htmlProjects
/case-studiespages/CaseStudies.htmlCase Studies
/blogpages/Blog.htmlBlog
/testimonialspages/Testimonials.htmlTestimonials
/contactpages/Contact.htmlContact

Why Hash Routing?

Static file hosts — GitHub Pages, Netlify, S3 static hosting, Vercel static output — serve files directly from a directory tree. When a user navigates to https://your-site.com/projects, the host looks for a file at /projects/index.html. If it does not exist, the host returns a 404 error. Hash routing sidesteps this entirely. Because the hash fragment (#/projects) is never sent to the server, every request resolves to an HTML file that actually exists on disk. The routing logic lives 100% in the browser. No server configuration, no _redirects file, and no catch-all rewrite rule is required. This also makes the app portable: the same build artifact can be deployed to any static host without modification.

Deployment

Because no server-side routing is required, Full Moon can be deployed to any host that can serve static files:
  • GitHub Pages — push the repository root to your gh-pages branch or configure Pages to serve from the main branch root
  • Netlify — drag and drop the repository root into Netlify Drop, or connect the repo and set the publish directory to /
  • Vercel — import the repository and set the output directory to /; no build command is needed since the files are pre-built
  • Any static CDN — upload the repository contents and point your domain at index.html
Add an empty .nojekyll file to the root of your repository when deploying to GitHub Pages. Without it, Jekyll — the default GitHub Pages processor — ignores directories and files whose names start with an underscore, which could silently swallow certain Vite chunk filenames. The Full Moon repo already includes .nojekyll for this reason.

Build docs developers (and LLMs) love