· retrotech  · 8 min read

Back to the Future: Recreating Your Old ICQ Web Pages

A step-by-step guide to rebuild your early-2000s ICQ-style personal web pages with modern tools. Includes templates (HTML/CSS/JS), tips for retro styling, visitor counters, guestbooks, hosting options, and resources for GIFs, fonts, and assets.

A step-by-step guide to rebuild your early-2000s ICQ-style personal web pages with modern tools. Includes templates (HTML/CSS/JS), tips for retro styling, visitor counters, guestbooks, hosting options, and resources for GIFs, fonts, and assets.

Why rebuild an ICQ-era page?

Nostalgia is powerful. Recreating your old ICQ web pages is a fun way to preserve memories and learn web development. Instead of cloning an 800×600 fixed layout with HTML tables, you can capture the look and feel with modern, accessible, and mobile-friendly techniques - plus add interactive features like visitor counters, guestbooks, and music players.

This guide walks you through the process step-by-step, gives ready-to-use templates (HTML/CSS/JS), and points to hosting and asset resources so you can relive the early 2000s with your own personal twist.


Plan: pick the features you want to recreate

Common ICQ-page features to consider:

  • Tiled background images and bright gradients
  • Animated GIFs (dancing babies, glitter, under construction)
  • Visitor counters and hit counters
  • Guestbook or message wall
  • MIDI or background music player
  • Marquees, flashing text, and pixel fonts
  • Link lists, badges, and contact details (ICQ UINs!)

Decide which elements are purely aesthetic and which need to be interactive. Aesthetic items are easy - GIFs, fonts, tiled patterns. Interactive ones need a backend or a 3rd-party API.


Assets: where to find retro GIFs, patterns, and fonts

Keep optimized, small GIFs and compressed images to avoid long load times. Convert large animated GIFs into APNG or short looping MP4 if you want better performance.


Starter project structure

A minimal project you can host on GitHub Pages, Netlify, or Vercel:

  • index.html
  • styles.css
  • script.js
  • /assets/ (GIFs, favicon, tiled background)

Below are ready-to-use templates you can copy and paste.


HTML: basic retro page (index.html)

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <link rel="stylesheet" href="styles.css" />
    <link rel="icon" href="/assets/favicon.ico" />
    <meta name="description" content="My retro ICQ-style homepage" />
  </head>
  <body>
    <div class="page-frame">
      <header class="header">
        <h1 class="logo">Welcome to my ICQ Page</h1>
        <div class="status">Online: <span class="status-dot"></span></div>
      </header>

      <main class="content">
        <section class="left">
          <img src="/assets/dancing.gif" alt="dancing GIF" class="gif" />
          <nav class="links">
            <a href="#about">About Me</a>
            <a href="#guestbook">Guestbook</a>
            <a href="#links">Links</a>
          </nav>
        </section>

        <section class="right">
          <article id="about">
            <h2>About Me</h2>
            <p>
              I used to hang out on ICQ. Nostalgia project: building this page
              to remember the dial-up days.
            </p>
          </article>

          <article id="guestbook" class="guestbook">
            <h2>Guestbook</h2>
            <form
              id="guest-form"
              action="https://formspree.io/f/YOUR_FORM_ID"
              method="POST"
            >
              <input type="text" name="name" placeholder="Your name" required />
              <textarea
                name="message"
                placeholder="Write a message"
                required
              ></textarea>
              <button type="submit">Sign Guestbook</button>
            </form>
            <div id="guest-entries"></div>
          </article>

          <div class="counter">
            Hits: <img id="hit-counter" src="" alt="hit counter" />
          </div>
        </section>
      </main>

      <footer class="footer">
        Made with nostalgia • <small>© 2003 → 2025</small>
      </footer>
    </div>

    <script src="script.js"></script>
  </body>
</html>

Notes:

  • Replace the Formspree endpoint with your own Formspree form ID (see Formspree setup below).
  • The hit counter image will be generated by CountAPI via JavaScript.

CSS: retro look with modern layout (styles.css)

