QR Local is a Node.js application designed to create short, QR code-friendly URLs for local network access at the qr.local domain. It uses base32 encoding to ensure QR codes can utilize alphanumeric mode for optimal space efficiency.
- Base32 URL shortening optimized for QR codes
- QR Code Generation with configurable error correction, version, and encoding
- Visual QR codes displayed in browse interface with click-to-download
- Multiple download formats (PNG and SVG)
- Configurable ID length to control QR code versions
- SQLite database for persistent storage
- Visit tracking with statistics
- Custom keys for predictable short URLs
- RESTful API for programmatic access
- Web interface for human-friendly management
- Delete functionality with confirmation
- Clone or download this repository
- Install dependencies:
npm install
- Start the server:
node index.js [base32_length] [options]
Command Line Arguments:
base32_length- Maximum length for base32 IDs (1-20, default: 6)
QR Code Options:
-e, --qr-error <L|M|Q|H>- Error correction level (default: M)-v, --qr-version <1-40>- QR code version (default: 1)-m, --qr-mode <mode>- Encoding mode: numeric, alphanumeric, byte (default: alphanumeric)-d, --qr-domain <domain>- Domain for QR code URLs (default: qr.local)-h, --help- Show help message
Usage Examples:
# Default settings (6 chars, Version 1, M error correction, alphanumeric, qr.local domain)
node index.js
# Custom base32 length with default QR settings
node index.js 10
# Custom domain for QR codes (server still runs on default port 80)
node index.js 6 -d mysite.com
# Custom domain with port in QR codes (port is just URL prefix, not server port)
node index.js 6 -d mysite.com:8080
# Server on custom port with matching domain configuration
PORT=8080 node index.js 6 -d mysite.com:8080
# High error correction with Version 2 and custom domain
node index.js 14 -e H -v 2 -d short.ly
# Full custom configuration
PORT=3000 node index.js 8 -m byte -e L -d example.org:3000Important: The --qr-domain option only affects the URLs embedded in generated QR codes. It does not change how the server operates or what port it binds to.
- QR Domain: Controls the URL prefix in QR codes (e.g.,
mysite.com/abc123) - Server Port: Set via
PORTenvironment variable (default: 80) - Server Function: Operates independently of QR domain setting
Examples:
- QR codes contain
mysite.com:8080/abc123but server runs on port 3000:PORT=3000 node index.js -d mysite.com:8080 - QR codes contain
qr.local/abc123but server runs on port 8080:PORT=8080 node index.js
Note: QR code capacity varies by version and error correction level. The domain prefix length affects available space for base32 IDs.
All API endpoints are prefixed with your server's base URL:
http://qr.local/api/
Note: For development/testing, you can use http://localhost:3000/api/
Currently, no authentication is required for API access.
Create a new URL redirect with optional custom key.
Endpoint: POST /api/add
Content-Type: application/json
Request Body:
{
"url": "https://example.com",
"key": "MYKEY23" // Optional custom key
}Success Response (201):
{
"success": true,
"qr_url": "qr.local/abc123d",
"base32_id": "abc123d",
"original_url": "https://example.com"
}Error Responses:
400- Missing or invalid URL400- Invalid custom key format409- Custom key already exists500- Database error
cURL Example:
# Auto-generate key
curl -X POST http://qr.local/api/add \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'
# Use custom key
curl -X POST http://qr.local/api/add \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "key": "GITHUB"}'Custom Key Requirements:
- 1 to
max_base32_lengthcharacters - Base32 characters only: A-Z, 2-7 (case insensitive)
- Must be unique across all redirects
Check if a URL already has a redirect and return its details.
Endpoint: GET /api/check
Query Parameters:
url(required) - The URL to check
Success Response (200) - URL Found:
{
"exists": true,
"qr_url": "qr.local/abc123d",
"base32_id": "abc123d",
"original_url": "https://example.com",
"created": "2023-12-01T10:30:00.000Z",
"visits": 5,
"last_visit": "2023-12-01T15:45:00.000Z"
}Success Response (200) - URL Not Found:
{
"exists": false,
"message": "No redirect found for this URL"
}Error Responses:
400- Missing or invalid URL parameter500- Database error
cURL Example:
curl "http://qr.local/api/check?url=https://example.com"Delete an existing redirect by its base32 ID.
Endpoint: DELETE /api/delete/:id
URL Parameters:
id(required) - The base32 ID of the redirect to delete
Success Response (200):
{
"success": true,
"message": "Redirect deleted successfully",
"deleted_id": "abc123d",
"deleted_url": "https://example.com"
}Error Responses:
404- Redirect not found500- Database error
cURL Example:
curl -X DELETE http://qr.local/api/delete/abc123dFollow a redirect to its destination URL.
Endpoint: GET /:base32id
URL Parameters:
base32id- The base32 ID of the redirect
Success Response: HTTP 302 redirect to destination URL
Error Response:
404- Redirect not found
Browser Example:
http://qr.local/abc123d
Note: This endpoint automatically increments the visit counter and updates the last visit timestamp.
Display a QR code image for a redirect.
Endpoint: GET /qr/:id/png
URL Parameters:
id- The base32 ID of the redirect
Success Response: PNG image of QR code
Error Response:
404- Redirect not found500- QR generation error
Browser Example:
http://qr.local/qr/abc123d/png
Download a QR code file for a redirect.
Endpoints:
GET /download/qr/:id/png- Download PNG formatGET /download/qr/:id/svg- Download SVG format
URL Parameters:
id- The base32 ID of the redirect
Success Response: File download with appropriate Content-Disposition headers
Error Response:
404- Redirect not found500- QR generation error
Browser Examples:
http://qr.local/download/qr/abc123d/png
http://qr.local/download/qr/abc123d/svg
Note: These endpoints trigger file downloads with filenames like qr-abc123d.png or qr-abc123d.svg.
The application provides a user-friendly web interface:
-
Add Redirect:
http://qr.local/human/add- Form to create new redirects with optional custom keys
- Real-time validation and feedback
-
Browse Redirects:
http://qr.local/human/browse- Table view of all redirects with statistics
- Visual QR codes displayed inline (80x80px)
- Click QR codes to download PNG files
- Download QR buttons for easy access
- Delete buttons with confirmation dialogs
- Sortable by creation date (newest first)
-
Add New Redirects
- URL validation
- Optional custom key input with format hints
- Success page with QR-ready URL
-
Browse All Redirects
- Complete redirect listing
- Visit statistics (count and last visit)
- One-click deletion with confirmation
- Direct links to destination URLs
-
Responsive Design
- Clean, modern interface
- Mobile-friendly layout
- Intuitive navigation
The application uses SQLite with the following schema:
CREATE TABLE redirects (
id TEXT PRIMARY KEY, -- Base32 ID
url TEXT NOT NULL, -- Destination URL
created DATETIME DEFAULT CURRENT_TIMESTAMP,
visits INTEGER DEFAULT 0, -- Visit counter
last_visit DATETIME -- Last access timestamp
);Database File: redirects.db (created automatically)
# Create short URL
curl -X POST http://qr.local/api/add \
-H "Content-Type: application/json" \
-d '{"url": "https://very-long-url.example.com/path/to/resource"}'
# Use returned qr.local/abc123d in QR codes# Check if URL already exists
curl "http://qr.local/api/check?url=https://github.com/myrepo"
# If not found, create with custom key
curl -X POST http://qr.local/api/add \
-H "Content-Type: application/json" \
-d '{"url": "https://github.com/myrepo", "key": "GITHUB"}'
# Result: qr.local/GITHUB# List all redirects (via web interface)
open http://qr.local/human/browse
# Delete specific redirect
curl -X DELETE http://qr.local/api/delete/GITHUBPORT- Server port (default: 3000)
- Base32 Length - Maximum characters for generated IDs
node index.js 10 # Max 10 character IDs
The server displays configuration on startup:
Using base32 ID length: 7 characters
QR Local server running at http://localhost:3000
Add redirects at: http://localhost:3000/human/add
Browse redirects at: http://localhost:3000/human/browse
The API uses standard HTTP status codes:
200- Success201- Created400- Bad Request (invalid input)404- Not Found409- Conflict (duplicate key)500- Internal Server Error
All error responses include a JSON object with an error field describing the issue.
qrlocal/
├── index.js # Main server file
├── package.json # Dependencies and scripts
├── redirects.db # SQLite database (auto-created)
└── README.md # This file
express- Web frameworksqlite3- Database driverbase32- Base32 encoding/decodingqrcode- QR code generation library
npm start # Start server
npm run dev # Start server (same as start)