Text Counter

Simple Text-Based Hit Counter Script

Text Counter is a lightweight CGI script that outputs page visit counts as plain text, allowing complete styling freedom through CSS. Unlike graphical counters, it doesn't generate images - just a number you can style however you want.

Free Download
Version 2.0
Perl CGI

Overview

Text Counter is a minimalist alternative to graphical hit counters. Instead of generating an image with digit graphics, it simply outputs the current count as plain text. This gives webmasters complete control over how the counter appears using standard HTML and CSS styling.

The script maintains a simple data file that stores the current count, incrementing it each time the page is loaded. It's designed to work with Server Side Includes (SSI), embedding the count directly into HTML output.

Key Benefits
  • No GD library required
  • Full CSS styling control
  • Lower server overhead
  • Faster page loads
  • Multiple counters per site
  • Easy customization

Historical Context

Text Counter emerged as an elegant solution to several problems webmasters faced with graphical counters in the mid-1990s:

"The primary advantage of a text counter is simplicity. With no graphics library dependencies and minimal server resources, it was often the only option on restrictive shared hosting."

Why Text Counters Existed
  • Server Limitations: Many shared hosts didn't have GD or ImageMagick libraries installed
  • Performance: Generating images for every page view was resource-intensive
  • Design Flexibility: Webmasters wanted counters that matched their site's typography
  • Bandwidth: Text output was measured in bytes; images were kilobytes
The Counter Era Timeline
1994First CGI counters appear on the web
1995Popular CGI script archives emerge with Counter scripts
1996-1999Peak hit counter era - nearly every personal site had one
2000Free counter services emerge (WebCounter, StatCounter)
2005+Analytics tools replace simple counters
2010+Google Analytics dominates; counters become nostalgic
Did You Know?

Hit counters were a status symbol in the 1990s web. A high visitor count signified popularity and credibility.

Some webmasters would start their counters at high numbers (like 10,000) to appear more established.

The phrase "You are visitor number X" became an iconic element of early web design.

Features

Pure Text Output

Outputs just the number - no images, no HTML tags. You control all styling with your own CSS.

Minimal Overhead

No image generation means faster execution and lower server resource usage.

Multiple Counters

Track different pages independently by specifying different data files.

No Dependencies

Works on any server with Perl - no graphics libraries or modules required.

File Locking

Prevents count corruption from simultaneous visitors using file locking.

Styling Freedom

Use any font, size, color, or effect available in CSS to display your count.

Text vs Graphical Counters

Feature Text Counter Graphical Counter
Output Format Plain text number GIF/PNG image
Server Requirements Just Perl Perl + GD/ImageMagick
Response Size ~10-20 bytes ~2-5 KB per image
Styling Control Full CSS control Limited to digit styles
Digit Themes Use any web font Pre-made digit images
Caching Cannot be cached Image can be cached
Accessibility Screen reader friendly Requires alt text
Copy/Paste Yes No

Installation

  1. Upload the Script
    Upload textcounter.pl to your cgi-bin directory.
  2. Configure Perl Path
    Edit the first line if needed: #!/usr/bin/perl
  3. Set Data File Path
    Configure the path where count data will be stored.
  4. Set Permissions
    chmod 755 textcounter.pl and chmod 666 counter.dat
  5. Enable SSI
    Ensure your server parses SSI (files may need .shtml extension).
  6. Add to Your Page
    Add the SSI directive where you want the counter displayed.

Code Examples

Basic SSI Include
<!-- Simple counter -->
<!--#exec cgi="/cgi-bin/textcounter.pl"-->

<!-- With styling -->
You are visitor number <strong><!--#exec cgi="/cgi-bin/textcounter.pl"--></strong>

<!-- With custom CSS -->
<span class="visitor-count"><!--#exec cgi="/cgi-bin/textcounter.pl"--></span>

<style>
.visitor-count {
    font-size: 2rem;
    font-family: 'Courier New', monospace;
    color: #00ff00;
    background: #000;
    padding: 5px 15px;
    border-radius: 5px;
}
</style>

<!-- Multiple counters for different pages -->
<!--#exec cgi="/cgi-bin/textcounter.pl?page=home"-->
<!--#exec cgi="/cgi-bin/textcounter.pl?page=about"-->
Modern Perl Implementation
#!/usr/bin/perl
use strict;
use warnings;
use Fcntl qw(:flock);

# Configuration
my $count_file = '/path/to/counter.dat';

# Initialize count
my $count = 0;

# Read and increment counter
if (open(my $fh, '+<', $count_file)) {
    flock($fh, LOCK_EX);
    $count = <$fh> || 0;
    chomp($count);
    $count++;
    seek($fh, 0, 0);
    truncate($fh, 0);
    print $fh "$count\n";
    close($fh);
}
elsif (open(my $fh, '>', $count_file)) {
    $count = 1;
    print $fh "1\n";
    close($fh);
}

