The official website for the Invisible Internet Project (I2P), built with Hugo.
# Clone the repository
git clone https://github.com/i2p/i2p.www.git
cd i2p.www
# Install Hugo (v0.147.8+ required)
# macOS: brew install hugo
# Linux: snap install hugo
# Run development server
hugo server -D
# Build for production
hugo --minifyi2p.www/
├── assets/css/ # Main stylesheet (main.css)
├── content/ # Markdown content by language
│ ├── en/ # English (source language)
│ ├── de/ # German
│ ├── es/ # Spanish
│ ├── fr/ # French
│ └── ... # 13 languages total
├── data/ # Data files (downloads.yaml, etc.)
├── i18n/ # UI translation strings
├── layouts/ # Hugo templates
├── scripts/ # Utility scripts
│ ├── i2p_tools.sh # Interactive tool menu
│ ├── tools/ # Content management tools
│ └── translate/ # Translation automation
├── static/ # Static assets (images, fonts, etc.)
└── tests/ # Python test suite
| Code | Language | Status |
|---|---|---|
| en | English | Source |
| de | Deutsch | Translated |
| es | Español | Translated |
| fr | Français | Translated |
| ru | Русский | Translated |
| zh | 中文 | Translated |
| ko | 한국어 | Translated |
| ar | العربية | Translated |
| pt | Português | Translated |
| vi | Tiếng Việt | Translated |
| hi | हिन्दी | Translated |
| cs | Čeština | Translated |
| tr | Türkçe | Translated |
Run the interactive tools menu:
./scripts/i2p_tools.shThis provides a menu-driven interface for common tasks:
╔════════════════════════════════════════╗
║ I2P Website Tools ║
╚════════════════════════════════════════╝
What would you like to do?
1) Update Site Banner
2) Add Research Paper
3) Add Media/Press Entry
4) Add Proposal
5) Exit
Updates the notification banner shown at the top of all pages:
./scripts/tools/update_banner.shThe banner configuration is stored in hugo.toml and content in i18n/*.toml files.
Adds a new research paper to the papers section:
./scripts/tools/add_paper.shPrompts for paper details (title, authors, year, abstract, PDF URL) and creates entries in all language files.
Adds a new media mention or press coverage:
./scripts/tools/add_media.shCreates a new I2P proposal with interactive editing and preview:
./scripts/tools/add_proposal.shFeatures:
- Interactive prompts for proposal metadata (number, title, author, status, etc.)
- Live preview using Hugo server
- Generates both
.md(Hugo content) and.txt(RST source) files - Validates proposal number uniqueness
- Supports all proposal statuses (Open, Closed, Rejected, Draft, etc.)
Located in scripts/translate/:
translate_claude_batch.py- Batch translation using Claude APItranslate_openai_batch.py- Batch translation using OpenAI APItranslate_openai_realtime.py- Real-time translation using OpenAIci_translate.sh- CI/CD translation automation
- Hugo Extended v0.147.8+
- Python 3.11+ (for tests)
- Node.js (optional, for some optimizations)
# Install test dependencies
pip install -r tests/requirements.txt
# Run all tests
pytest tests/
# Run specific test file
pytest tests/test_links.py
# Run with verbose output
pytest tests/ -v- Config validation - Hugo configuration integrity
- Downloads - Download links and checksums
- Front matter - Markdown metadata validation
- HTML output - Generated HTML structure
- i18n consistency - Translation key completeness
- Links - Internal and external link validation
- Static assets - Asset file integrity
- Accessibility - Basic a11y checks
- Build performance - Size and page count metrics
- Translation completeness - Cross-language content parity
# Start with drafts enabled
hugo server -D
# Start with specific port
hugo server -p 1314
# Start with live reload disabled
hugo server --disableLiveReloadThe site uses GitHub Actions for CI/CD:
- Build - Hugo builds the site with minification
- Test - Python test suite validates output
- Optimize - SVG optimization and WebP conversion
- Deploy - Cloudflare Pages deployment
# Production build
hugo --minify --gc
# Output is in public/Key configuration options:
# Banner settings
[params.banner]
enabled = true
dismissible = true
id = "banner-3" # Auto-incremented by i2p_tools.sh
# Poll settings
[params.poll]
enabled = true
pollId = "2"Note: Do not manually edit banner or poll settings. Use
./scripts/i2p_tools.shwhich automatically handles ID increments and updates all language files.
Contains all download links, versions, and checksums for I2P releases.
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Make your changes
- Run tests (
pytest tests/) - Commit your changes
- Push to the branch (
git push origin feature/my-feature) - Open a Pull Request
- Only create/edit files in
content/en/- English is the source language - Translations are automatically generated by the CI/CD pipeline when new English content is detected
- The pipeline will translate new content and commit it to the repository automatically
- Use frontmatter for metadata (title, description, date)
- Images go in
static/images/