Create professional WiFi access cards, stickers, and information sheets with scannable QR codes.
Manage multiple wireless networks, generate printable materials in 16 languages, and share credentials securely — all from your browser, no account required.
- Unlimited WiFi networks stored locally in your browser (IndexedDB)
- Support for Open, WPA/WPA2/WPA3 PSK, and WPA2/WPA3 Enterprise (EAP) networks
- EAP configuration: PEAP, TLS, TTLS, LEAP, PWD with Phase 2 authentication
- PSK password validation enforcing WPA standard (8–63 characters)
- Tags — organize networks with multiple tags (e.g. building, floor, department); collapsible groups in the overview with per-group print and share actions
- Search, edit, duplicate, and organize your networks
- Information Sheets (A4) — full-page layout with large QR code, ideal for laminating
- Stickers — compact 2-per-row layout, cut along dashed borders
- Cards — credit card size (85.6 x 54mm), perfect for laminated handouts
- Connection guide — optional illustrated step-by-step instructions on information sheets (open camera → scan QR → tap notification → connected)
- Real-time print preview with layout selection
- Direct printing via browser (suppressed headers/footers)
- PDF download — generates actual PDF files with embedded metadata (author, title, keywords), page breaks per network
- 16 languages: English, Deutsch, Francais, Espanol, Italiano, Portugues, Turkce, Polski, Russkij, Arabic, Chinese, Japanese, Korean, Georgian, Thai, Vietnamese
- Separate UI language and print language settings
- Multi-language printouts: information sheets stack labels vertically per language; stickers and cards generate one per language per network
- Auto-detects browser language with fallback to English
- Share via link — encode one or all networks into a URL fragment
- Password protection — AES-256-GCM encryption with PBKDF2 key derivation (310,000 iterations, SHA-256)
- All cryptography runs client-side via the Web Crypto API — no data leaves the browser
- URL length monitoring with warnings when exceeding safe browser limits
- Import shared credentials with one click; decryption prompt for password-protected links
- Install on any device — desktop, tablet, or phone
- Works fully offline after first load (Service Worker with Workbox precaching)
- Auto-updates via
skipWaiting+clientsClaim - Translation files cached with StaleWhileRevalidate strategy
- Node.js 24+ (see
.nvmrc) - npm (comes with Node.js)
# Clone the repository
git clone https://github.com/bauer-group/COM-WiFiAccessCardGenerator.git
cd COM-WiFiAccessCardGenerator
# Install dependencies
npm install
# Start development server
npm run devOpen http://localhost:5173 in your browser.
# Type-check and build for production
npm run build
# Preview the production build locally
npm run previewThe app supports three deployment targets. The BASE_URL environment variable controls where the app expects its assets — it defaults to / (root) and only needs to be changed for GitHub Pages without a custom domain.
| Scenario | BASE_URL | URL |
|---|---|---|
Local dev (npm run dev) |
/ (default) |
http://localhost:5173/ |
Docker (docker compose up) |
/ (default) |
http://localhost:8080/ |
| GitHub Pages + custom domain | / (default) |
https://wifi-access-cards.app.bauer-group.com |
| GitHub Pages without custom domain | /COM-WiFiAccessCardGenerator/ |
https://bauer-group.github.io/COM-WiFiAccessCardGenerator/ |
Deployments are automated via GitHub Actions. Push to main and the workflow builds and deploys.
Setup:
- Repository Settings > Pages > Source > GitHub Actions
- Repository Settings > Pages > Custom domain >
wifi-access-cards.app.bauer-group.com - DNS: CNAME record pointing to
bauer-group.github.io
No BASE_URL configuration needed — the default / is correct for custom domains.
If no custom domain is configured, assets must be served from the repository subpath. Add the BASE_URL env to the build step in .github/workflows/deploy-pages.yml:
- name: Build
run: npm run build
env:
BASE_URL: '/COM-WiFiAccessCardGenerator/'# Build and run
docker compose up -d
# Access at http://localhost:8080The Docker setup includes:
- Multi-stage build (Node.js > Nginx Alpine)
- Read-only root filesystem with minimal capabilities (
cap_drop: ALL) - Resource limits (256MB memory, 1 CPU)
- Security headers (CSP, X-Frame-Options, HSTS-ready)
- Health check endpoint at
/health - Gzip compression and optimized caching
- Non-root Nginx user
| Layer | Technology |
|---|---|
| Framework | React 19 + TypeScript 5.8 |
| Build | Vite 8 (Rolldown) + SWC |
| Styling | Tailwind CSS 4 |
| Components | Radix UI primitives |
| Icons | Lucide React |
| Database | Dexie.js 4 (IndexedDB wrapper) |
| i18n | i18next with browser language detection |
| QR Codes | qrcode.react |
| jsPDF + html2canvas-pro (lazy-loaded) | |
| PWA | vite-plugin-pwa + Workbox |
| Crypto | Web Crypto API (PBKDF2 + AES-256-GCM) |
| Server | Nginx Alpine (Docker) |
src/
components/ # React components
ui/ # Radix-based design system (Button, Dialog, Select, ...)
NetworkCard.tsx # Network list item with QR code and actions
NetworkForm.tsx # Add/edit network form with validation
PrintView.tsx # Print layouts (Sheet, Sticker, Card)
PrintDialog.tsx # Print preview + PDF generation
ShareDialog.tsx # Share link generation with encryption
ImportDialog.tsx # Import shared credentials
SettingsPanel.tsx
context/ # Theme context (light/dark/system)
db/ # Dexie database schema and operations
utils/
crypto.ts # AES-256-GCM encryption/decryption
share.ts # Share link encoding/decoding
wifi-qr.ts # WIFI: URI scheme generation
print-labels.ts # Static print labels for all 16 languages
i18n.ts # i18next configuration
types/ # TypeScript type definitions
public/
locales/ # Translation files (16 languages)
icon-*.png # PWA icons
| Command | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
Type-check and build for production |
npm run preview |
Preview production build |
npm run test |
Run tests in watch mode |
npm run test:run |
Run tests once |
npm run test:coverage |
Run tests with coverage report |
npm run type-check |
TypeScript type checking |
npm run generate-icons |
Generate PWA icons from SVG |
npm run clean |
Remove dist and Vite cache |
- No server, no tracking — all data stays in your browser's IndexedDB
- Encryption — shared links can be protected with AES-256-GCM (PBKDF2 310k iterations)
- CSP headers — Content Security Policy configured in Nginx
- Docker hardening — read-only filesystem, dropped capabilities, no-new-privileges
- Dependency auditing —
npm auditruns clean with zero vulnerabilities
This project follows the BAUER GROUP Corporate Identity guidelines:
- Primary color: BAUER Orange
#FF8500 - Typography: System font stack
- Warm gray palette:
#F9F8F6to#231F1C
MIT © 2026 BAUER GROUP