# Output
print "Content-type: text/plain\n\n";
print $count;

exit 0;
PHP Equivalent
<?php
/**
 * Text Counter - PHP Version
 * Simple text-based hit counter
 */

$count_file = __DIR__ . '/counter.txt';

// Read current count
$count = 0;
if (file_exists($count_file)) {
    $count = (int) file_get_contents($count_file);
}

// Increment
$count++;

// Save (with file locking)
$fp = fopen($count_file, 'w');
if (flock($fp, LOCK_EX)) {
    fwrite($fp, $count);
    flock($fp, LOCK_UN);
}
fclose($fp);

// Output plain text
header('Content-Type: text/plain');
echo $count;
?>
PHP Inline Usage
<?php
// Inline counter function
function getVisitorCount($file = 'counter.txt') {
    $count = file_exists($file) ? (int) file_get_contents($file) : 0;
    $count++;
    file_put_contents($file, $count, LOCK_EX);
    return $count;
}
?>

<!-- Usage in HTML -->
<p>You are visitor number <strong><?= number_format(getVisitorCount()) ?></strong></p>
JavaScript Counter Display
/**
 * Client-side counter display with number animation
 * Note: Actual counting must happen server-side
 */

class AnimatedCounter {
    constructor(element, targetValue, options = {}) {
        this.element = document.querySelector(element);
        this.target = targetValue;
        this.options = {
            duration: 2000,
            separator: ',',
            ...options
        };
        this.animate();
    }

    animate() {
        const start = 0;
        const startTime = performance.now();

        const updateCounter = (currentTime) => {
            const elapsed = currentTime - startTime;
            const progress = Math.min(elapsed / this.options.duration, 1);

            // Easing function
            const easeOut = 1 - Math.pow(1 - progress, 3);

            const currentValue = Math.floor(start + (this.target - start) * easeOut);
            this.element.textContent = currentValue.toLocaleString();

            if (progress < 1) {
                requestAnimationFrame(updateCounter);
            }
        };

        requestAnimationFrame(updateCounter);
    }
}

// Usage: Fetch count from server and animate
fetch('/api/counter')
    .then(response => response.text())
    .then(count => {
        new AnimatedCounter('#visitor-count', parseInt(count));
    });

Modern Alternatives (2024)

While hit counters served their purpose in the 1990s, modern websites typically use analytics tools that provide much more insight than a simple number:

Privacy-Focused Analytics
  • Plausible Analytics From $9/mo

    Lightweight, privacy-friendly, no cookies, GDPR compliant. Open source and can be self-hosted.

  • Umami Free / Open Source

    Self-hosted, privacy-focused, simple and fast. Modern alternative to Google Analytics.

  • Fathom Analytics From $14/mo

    Cookie-free, GDPR compliant, beautiful dashboard. Used by GitHub, IBM.

  • GoatCounter Free for personal

    No tracking, no cookies, minimal JavaScript. Truly privacy-focused.

Simple Counter Services
  • StatCounter Free tier available

    One of the oldest counter services still running. Includes invisible counter option.

  • Counter.dev Free / Open Source

    Simple, privacy-first analytics. No cookies, no tracking.

  • hit-counter (GitHub) Free / Open Source

    Badge-style hit counter for GitHub READMEs and websites.

  • Visitor Badge Free

    Simple visitor badge for markdown files and websites.

Feature Comparison
Feature Text Counter (1990s) Modern Analytics (2024)
Total page views
Unique visitors
Geographic data
Referrer tracking
Real-time data
No external dependencies Self-hosted only
Visible counter on page Optional widget

Download

Compressed Archives
  • textcounter.tar.gz 2.1 KB
  • textcounter.zip 2.4 KB
  • textcounter.tar.Z 3.0 KB
Package Contents
  • textcounter.pl

    Main Perl script that outputs the counter value

  • README

    Installation and configuration instructions

Frequently Asked Questions

Text Counter outputs just a number as plain text, which you can style with CSS. Graphical Counter generates an image with stylized digit graphics. Text Counter is lighter and more flexible for styling; Graphical Counter offers pre-designed visual themes.

The basic script outputs a raw number. To add comma formatting, modify the script to use Perl's number formatting: $count =~ s/(\d)(?=(\d{3})+(\D|$))/$1,/g; or use JavaScript after the fact with parseInt(num).toLocaleString().

Yes, simply edit the counter data file and enter your starting number. Some webmasters started their counters at higher numbers to appear more established - a common practice in the 1990s.

Common issues: (1) Data file permissions - must be writable by the web server (chmod 666), (2) SSI not enabled - check server configuration, (3) Path errors - verify the cgi-bin path and data file location, (4) File locking issues - ensure the script can acquire locks.

Yes, modern analytics tools like Plausible, Umami, or even simple services like Counter.dev provide much more information than a hit counter while respecting visitor privacy. If you just want a visible count badge, services like visitor-badge or hit-counter on GitHub work well.

Resources

Back to Scripts