Skip to main content

Documentation Index

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

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

The Layout component is the outermost wrapper of the entire Web Weaver application. Every page a visitor sees is rendered inside it. Beyond providing a consistent navigation header, Layout is the single place where the three global ambient effects — EmberCursor, FogLayer, and BlackCat — are mounted, ensuring they are present on every route without any page component needing to import them individually. Understanding Layout is the key to understanding how the whole app is assembled.

What Layout does

Layout fulfils three distinct responsibilities:
  1. Routing shell — It wraps the app in React Router v6’s HashRouter and defines the top-level Routes tree, mapping URL hashes to page components.
  2. Global effects host — It renders <EmberCursor />, <FogLayer />, and <BlackCat /> exactly once, outside of any route, so they persist across navigation.
  3. Navigation bar — It outputs a sticky header containing hash-based <Link> elements to every section of the portfolio.
The header contains the following hash-router links, appearing in this order:
LabelHash
About#/about
Projects#/projects
Skills#/skills
Work#/work
Case Studies#/case-studies
Blog#/blog
Testimonials#/testimonials
Contact#/contact

Module exports

Because the compiled bundle uses short export names for tree-shaking, the Layout.js module exposes several named exports. You will rarely need to import these directly — the default app entry point wires them up automatically.
ExportDescription
HThe HashRouter wrapper component
LThe header/nav component containing hash Link elements
RThe Routes container
oA single Route definition
rThe createHashRouter render helper used by the app entry point

Usage

Layout is instantiated once in assets/main.js and is not intended to be composed manually inside page components. The structure it renders looks like this:
// Conceptual render tree — actual code is in the compiled bundle
import { HashRouter, Routes, Route, Outlet } from "react-router-dom";
import EmberCursor from "./EmberCursor";
import FogLayer from "./FogLayer";
import BlackCat from "./BlackCat";

export default function Layout() {
  return (
    <HashRouter>
      {/* Global ambient effects — always mounted */}
      <EmberCursor />
      <FogLayer />
      <BlackCat />

      {/* Sticky navigation header */}
      <header>
        <nav>
          <Link to="/about">About</Link>
          <Link to="/projects">Projects</Link>
          <Link to="/skills">Skills</Link>
          <Link to="/work">Work</Link>
          <Link to="/case-studies">Case Studies</Link>
          <Link to="/blog">Blog</Link>
          <Link to="/testimonials">Testimonials</Link>
          <Link to="/contact">Contact</Link>
        </nav>
      </header>

      {/* Active route renders here */}
      <main>
        <Outlet />
      </main>
    </HashRouter>
  );
}

Props

Layout accepts no props. All configuration — routes, nav links, and ambient components — is hard-coded inside the module.

Implementation notes

HashRouter strategy

Web Weaver uses HashRouter (URLs like /#/about) rather than BrowserRouter. This means the app can be deployed to any static file host without server-side URL rewriting.

Global effects lifecycle

EmberCursor, FogLayer, and BlackCat are mounted outside the <Routes> tree, so they are never unmounted during navigation. Their internal state and animations are preserved across all route transitions.

z-index layering

The three ambient components each manage their own stacking context. FogLayer sits above the background but below page content; BlackCat uses a low z-index so it never obscures interactive elements; EmberCursor sits at the very top.

No props needed

Because Layout is a singleton shell rather than a reusable widget, it deliberately exposes no configuration props. Customising nav links or adding new routes requires editing the module directly.
When adding a new page to the portfolio, register it in two places: add a <Route> inside the Routes tree, and add a corresponding <Link> to the nav header. Both live inside the Layout.js module.

Build docs developers (and LLMs) love