A minimalist, responsive, and accessible URL shortener service built with Hono JS and Tailwind CSS, deployed on Cloudflare Workers.
- π URL Shortening - Shorten long URLs instantly with auto-generated or custom short codes
- π Copy to Clipboard - One-click copy for generated short URLs
- π± QR Code Generation - Generate downloadable QR codes for your shortened URLs
- π Visit Statistics - Track how many times your shortened links have been clicked
- βΏ Accessible (a11y) - WCAG 2.1 compliant with screen reader support, keyboard navigation, and reduced motion support
- π± Responsive Design - Beautiful UI that works on all devices
- β‘ Edge Deployed - Runs on Cloudflare Workers for ultra-fast global performance
- π Smart Redirects - 2-second loading screen with countdown before redirect
| Technology | Purpose |
|---|---|
| Hono | Ultra-fast web framework |
| Tailwind CSS v4 | Utility-first CSS framework |
| Vite | Build tool and dev server |
| Cloudflare Workers | Edge deployment platform |
| Vitest | Unit testing framework |
| qrcode | QR code generation |
| Plus Jakarta Sans | Typography |
# Clone the repository
git clone https://github.com/yehezkielgunawan/shortin-v3-rev.git
cd shortin-v3-rev
# Install dependencies
pnpm install# Start development server on port 3000
pnpm devThe app will be available at http://localhost:3000
# Run tests in watch mode
pnpm test
# Run tests once (CI mode)
pnpm test:ci
# Run tests with coverage report
pnpm test:coverage# Build for production
pnpm build
# Preview production build locally
pnpm cf:preview
# Deploy to Cloudflare Workers
pnpm cf:deployGenerate/synchronize types based on your Worker configuration:
pnpm cf-typegen- Enter your long URL in the input field
- (Optional) Add a custom short code
- Click "Shorten URL"
- Copy the generated short URL
- After shortening a URL, click the "Generate QR Code" button
- The QR code will be displayed with the shortened URL below it
- Click "Download QR Code" to save it as a PNG image
Visit https://shortin-api.yehezgun.com/{shortCode} to be redirected to the original URL.
The app proxies requests to the backend API through /api/* routes.
POST /api/shorten
Content-Type: application/json
{
"url": "https://www.example.com/some/long/url",
"shortCodeInput": "custom-code" // optional
}Response (201)
{
"id": "id_1620000000000_1234",
"url": "https://www.example.com/some/long/url",
"shortCode": "custom-code",
"createdAt": "2024-01-01T00:00:00.000Z",
"updatedAt": "2024-01-01T00:00:00.000Z",
"count": 0
}GET /api/{shortCode}Response (200)
{
"url": "https://www.example.com/some/long/url"
}GET /api/{shortCode}/statsResponse (200)
{
"count": 42
}PUT /api/{shortCode}
Content-Type: application/json
{
"url": "https://www.example.com/new/url"
}Response (200)
{
"message": "Short code updated successfully"
}DELETE /api/{shortCode}Response (200)
{
"message": "Short code deleted successfully"
}| Status | Response |
|---|---|
| 400 | { "error": "URL is required" } |
| 400 | { "error": "Short code already in use" } |
| 404 | { "error": "Short code not found" } |
| 500 | { "error": "Failed to shorten URL" } |
shortin-v3-rev/
βββ src/
β βββ client/ # Client-side hydration scripts
β β βββ main.tsx # Main page hydration
β β βββ redirect.tsx # Redirect page hydration
β βββ components/ # JSX Components
β β βββ ShortenForm.tsx
β β βββ RedirectPage.tsx
β βββ lib/ # Shared utilities
β β βββ formReducer.ts
β β βββ qrcode.ts # QR code generation utility
β βββ test/ # Test files
β β βββ setup.ts
β β βββ index.test.ts
β β βββ formReducer.test.ts
β βββ index.tsx # Main Hono app & routes
β βββ renderer.tsx # HTML renderer
β βββ style.css # Global styles
βββ public/ # Static assets
βββ dist/ # Build output
βββ vite.config.ts # Vite configuration
βββ vitest.config.ts # Vitest configuration
βββ wrangler.jsonc # Cloudflare Workers config
βββ package.json
This app is built with accessibility in mind:
- Semantic HTML - Proper use of
<main>,<article>,<header>,<footer>landmarks - ARIA Labels - Screen reader-friendly labels and live regions
- Keyboard Navigation - Skip links and proper focus management
- Color Contrast - WCAG AA compliant color contrast ratios
- Reduced Motion - Respects
prefers-reduced-motionuser preference - High Contrast Mode - Supports
prefers-contrast: highmedia query - Form Accessibility - Proper labels, error announcements, and validation messages
Configure the following in your Cloudflare Workers environment:
| Variable | Description | Default |
|---|---|---|
API_ENDPOINT |
Backend API URL | https://shortin-api.yehezgun.com |
| Script | Description |
|---|---|
pnpm dev |
Start development server |
pnpm build |
Build for production |
pnpm test |
Run tests in watch mode |
pnpm test:ci |
Run tests once |
pnpm test:coverage |
Run tests with coverage |
pnpm cf:preview |
Preview production build |
pnpm cf:deploy |
Deploy to Cloudflare Workers |
pnpm cf-typegen |
Generate Cloudflare types |
pnpm up-latest |
Update all dependencies |
This project is open-source and available under the MIT License.
- Hono - Fast, lightweight web framework
- Tailwind CSS - Utility-first CSS
- Cloudflare Workers - Edge computing platform
- Plus Jakarta Sans - Beautiful typography
Made with β€οΈ by Yehezkiel Gunawan