:root {
  --accent: #00cc66; /* ICQ-ish green */
  --bg: #0f0f1a;
  --glass: rgba(255, 255, 255, 0.04);
  --mono: 'VT323', monospace;
}
@import url('https://fonts.googleapis.com/css2?family=VT323&family=Press+Start+2P&display=swap');

* {
  box-sizing: border-box;
}
html,
body {
  height: 100%;
  margin: 0;
  background: url('/assets/tile.png');
  font-family: var(--mono);
  color: #f0f0f5;
}
.page-frame {
  max-width: 980px;
  margin: 20px auto;
  padding: 12px;
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.02),
    rgba(0, 0, 0, 0.06)
  );
  border: 2px solid rgba(255, 255, 255, 0.03);
}
.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px;
}
.logo {
  font-family: 'Press Start 2P', monospace;
  font-size: 18px;
  margin: 0;
  color: var(--accent);
  text-shadow: 0 0 8px rgba(0, 204, 102, 0.12);
}
.status-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  background: var(--accent);
  border-radius: 50%;
  box-shadow: 0 0 8px var(--accent);
}
.content {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 16px;
  padding: 12px;
}
.left {
  padding: 8px;
}
.right {
  padding: 8px;
}
.gif {
  display: block;
  max-width: 100%;
  border: 2px dashed rgba(255, 255, 255, 0.06);
}
.links a {
  display: block;
  padding: 6px 4px;
  color: #fff;
  text-decoration: none;
  border-bottom: 1px dotted rgba(255, 255, 255, 0.03);
}
.guestbook form {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
input,
textarea {
  background: var(--glass);
  border: 1px solid rgba(255, 255, 255, 0.04);
  color: #fff;
  padding: 8px;
}
button {
  background: var(--accent);
  color: #001;
  border: none;
  padding: 8px;
  font-weight: bold;
}
.counter {
  margin-top: 12px;
}
.footer {
  text-align: center;
  padding: 10px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.6);
}

/* Retro marquee effect */
.marquee {
  overflow: hidden;
  white-space: nowrap;
}
.marquee span {
  display: inline-block;
  padding-left: 100%;
  animation: marquee 12s linear infinite;
}
@keyframes marquee {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-100%);
  }
}

/* Responsive */
@media (max-width: 720px) {
  .content {
    grid-template-columns: 1fr;
  }
}

Notes:

  • We use Google Fonts to get retro or pixel fonts.
  • Background tile tile.png is a small 40–80px repeating PNG in /assets.

JavaScript: hit counter and simple enhancements (script.js)

We’ll use CountAPI to provide an image-based hit counter. CountAPI is simple and great for static sites.

CountAPI docs: https://countapi.xyz

// script.js
// 1) Hit counter (image) using CountAPI
const namespace = 'my-icq-page-example';
const key = 'hits';
const img = document.getElementById('hit-counter');

// Construct a URL that returns an image (you can customize style manually)
// We'll hit the endpoint to increment and display the count as text in an img as fallback.
fetch(`https://api.countapi.xyz/hit/${namespace}/${key}`)
  .then(r => r.json())
  .then(data => {
    const count = data.value;
    // Create a small data-URL PNG with the number, or use a simple fallback image generator.
    // Simpler: use a number overlay via CSS. For demo, we'll set alt text and display number elsewhere.
    img.src = `https://via.placeholder.com/120x24.png?text=Hits+${count}&bg=000000&fg=00cc66`;
  })
  .catch(err => console.error('CountAPI error', err));

// 2) Simple guestbook display: if you want public entries, use a third-party API (Sheet.best / Sheety / Firebase)
// For this template we just attach a success message to the Formspree form.
const form = document.getElementById('guest-form');
if (form) {
  form.addEventListener('submit', e => {
    // Let Formspree handle the POST; show a friendly message.
    setTimeout(() => {
      alert('Thanks for signing the guestbook!');
    }, 400);
  });
}

// 3) Optional: small blinking text using class toggle
setInterval(() => {
  document
    .querySelectorAll('.logo')
    .forEach(
      el => (el.style.opacity = el.style.opacity === '0.6' ? '1' : '0.6')
    );
}, 900);

