Skip to main content

Documentation Index

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

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

VisitorCounter is a self-contained hit counter that evokes the animated GIF visitor counters that adorned personal homepages of the late 1990s. It reads a persistent count from localStorage, increments it at most once per browser session, and displays the result as a row of individual LED-segment cells using the VT323 monospace font in cyan-on-black — a faithful reproduction of the vintage seven-segment display aesthetic.

Storage logic

The component uses two Web Storage APIs to separate persistence from session deduplication: localStorage key: retro_visitor_count Holds the running total as a decimal string. This value persists indefinitely across browser sessions and is shared by all tabs in the same origin. On first ever load (no existing key), the value is seeded at 1337 as a playful nod to leet-speak culture. sessionStorage key: has_visited Acts as a per-session flag. It is set to "true" the first time the component mounts in a given browser session and is cleared automatically by the browser when the tab or window is closed. Subsequent navigations within the same session (opening new pages, refreshing) will find the flag already set and will not increment the counter again. The full increment logic, run once inside useEffect([]):
const stored = localStorage.getItem('retro_visitor_count');
let count = stored ? parseInt(stored, 10) : 1337;

if (!sessionStorage.getItem('has_visited')) {
  count += 1;
  localStorage.setItem('retro_visitor_count', count.toString());
  sessionStorage.setItem('has_visited', 'true');
}

setCount(count);

Display format

The count integer is converted to a six-digit zero-padded string via:
count.toString().padStart(6, '0')
This means counts from 000001 through 999999 are all displayed with leading zeros, matching the fixed-width readout of a physical odometer or LED panel. Each digit is rendered as its own <div> cell with these styles:
PropertyValue
Width / Heightw-3 / h-4 (12×16px)
Backgroundbg-[#111] (near-black)
Text colortext-retro-cyan (cyan)
Fontfont-vt323 text-sm
Borderborder border-[#222]
Alignmentflex items-center justify-center
The cells sit inside a wrapper div with bg-black, p-1 padding, and a two-pixel beveled border (border-2 border-retro-darkgray border-t-retro-gray border-l-retro-gray) that gives the counter the appearance of a slightly recessed hardware panel.

Where it appears

VisitorCounter is rendered inside the Taskbar component’s system tray — the right-hand win98-in panel next to the pulsing status dots and retro clock. It is hidden on small screens via hidden sm:block so the tray does not overflow on narrow viewports.

Usage

VisitorCounter accepts no props. It is already embedded inside Taskbar, so adding Taskbar to your app root is sufficient for most use cases. If you want to embed the counter elsewhere — for example, inside a dedicated “About” window — import and place it directly:
import { V as VisitorCounter } from './components/VisitorCounter';

export default function AboutWindow() {
  return (
    <div className="p-4 font-pixel text-sm">
      <p>You are visitor number:</p>
      <div className="mt-2">
        <VisitorCounter />
      </div>
    </div>
  );
}
The counter reflects the number of unique browser sessions on the device that viewed the portfolio, not server-side analytics. Clearing localStorage resets the display back to 1337 on the next visit.

Taskbar

The Taskbar houses VisitorCounter inside its system tray by default.

CustomCursor

The pixel-art cursor overlay, exported from CustomCursor.js.

Architecture: Styling

VT323 font, retro-cyan color, and other theme tokens explained.

Customization: Theming

Swap colors and fonts to make the counter fit your own retro palette.

Build docs developers (and LLMs) love