Skip to main content

Documentation Index

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

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

Adding a page to Web Surfer is a two-step process: first you register the route in the React app’s router config and create the page component, then you create a static HTML entry file in the pages/ directory so that visitors can reach it directly by URL. Both steps are needed because the app uses hash-based routing — each HTML file is responsible for setting the correct hash before the React app boots.

How routing works

Web Surfer uses React Router v6 in hash history mode. Every URL in the site looks like yoursite.com/#/about — the # fragment is what React Router reads to decide which component to render. All route definitions live in the router config in the source file src/main.jsx (or equivalent). Adding a new page means:
  1. Telling the router what path maps to what component.
  2. Giving that route its own HTML entry point so the page can be linked or bookmarked directly.
Because the deployed site is a pre-built static artifact, you need the source project to add React pages — you cannot add new routes by only editing files in the dist/ or built output.

Step-by-step: add a new page

1

Create your new React component

Add a new file at src/pages/Portfolio.jsx (or wherever your source pages live). See the example component in the next section.
2

Register the route in the router config

Open src/main.jsx and import your component, then add an entry to the createHashRouter array:
src/main.jsx
import Portfolio from './pages/Portfolio';

const router = createHashRouter([
  // ... existing routes
  { path: '/portfolio', element: <Layout><Portfolio /></Layout> },
]);
Wrap the component in <Layout> just like every other route so it inherits the header, footer, sparkle cursor, and page-transition animation.
3

Create a static HTML entry file

Create pages/Portfolio.html in the repository root (alongside the existing pages/About.html, pages/Skills.html, etc.). Use this pattern — it is identical to every other page file except for the title and route value:
pages/Portfolio.html
<!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>Portfolio | web-surfer</title>
    <script type="module" crossorigin src="../assets/main.js"></script>
    <link rel="modulepreload" crossorigin href="../assets/jsx-runtime.js">
    <link rel="modulepreload" crossorigin href="./components/SparkleCursor.js">
    <link rel="modulepreload" crossorigin href="../assets/proxy.js">
    <link rel="modulepreload" crossorigin href="./components/Layout.js">
    <link rel="modulepreload" crossorigin href="./components/Win98Window.js">
    <link rel="stylesheet" crossorigin href="../assets/main.css">
    <script>
      window.__STATIC_PAGE_ROUTE__ = "/portfolio";
      if (!window.location.hash || window.location.hash === "#/" || window.location.hash === "#") {
        window.location.hash = "/portfolio";
      }
    </script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
Change "/portfolio" to match the path you used in the router config.
4

Rebuild the project

Run the build command to compile your new component and update the output assets:
npm run build
After the build completes, dist/pages/Portfolio.html will be present alongside the updated dist/assets/main.js.
5

Add a navigation link

Open Layout.js (or your nav component) in the source and add a link to your new route so visitors can find it from the main navigation. Use React Router’s <Link> component to keep navigation client-side:
import { Link } from 'react-router-dom';

<Link to="/portfolio">Portfolio</Link>

Using Win98Window in your page

The Win98Window component wraps any content in a fully interactive Windows 98–style window chrome with a title bar, minimize, maximize, and close buttons. Import it from components/Win98Window and pass a title and optional icon prop:
src/pages/Portfolio.jsx
import { Win98Window } from '../../components/Win98Window';
import { FolderOpen } from 'lucide-react';

export default function Portfolio() {
  return (
    <Win98Window
      title="My Portfolio"
      icon={<FolderOpen size={14} />}
    >
      <div className="p-4">
        <h2 className="font-pixel text-xs mb-4">FEATURED WORK</h2>
        {/* your content */}
      </div>
    </Win98Window>
  );
}
Win98Window accepts these props:
PropTypeDescription
titlestringText shown in the title bar
iconReactNodeOptional icon rendered before the title (16 × 16 recommended)
classNamestringExtra classes applied to the outer window wrapper
contentClassNamestringExtra classes applied to the inner win98-content div
defaultMaximizedbooleanStart the window in full-screen maximized state
onClosefunctionCallback fired when the ✕ button is clicked
The pages/ HTML files in the repository are Vite build outputs — they are not hand-authored pages. The window.__STATIC_PAGE_ROUTE__ script block is the key ingredient: it sets the URL hash before React boots, so the router sees the correct path immediately and renders the right component. This is how each page can be a standalone HTML file without any server-side routing or redirect rules.
For blog posts or long-form writing pages, add the notebook-paper CSS class to the content wrapper inside your component. It applies a cream background with repeating teal ruled lines and a pink margin rule, giving the page an authentic lined-paper feel:
<div className="notebook-paper p-4 leading-[25px]">
  <p>Your writing goes here...</p>
</div>

Build docs developers (and LLMs) love