Aurora Borealis uses hash-based SPA routing: every route is a hash fragment handled entirely in the browser, and each page has a corresponding static HTML file underDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/aurora-borealis/llms.txt
Use this file to discover all available pages before exploring further.
pages/ that bootstraps the React app and redirects to the correct hash. Adding a new page involves four files: the page component in the source bundle, the router configuration, a static HTML entry point, and an update to ConstellationNav.
Steps
Open the Vite source project and locate the page components file (the source equivalent of what becomes
assets/main.js). Page components follow a consistent shape: a single functional component that renders a <main> element with Tailwind classes for padding and max-width, wrapped in the project’s page-level motion container.Copy an existing simple page (such as the Writing or Contact page) as your starting point and strip its content, keeping the structural wrapper:
// NewPage component — minimal starting point
const NewPage = () => {
return (
<PageTransition>
<main className="min-h-screen pt-32 pb-32 px-6 max-w-5xl mx-auto relative">
<div className="mb-16">
<h1 className="font-space text-5xl text-star mb-4">
New Page Title
</h1>
<p className="font-mono text-muted text-sm uppercase tracking-widest">
Subtitle or status line
</p>
</div>
{/* Your content here */}
</main>
</PageTransition>
);
};
PageTransition is the shared wrapper component that applies the fade + blur entrance and exit animation. It reads as follows in source:const PageTransition = ({ children }) => {
const location = useLocation();
return (
<motion.div
key={location.pathname}
initial={{ opacity: 0, filter: "blur(10px)" }}
animate={{ opacity: 1, filter: "blur(0px)" }}
exit={{ opacity: 0, filter: "blur(10px)" }}
transition={{ duration: 0.4 }}
>
{children}
</motion.div>
);
};
Wrapping your page in
<PageTransition> ensures it uses the same fade-and-blur animation as every other route.Find the
<Routes> block inside the top-level App component and add a new <Route> element for your page:<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/about" element={<AboutPage />} />
<Route path="/projects" element={<ProjectsPage />} />
<Route path="/skills" element={<SkillsPage />} />
<Route path="/writing" element={<WritingPage />} />
<Route path="/case-studies" element={<CaseStudiesPage />} />
<Route path="/contact" element={<ContactPage />} />
{/* Add your new route here */}
<Route path="/new-page" element={<NewPage />} />
</Routes>
The path string must exactly match the hash fragment you will use in the HTML entry point — without the leading
#.If you have not already applied
<PageTransition> inside the component itself (as shown in Step 1), you can apply it at the route level instead:Either location works — just do not double-wrap by applying it both inside the component and at the route level.
Create a new file at
pages/NewPage.html. This file is the static entry point that the browser loads when a visitor navigates directly to the page URL. Copy the template below exactly, updating the <title> tag and the two "/new-page" strings to match your actual route:<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>New Page | aurora-borealis</title>
<script type="module" crossorigin src="../assets/main.js"></script>
<link rel="modulepreload" crossorigin href="./useScreenInit.js">
<link rel="modulepreload" crossorigin href="../assets/jsx-runtime.js">
<link rel="modulepreload" crossorigin href="../assets/proxy.js">
<link rel="modulepreload" crossorigin href="./components/ConstellationNav.js">
<link rel="modulepreload" crossorigin href="./components/AuroraBackground.js">
<link rel="modulepreload" crossorigin href="./components/StarField.js">
<link rel="stylesheet" crossorigin href="../assets/main.css">
<script>
window.__STATIC_PAGE_ROUTE__ = "/new-page";
(function () {
if (!window.location.hash || window.location.hash === "#") {
window.location.replace(
window.location.pathname + window.location.search + "#/new-page"
);
}
})();
</script>
</head>
<body>
<div id="root"></div>
</body>
</html>
The
window.__STATIC_PAGE_ROUTE__ assignment at the top of the inline <script> block tells the React app which route this HTML file corresponds to, so it can activate the correct route on first load without waiting for the hash redirect:Update
"/new-page" to match the route path you registered in Step 2. This value must be identical to the path prop on your <Route> element.Open
components/ConstellationNav.js and add an entry for your new page to the navigation link array. The existing entries follow the pattern of a route path, a display label, and optional coordinates for the SVG constellation line rendering:// Inside ConstellationNav.js — add to the nav links array
{ path: "/new-page", label: "New Page" }
The nav component renders each entry as a
<Link> (from React Router DOM) targeting the hash route. After adding the entry, rebuild the project so the updated ConstellationNav.js file is reflected in assets/main.js.Reference: static HTML entry point fields
| Field | Value | Purpose |
|---|---|---|
<title> | New Page | aurora-borealis | Browser tab title |
src="../assets/main.js" | Relative path from pages/ | Loads the React app bundle |
href="./useScreenInit.js" | Root-relative path (resolves to repo root) | Preloads the React + screen-size init module |
window.__STATIC_PAGE_ROUTE__ | e.g. "/new-page" | Tells the SPA which route to activate on load |
| Hash redirect script | Replaces URL with #/new-page | Ensures hash routing initializes correctly on direct visits |
The
assets/ references (e.g. ../assets/main.js) are relative to the pages/ subdirectory, one level below the project root. The useScreenInit.js and components/ references use ./ — root-relative paths that resolve from the project root regardless of the requesting page. If you place your HTML file in a nested subdirectory, adjust only the ../assets/ paths accordingly.