A production-ready URL shortener service built on EdgeOne Pages Functions with KV storage. Features a complete RESTful API and a minimal Next.js UI interface.
Prerequisites: Please apply for and enable EdgeOne Pages KV storage service first
Choose the corresponding site to deploy:
- Fork Repository: Fork this repository to your GitHub account
- Bind Project: Go to EdgeOne Pages console, bind your GitHub repository and select the forked repo
- Configure Build: Complete the configuration following the wizard and deploy
- Additional Config: If KV binding or environment variables were not configured during initial deployment, re-deploy after binding them
After deployment, complete the following configuration:
-
Create KV Namespace
- Create or attach a KV namespace in your project settings
- Set the binding name to
dwz_kv(or your custom name)
-
Configure Environment Variables (Optional)
- If using a custom KV binding name, set
DWZ_KV_BINDINGenvironment variable - For API authentication protection, set
API_TOKENenvironment variable - To display ICP filing info, set
ICPenvironment variable
- If using a custom KV binding name, set
-
Re-deploy
- Trigger a re-deployment after configuration to apply changes
POST /api/shorten
Create a new short link or return an existing one.
Request Body
{
"url": "https://example.com/very/long/url",
"slug": "my-link" // Optional, auto-generated if not provided
}Response
{
"slug": "my-link",
"url": "https://example.com/very/long/url",
"shortUrl": "https://your.domain.com/s/my-link"
}Notes
- Automatically generates a 7-character random slug if not provided
- Same URL returns the same short link on multiple requests (idempotency)
- If
API_TOKENis set, include in request headers:Authorization: Bearer {API_TOKEN}orX-API-Token: {API_TOKEN}
GET /api/resolve?slug={slug}
Query the original URL for a short link.
Query Parameters
slug: Short link alias, e.g.,abc123- Also accepts full short URL, e.g.,
https://your.domain.com/s/abc123
Response
{
"slug": "abc123",
"url": "https://example.com/original/url"
}GET /s/:slug
302 redirect to the original URL and increment visit counter.
Example
https://your.domain.com/s/abc123 → https://example.com/original/url
| Key Pattern | Value Type | Description |
|---|---|---|
s:{slug} |
String | Forward mapping: short link alias → original URL |
u:{url} |
String | Reverse mapping: original URL → short link alias (for idempotency) |
c:{slug} |
String | Visit counter: stores the number of visits for a short link |
- Frontend UI: Next.js 14 + React + Tailwind CSS
- Backend API: EdgeOne Pages Functions (serverless)
- Data Storage: EdgeOne KV (key-value store)
- Development Language: TypeScript
| Variable | Description | Default | Required |
|---|---|---|---|
DWZ_KV_BINDING |
KV namespace binding name | dwz_kv |
No |
API_TOKEN |
API access token, requires header auth when enabled | - | No |
PASSWORD |
Password required for creating short links | - | No |
NEXT_PUBLIC_PASSWORD_REQUIRED |
Set to true to show password input in UI (also set when PASSWORD is configured) |
- | No |
NEXT_PUBLIC_ANNOUNCEMENT |
Announcement text displayed in top-right corner, auto-hides after 5 seconds, user can manually close, supports HTML tags | - | No |
NEXT_PUBLIC_ANNOUNCEMENT_ENCODED |
URL-encoded announcement content, takes priority over NEXT_PUBLIC_ANNOUNCEMENT, useful for cloud platforms with special character restrictions |
- | No |
ICP |
ICP filing number, displays at page footer when set | - | No |
Details
-
DWZ_KV_BINDING: Set this if your KV binding name is not
dwz_kv- Runtime lookup order:
globalThis[bindingName]→env[bindingName]
- Runtime lookup order:
-
API_TOKEN: Protects the short link creation endpoint from abuse
- When enabled, calling
/api/shortenrequires:Authorization: Bearer {API_TOKEN}orX-API-Token: {API_TOKEN}
- Same-origin requests (Web UI) don't require the token
- When enabled, calling
-
PASSWORD: Protects short link creation by requiring password input
- When enabled, calling
/api/shortenrequires:{ "password": "your-password" }in request body
- Local development environment (localhost) automatically bypasses password validation
- When enabled, calling
-
NEXT_PUBLIC_PASSWORD_REQUIRED: Controls whether the Web UI displays password input
- Set to
trueto show the password input field in UI - Should be set to
truewhenPASSWORDis configured - Read at build time, no runtime API request needed
- Set to
-
ICP: Required for mainland China users to display website filing information
npm install -g edgeoneedgeone pages linkFollow the prompts to select or create an EdgeOne Pages project.
Go to EdgeOne Console, find your bound project, and attach a KV namespace in the project settings.
edgeone pages devVisit http://localhost:8088 to view the application.
- Changes to
functions/directory auto-reload - Changes to
app/andcomponents/require server restart - Local development environment automatically bypasses API Token validation
Built with EdgeOne Pages ⚡