Skip to main content

Documentation Index

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

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

Log Portfolio handles navigation without React Router. Instead, the app reads from window.location.hash and a special global variable — window.__STATIC_PAGE_ROUTE__ — to determine which window should open automatically when the page loads. This bespoke approach keeps the routing surface minimal and works seamlessly with GitHub Pages static hosting, where server-side URL rewriting is not available.

How Hash-Based Routing Works

The app’s router inspects window.location.hash on mount. A URL like https://example.com/#/about-page will cause the router to match the /about-page route and call openWindow() for the About Me app. Because the hash fragment is handled entirely client-side, no server configuration is required and the same index.html entry point serves all routes. window.__STATIC_PAGE_ROUTE__ is an additional signal used by the static pages in pages/. When a visitor navigates directly to a static page file (e.g. pages/AboutPage.html), that file sets this variable before the React app boots. The router reads it on startup and treats it as the intended route, even if the hash is not yet set.

Static Page Files

Each app in the desktop registry has a corresponding HTML file in pages/. These files load the same compiled Vite bundle as index.html, but they inject two extra lines into a <script> block in the <head>:
<!-- pages/AboutPage.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>AboutPage | log-portfolio</title>
    <script type="module" crossorigin src="../assets/main.js"></script>
    <!-- ... modulepreload links ... -->
    <link rel="stylesheet" crossorigin href="../assets/main.css">
    <script>
  window.__STATIC_PAGE_ROUTE__ = "/about-page";
  if (!window.location.hash || window.location.hash === "#/" || window.location.hash === "#") {
    window.location.hash = "/about-page";
  }
</script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
The inline script does two things:
  1. Sets window.__STATIC_PAGE_ROUTE__ — tells the React router which route this page represents, regardless of the current hash.
  2. Sets window.location.hash — forces the hash to the correct route if it isn’t already set (e.g. on a fresh load). If the visitor already has a hash (such as from a previously visited URL), it is left untouched to avoid overriding their navigation state.
The result is that navigating directly to pages/AboutPage.html renders the full desktop with the AboutMe.txt window already open — the same experience as reaching index.html#/about-page.

All Static Page Routes

AboutPage.html

Route: /about-page
Opens the AboutMe.txt Notepad-style window with the developer’s bio and skills summary.

BlogPage.html

Route: /blog-page
Opens the Internet Explorer window with the retro Geocities-style blog.

ContactPage.html

Route: /contact-page
Opens the Outlook Express window with the email compose form.

ProjectsPage.html

Route: /projects-page
Opens the My Computer file explorer window listing portfolio projects.

SkillsPage.html

Route: /skills-page
Opens the Control Panel window with animated skill installation progress bars.

TestimonialsPage.html

Route: /testimonials-page
Opens the MSN Messenger window with scrolling client testimonials as chat messages.

Adding a New Static Page

1

Copy an existing page file

Duplicate any existing file in pages/ as a starting point. For example, to add a resume page:
cp pages/AboutPage.html pages/ResumePage.html
2

Update the route value and title

Open the new file and change the <title> and the two routing values in the inline <script>:
<title>ResumePage | log-portfolio</title>
<script>
  window.__STATIC_PAGE_ROUTE__ = "/resume-page";
  if (!window.location.hash || window.location.hash === "#/" || window.location.hash === "#") {
    window.location.hash = "/resume-page";
  }
</script>
3

Add the app to the Desktop registry

Add a new entry to the apps array in components/Desktop.js with a matching id and your new app component:
{
  id: "resume",
  title: "Resume.pdf",
  icon: <FileText size={32} className="text-red-400 drop-shadow-md" />,
  component: <ResumeApp />,
  defaultSize: { width: 500, height: 600 },
}
4

Wire the route in the app router

Add the /resume-page route to the app’s hash router so that the route string maps to the resume window id and the router calls openWindow() on page load.

The .nojekyll File

The repository root contains a .nojekyll file. GitHub Pages runs a Jekyll build step by default that ignores any file or directory whose name begins with an underscore (_). The .nojekyll file disables this behavior, ensuring that Vite’s assets/ output directory and any other files that Jekyll might otherwise suppress are served correctly. Without it, the compiled JavaScript and CSS could return 404 errors on GitHub Pages.

Further Reading

Architecture Overview

The full three-layer shell model, data flow diagram, and the desktop app registry format.

Window Management System

How WindowContext tracks open windows, manages z-index focus ordering, and drives window animations.

Build docs developers (and LLMs) love