A simple and efficient URL shortener built with Cloudflare Workers, Hono, and TypeScript.
- Shorten long URLs into compact, easy-to-share short URLs
- Redirect short URLs to their original long URLs
- Track click analytics for each short URL
- API key authentication for secure access to the API endpoints
- Duplicate URL detection to prevent creating multiple short URLs for the same long URL
- Support for custom short codes
- Expiration time for short URLs
- Rate limiting to prevent abuse
- Input validation and error handling
- Update and delete short URLs
- CORS support with configurable allowed origins
- Caching of URL mappings for faster access
- Logging for better debugging and monitoring
- Pretty JSON formatting for API responses
- OpenGraph metadata support for rich previews when sharing short URLs on social media platforms
- Fallback values for missing OpenGraph metadata
- Caching of OpenGraph metadata to improve performance
- Error handling for fetching and extracting OpenGraph metadata
- Validation of OpenGraph metadata to ensure valid formats
- Encoding of OpenGraph metadata values to prevent cross-site scripting (XSS) attacks
- CSRF protection for API endpoints
- Node.js
- Cloudflare Workers account
- Wrangler CLI
-
Clone the repository:
git clone https://github.com/llegomark/url-shortener.git
-
Install the dependencies:
cd url-shortener npm install
-
Set up the required Cloudflare Workers KV namespaces:
URL_MAPPINGS
: Stores the mappings between short codes and original URLsURL_ANALYTICS
: Stores the click analytics for each short URLAPI_KEYS
: Stores the API keys for authenticationCUSTOM_DOMAINS
: Stores the custom domain mappingsOG_METADATA_CACHE
: Stores the cached OpenGraph metadata
Update the
wrangler.toml
file with the appropriate namespace bindings. -
Generate an API key and store it in the
API_KEYS
KV namespace:wrangler kv:put --namespace-id=<API_KEYS_NAMESPACE_ID> "your-api-key" "true"
Replace
<API_KEYS_NAMESPACE_ID>
with the actual namespace ID ofAPI_KEYS
. -
Set the
ALLOWED_CORS_ORIGINS
environment variable to specify the allowed origins for CORS:wrangler secret put ALLOWED_CORS_ORIGINS
Enter the comma-separated list of allowed origins when prompted.
-
Start the development server:
npm run dev
-
Create a short URL:
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer your-api-key" -d '{"url": "https://example.com/long-url"}' https://localhost:8787/api/urls
Replace
your-api-key
with your actual API key. -
Create a short URL with a custom short code:
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer your-api-key" -d '{"url": "https://example.com/long-url", "customCode": "my-custom-code"}' https://localhost:8787/api/urls
Replace
your-api-key
with your actual API key andmy-custom-code
with your desired custom short code. -
Create a short URL with an expiration time:
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer your-api-key" -d '{"url": "https://example.com/long-url", "expiresIn": 3600}' https://localhost:8787/api/urls
Replace
your-api-key
with your actual API key and3600
with the desired expiration time in seconds (e.g., 3600 seconds = 1 hour). -
Access the short URL:
curl -L https://localhost:8787/short-code
Replace
short-code
with the generated short code. -
Update a short URL:
curl -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer your-api-key" -d '{"url": "https://example.com/new-long-url"}' https://localhost:8787/api/urls/short-code
Replace
your-api-key
with your actual API key,short-code
with the short code you want to update, andhttps://example.com/new-long-url
with the new long URL. -
Delete a short URL:
curl -X DELETE -H "Authorization: Bearer your-api-key" https://localhost:8787/api/urls/short-code
Replace
your-api-key
with your actual API key andshort-code
with the short code you want to delete. -
Create a custom domain mapping:
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer your-api-key" -d '{"domain": "https://custom-domain.com", "target": "https://example.com"}' https://localhost:8787/api/domains
Replace
your-api-key
with your actual API key,https://custom-domain.com
with your custom domain, andhttps://example.com
with the target URL. -
Get URL analytics:
curl -H "Authorization: Bearer your-api-key" https://localhost:8787/api/analytics/short-code
Replace
your-api-key
with your actual API key andshort-code
with the short code you want to retrieve analytics for. -
Get overall analytics:
curl -H "Authorization: Bearer your-api-key" https://localhost:8787/api/analytics
Replace
your-api-key
with your actual API key.
The URL Shortener also comes with a user-friendly frontend built with React, TypeScript, Vite, and Tailwind CSS. The frontend provides an intuitive interface for users to interact with the URL shortening service.
- Shorten long URLs into compact, easy-to-share short URLs
- Update and delete short URLs
- View click analytics for each short URL
- Responsive design for optimal viewing on various devices
- API key authentication for secure access to the backend API
- Option to use environment variables for the API base URL and API key
- Input validation and error handling
- Copy short URLs to clipboard with a single click
- Loading states and error messages for better user experience
- Styled with Tailwind CSS for a modern and visually appealing interface
The frontend code is maintained in a separate repository. You can find the frontend repository at:
Please refer to the frontend repository for detailed instructions on setting up and running the frontend application.
The frontend communicates with the URL Shortener backend API to perform various operations such as creating short URLs, updating and deleting URLs, and retrieving click analytics. It sends requests to the backend API endpoints using the appropriate HTTP methods and headers.
Make sure to configure the frontend with the correct backend API URL and API key to establish a successful connection between the frontend and backend.
The URL shortener now supports OpenGraph metadata for rich previews when sharing short URLs on social media platforms. When creating a short URL, you can optionally provide the OpenGraph metadata (ogTitle
, ogDescription
, ogImage
) in the request payload. If the metadata is not provided, the system will attempt to fetch it from the original URL.
The fetched OpenGraph metadata is cached for improved performance, and fallback values are used if the metadata is missing or invalid. The metadata values are properly encoded to prevent cross-site scripting (XSS) attacks.
To set an expiration time for a short URL, include the expiresIn
parameter in the request payload when creating the short URL. The value should be in seconds.
For example, to create a short URL that expires in 1 hour (3600 seconds):
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer your-api-key" -d '{"url": "https://example.com/long-url", "expiresIn": 3600}' https://localhost:8787/api/urls
If the expiresIn
parameter is not provided, the short URL will not have an expiration time and will remain valid indefinitely.
When a short URL with an expiration time is accessed after its expiration, a 404 (Not Found) error will be returned, and the short URL will be automatically deleted from the system.
Deploy the URL shortener to Cloudflare Workers:
npm run deploy
Contributions are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request.
This project is licensed under the MIT License.