Notes:

  • Replace namespace and key with a unique name to avoid collisions. See CountAPI docs.

Guestbook options (private and public)

  1. Quick (email-based) - Formspree - form posts to Formspree and you receive an email notification. Set your form action to the Formspree URL.

  2. Public guestbook (stored) - Sheet.best or Sheety let you turn a Google Sheet into a REST API so you can POST and GET messages.

  3. Robust - Firebase Realtime Database or Firestore - display entries live and store them in a DB. This requires a Firebase project but is great for a persistent, searchable guestbook.

  4. Git-based - Staticman writes comments to your Git repo (works well for GitHub Pages) but requires more setup.

Choose based on whether you want messages publicly displayed or just emailed to you.


Hosting: where to put your page

If you use Formspree or CountAPI, you can host completely static. For a public guestbook with a write API you might pick Netlify Functions or Firebase.


Authentic extras (but modern-friendly)

  • Background music - Use an
<button id="play-music">Play Theme</button>
<audio id="bg-audio" src="/assets/retro-loop.mp3" preload="none"></audio>
<script>
  document.getElementById('play-music').addEventListener('click', () => {
    document.getElementById('bg-audio').play();
  });
</script>
  • Marquee - avoid deprecated

  • Blinking/flashing - prefer subtle CSS animations over

  • Pixel art icons and badges - make small PNGs (32px–64px) or use SVG for crisp scaling.


Accessibility & performance tips

  • Keep contrast high and text readable. Use real text (not text-in-images) for accessibility.
  • Optimize GIFs - reduce frames and colors, or use looping MP4 for large animations.
  • Don’t autoplay audio; always provide a clear stop/pause control.
  • Provide alt attributes for images and gifs.
  • Mobile-friendly - stack columns on small screens (example CSS includes responsive grid).

Example enhancements and ideas

  • Add a modern social section (Twitter/X, Mastodon) alongside ICQ UIN as a wink to old and new.
  • Create a theme toggle - classic (dithered tile + neon) vs. modern (clean) - store preference in localStorage.
  • Archive your old HTML if you have it - include a “revisited” toggle that swaps in the original markup inside an iframe.

Resources and references


Final checklist before you publish

  • Replace demo endpoints (Formspree ID, CountAPI namespace/key) with your own.
  • Compress GIFs and images.
  • Add favicon and social preview image if you plan to share.
  • Test on mobile and desktop.
  • Consider a license or attribution for any copyrighted GIFs or music.

Recreating your ICQ web pages is as much about the feel as the code. Use the templates above to capture the aesthetic, then personalize with your own content, badges, and a story. Have fun bringing a bit of the dial-up era into a modern static site that you can keep online forever.

Back to Blog

Related Posts

View All Posts »
Reviving the IBM PC AT: A Retro Tech Restoration Guide

Reviving the IBM PC AT: A Retro Tech Restoration Guide

A complete, step-by-step restoration guide for the IBM PC AT (5170-era and compatibles). Covers inspection, cleaning, power supply and capacitor work, floppy/HDD modernization, keyboard/video adapters, networking, software transfer and sourcing vintage parts.

Revisiting the Amiga 500: A Time Capsule for Modern Game Developers

Revisiting the Amiga 500: A Time Capsule for Modern Game Developers

The Amiga 500 packed custom chips and a creative community that squeezed extraordinary games and demos from modest hardware. Modern indie developers can learn from Amiga techniques-bitplanes, blitter-driven blits, copper timing, tracker music and constraint-led design-to build efficient, memorable games today.

The Atari ST: Redefining Retro Gaming for Modern Developers

The Atari ST: Redefining Retro Gaming for Modern Developers

The Atari ST's unique blend of CPU-driven graphics, a 512-color palette, and a 3-channel PSG plus MIDI connectivity shaped a generation of distinctive games. This article explores the ST's architecture, the creative techniques it forced on developers, and how modern devs can revive ST-style graphics and sound to make retro-inspired games that resonate with today's players.