A nostalgic Web 2.0 social directory service with a retro aesthetic inspired by the golden age of the internet (2000s). Browse, search, and submit websites in a delightfully vintage interface complete with visitor counters, rotating buttons, and glitch effects.
- Retro Web 2.0 Design: Nostalgic UI inspired by GeoCities, Wiby, and early web directories
- Site Directory: Browse websites organized by categories (Art, Web Dev, Gaming, etc.)
- Search Engine: Terminal-style search functionality with real-time results
- Site Submission: Submit your own websites to the directory with form validation
- Button Rotator: Classic 88x31 button carousel widget
- Visitor Counter: Retro hit counter with glitch animation effects
- Popup Ads: Parody retro advertisements (non-intrusive)
- Loading Screen: Classic progress bar loading animation
- Easter Eggs: Hidden features like Konami code admin console
- Responsive Design: Works beautifully on desktop, tablet, and mobile devices
- RESTful API: Full backend API for site management
- Helmet.js security headers
- Rate limiting (100 requests/15min, 10 submissions/15min)
- Input validation and sanitization
- SQL injection protection
- CORS configuration
- XSS prevention
- Node.js (v14 or higher)
- PostgreSQL database (Neon recommended)
- npm or yarn
- Clone the repository
git clone https://github.com/yourusername/the-underweb.git
cd the-underweb- Install dependencies
npm install- Set up environment variables
cp backend/.env.example backend/.envEdit backend/.env and add your database credentials:
DATABASE_URL=postgresql://user:password@host:5432/dbname?sslmode=require
PORT=3000
NODE_ENV=development
CORS_ORIGIN=http://localhost:3000- Start the server
npm startThe application will be available at http://localhost:3000
npm run devThis uses nodemon for auto-restart on file changes.
the-underweb/
βββ backend/
β βββ server.js # Express server with API routes
β βββ .env # Environment variables (not in git)
β βββ .env.example # Environment template
βββ public/
β βββ index.html # Main HTML file
β βββ css/
β β βββ style.css # Responsive styles
β βββ js/
β βββ script.js # Main application logic
β βββ search.js # Search functionality
β βββ submit.js # Form submission handler
β βββ counter.js # Visitor counter
β βββ rotator.js # Button rotator widget
βββ .github/
β βββ workflows/
β βββ neon.yaml # GitHub Actions for Neon DB
βββ .gitignore
βββ package.json
βββ README.md
CREATE TABLE IF NOT EXISTS sites (
id SERIAL PRIMARY KEY,
url TEXT NOT NULL UNIQUE,
title TEXT NOT NULL,
description TEXT,
category VARCHAR(50),
button_url TEXT,
submitted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
status VARCHAR(20) DEFAULT 'pending'
);art- Pixel Art & Graphicsweb- Web Developmentnostalgia- Web Nostalgiacode- Code & Programminggaming- Retro Gamingother- Miscellaneous
Submit a new site to the directory.
Request Body:
{
"url": "https://example.com",
"title": "Example Site",
"description": "A cool retro website",
"category": "web",
"buttonUrl": "https://example.com/button.gif"
}Response: 201 Created
{
"message": "Site submitted successfully.",
"id": 123
}Get all submitted sites with optional filtering and pagination.
Query Parameters:
category- Filter by category (optional)status- Filter by status (optional)limit- Number of results (default: 100)offset- Pagination offset (default: 0)
Response: 200 OK
{
"sites": [
{
"id": 1,
"url": "https://example.com",
"title": "Example Site",
"description": "A cool retro website",
"category": "web",
"button_url": "https://example.com/button.gif",
"submitted_at": "2025-01-15T10:30:00Z",
"status": "pending"
}
],
"count": 1
}Get a specific site by ID.
Response: 200 OK
{
"id": 1,
"url": "https://example.com",
"title": "Example Site",
...
}Health check endpoint for monitoring.
Response: 200 OK
{
"status": "healthy",
"database": "connected",
"timestamp": "2025-01-15T10:30:00Z"
}| Variable | Description | Default |
|---|---|---|
DATABASE_URL |
PostgreSQL connection string | (required) |
PORT |
Server port | 3000 |
NODE_ENV |
Environment (development/production) | development |
CORS_ORIGIN |
Allowed CORS origins | http://localhost:3000 |
DEBUG |
Enable debug logging | false |
To allow multiple origins, use a comma-separated list:
CORS_ORIGIN=http://localhost:3000,https://yoursite.com- Set environment variables
export NODE_ENV=production
export DATABASE_URL=your_production_database_url
export PORT=3000- Build and start
npm start- Set environment variables in your platform's dashboard
- Configure build command:
npm install - Configure start command:
npm start - Set publish directory:
public
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]- Start the server:
npm start - Open http://localhost:3000 in your browser
- Test the following features:
- Browse directory listings
- Search for sites
- Submit a new site
- Check visitor counter
- Try the button rotator
- Test on mobile devices
# Health check
curl http://localhost:3000/api/health
# Submit a site
curl -X POST http://localhost:3000/api/sites \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com","title":"Test Site","category":"web"}'
# Get all sites
curl http://localhost:3000/api/sites- Verify
DATABASE_URLis correct in.env - Check network connectivity to database
- Ensure SSL mode is properly configured
# Find process using port 3000
lsof -i :3000
# Kill the process
kill -9 <PID>
# Or use a different port
PORT=3001 npm start- Update
CORS_ORIGINin.envto match your frontend URL - Check browser console for specific CORS error messages
- Ensure protocol (http/https) matches
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Use 2 spaces for indentation
- Follow existing code patterns
- Add comments for complex logic
- Test your changes before committing
This project is licensed under the MIT License - see the LICENSE file for details.
- Inspired by early web directories like Wiby, Peelopaalu, and GeoCities
- Nostalgic design elements from the Web 2.0 era
- Community contributors and testers
For issues, questions, or suggestions:
- Open an issue on GitHub
- Check existing issues for solutions
- Review the troubleshooting section
- User authentication and profiles
- User-submitted ratings and reviews
- RSS feed support
- WebRing functionality
- Admin moderation dashboard
- Email notifications
- API key system for developers
- Site uptime monitoring
- Advanced search with filters
- Tagging system
- Social sharing features
- Dark mode toggle
- Internationalization (i18n)
Current Version: 1.0.0 Status: Production Ready β Last Updated: January 2025
Built with β€οΈ and nostalgia for the early web.