Skip to main content

Documentation Index

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

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

The Craft’s routing is powered by React Router v6, and every page is lazy-loaded via React.lazy() in assets/main.js. Adding a new page requires four coordinated changes: write the component, register a lazy import, declare a route, and optionally add a navigation entry so visitors can reach it from the moon-phase rail. The steps below walk through each one in order.
1

Create the page component

Create a new file inside the assets/ directory — for example, assets/Gallery.js. All page components in The Craft follow the same shell: they wrap their content in <PageTransition>, open with a centred <header> block using the font-cinzel heading and font-garamond subtitle, then render their main content below.
import { PageTransition } from '../components/PageTransition';

export function Gallery() {
  return (
    <PageTransition className="min-h-screen p-8 md:p-16">
      <header className="text-center mb-16">
        <h1 className="font-cinzel text-4xl md:text-6xl text-parchment mb-4">
          The Gallery
        </h1>
        <p className="font-garamond text-xl text-parchment/60 italic">
          Artifacts and visual incantations.
        </p>
      </header>
      {/* your content here */}
    </PageTransition>
  );
}
Study an existing page before writing your own. assets/Blog.js is a good template for list-based content; assets/About.js is a good template for a two-column hero layout. Matching the padding (p-8 md:p-16 lg:p-24) and typography classes keeps your new page visually consistent with the rest of the grimoire.
2

Add a lazy import to main.js

Open assets/main.js and find the block where the other pages are lazily imported — you will see nine existing React.lazy calls, one for each current page. Add your new component immediately after the last one, using the same pattern:
const Gallery = React.lazy(() =>
  import('./Gallery.js').then(m => ({ default: m.Gallery }))
);
The .then(m => ({ default: m.Gallery })) transform is required because The Craft uses named exports (export function Gallery()) rather than default exports. React.lazy expects a module with a default export, so this one-liner re-shapes the module object at import time.
The file name passed to import() must match exactly — including capitalisation. './gallery.js' and './Gallery.js' are different paths on case-sensitive file systems (Linux, most production hosting environments). Use the exact same casing as the file you created in Step 1.
3

Register the route

Still in assets/main.js, find the <Route path="/" element={<Layout />}> block that wraps all the existing page routes. Add your new route as a child:
<Route path="gallery" element={<Gallery />} />
The existing routes for reference:
<Route path="/" element={<Layout />}>
  <Route index element={<Home />} />
  <Route path="about" element={<About />} />
  <Route path="projects" element={<Projects />} />
  <Route path="skills" element={<Skills />} />
  <Route path="work" element={<Work />} />
  <Route path="case-studies" element={<CaseStudies />} />
  <Route path="blog" element={<Blog />} />
  <Route path="contact" element={<Contact />} />
  <Route path="testimonials" element={<Testimonials />} />
  <Route path="gallery" element={<Gallery />} />  {/* your new route */}
  <Route path="*" element={<NotFound />} />
</Route>
Keep the wildcard <Route path="*" element={<NotFound />} /> as the last child. React Router matches routes in order, so placing it anywhere above your new route will cause the 404 page to render instead of your content.
4

Add a navigation entry

Open components/MoonPhaseNav.js and add an entry to the navItems array:
{ path: '/gallery', name: 'The Gallery', phase: 'full' }
The available phase values, and the moon shape each one renders, are:
Phase valueAppearance
newCompletely dark circle
waxing-crescentThin sliver lit on the right
first-quarterRight half lit
waxing-gibbousMostly lit, small shadow on the left
fullFully lit circle
waning-gibbousMostly lit, small shadow on the right
last-quarterLeft half lit
waning-crescentThin sliver lit on the left
Pick any phase that is not already used by an existing route, or intentionally re-use one if you prefer a specific icon.
The moon-phase navigation is designed for exactly 8 routes — one per major lunar phase. If you add more than 8 routes, phases will be reused and two entries will display identical icons. For portfolios with more sections, consider extending the nav style in MoonPhaseNav.js with a different visual indicator (a numbered badge, a sigil icon, or a text-only label) for the overflow entries.
You can test a new route in the browser before adding it to the nav. Navigate directly to http://localhost:5173/gallery — the route will render correctly because the wildcard /* only fires for paths that have no registered route. The nav entry is only needed so that visitors can discover the page through the UI.
Here is a complete before-and-after summary of the four files touched when adding a /gallery route.

assets/Gallery.js

New file. Export a Gallery function component wrapped in <PageTransition>. Add your header and content inside.

assets/main.js

Add one React.lazy import and one <Route path="gallery" ... /> child inside the Layout route.

components/MoonPhaseNav.js

Add { path: '/gallery', name: 'The Gallery', phase: 'full' } to the navItems array.

Nothing else

No changes needed to any shared component files — the Layout and PageTransition wrappers handle everything automatically. The project ships as a pre-built static bundle, so there is no tailwind.config.js or vite.config.js to edit in the deployed output.

Build docs developers (and LLMs) love