Skip to content

feat: Plummer — Cloudflare Workers link shortener#1

Merged
kiyarose merged 6 commits into
mainfrom
copilot/create-link-shortening-service
May 1, 2026
Merged

feat: Plummer — Cloudflare Workers link shortener#1
kiyarose merged 6 commits into
mainfrom
copilot/create-link-shortening-service

Conversation

Copy link
Copy Markdown

Copilot AI commented May 1, 2026

Implements the Plummer link shortener as a single-file Cloudflare Worker backed by a KV namespace (LINKIVERSE). Designed as both an internal tool (share.sillylittle.tech) and a forkable template.

Worker (src/index.js)

  • RoutingGET / homepage, GET /admin dashboard (Basic Auth), GET|POST /:slug redirect handler, REST /api/links
  • Redirect logic — KV lookup → expiry check (auto-deletes stale entries) → optional password gate → click increment (via waitUntil) → 302
  • Admin APIGET /api/links, POST /api/links, DELETE /api/links/:slug; slug validated to [a-zA-Z0-9_-]{1,64}, reserved slugs blocked, destination URL must be http(s)
  • Auth — HTTP Basic Auth against ADMIN_SECRET Wrangler secret; timing-safe comparison via SHA-256 + constant-time XOR to avoid length/timing leaks
  • Password protection — stored as SHA-256 hash; same timing-safe comparison on unlock
  • SecurityX-Content-Type-Options, X-Frame-Options, Referrer-Policy on every response; onclick values use JSON.stringify + escHtml to prevent XSS injection
  • UI — matches SillyLittleTech lander/pasCurtain style: Lexend font, CSS custom-property theming, dark/light toggle with localStorage persistence

KV schema — key: link:{slug}

{
  "slug": "my-link",
  "guest": "https://example.com",   // destination URL
  "passwordHash": null,              // SHA-256 hex, or null
  "expiresAt": null,                 // Unix ms timestamp, or null
  "clicks": 42,
  "createdAt": 1714500000000
}

Infrastructure

  • wrangler.toml — KV binding + commented [[routes]] stub for share.sillylittle.tech
  • package.json — wrangler v4.86.0 (patched; v3 line had a known CVE)
  • .github/workflows/deploy.yml — deploys to Workers on push to main

Required setup (first deploy)

# 1. Create KV namespace and paste ID into wrangler.toml
npx wrangler kv namespace create LINKIVERSE

# 2. Set admin password
npx wrangler secret put ADMIN_SECRET

# 3. Add to GitHub repo secrets for CI/CD:
#    CLOUDFLARE_API_TOKEN  (Workers:Edit permission)
#    CLOUDFLARE_ACCOUNT_ID

Full instructions in the updated README.md.

Original prompt

Base requirements for this repo off of SillyLittleTech/projecthub#25
Using Cloudflare workers we should create a link shortening service for internal use (open source for if a user wants to use a template, and for clarity).
The main "web" portion features a homepage explaining the fact it is a link shortening service URL, and have a link to an admin dashboard. This admin dashboard, would contain tools to create links on a specified subdomain or domain. In this case we will be using "share.sillylittle.tech", but support default Cloudflare dev domains for testing.
When creating links, the user sets the slug or URL of the short link, and the guest (where the short link goes). The user also has a few options, they can set links to expire, which will set a timestamp we can use to delete the link from a KV database we will set up for this service, they can make a link have a basic password protection page, and we should track basic analytics in the dashboard (clicks!).
Base UI off of a combination of https://github.com/sillylittletech/lander and https://github.com/sillylittletech/pasCurtain.
If something more is needed for setup, E.G. is creating the KV database, repo or action secrets, etc.
(And build steps once the code is done), please put these details in the PR description, or in a comment on the PR.)

Copilot AI changed the title [WIP] Create link shortening service with admin dashboard feat: Plummer — Cloudflare Workers link shortener May 1, 2026
Copilot AI requested a review from kiyarose May 1, 2026 05:00
@kiyarose
Copy link
Copy Markdown
Member

kiyarose commented May 1, 2026

@copilot Wait, so where do I get the Github secrets,
Wht do I put for "ADMIN_SECRET", and do I need to make an entire new KV for the "preview namespace"
I also wonder, what do I need to do in order to set up the domain for this tool.

Copy link
Copy Markdown
Author

Copilot AI commented May 1, 2026

@copilot Wait, so where do I get the Github secrets,
Wht do I put for "ADMIN_SECRET", and do I need to make an entire new KV for the "preview namespace"
I also wonder, what do I need to do in order t...

Great questions — here's a breakdown of each:


GitHub Actions secrets (CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID)

Both come from the Cloudflare Dashboard:

  • CLOUDFLARE_API_TOKEN → Log in → top-right avatar → My ProfileAPI TokensCreate Token → use the "Edit Cloudflare Workers" template. Copy the token it shows you (only visible once).
  • CLOUDFLARE_ACCOUNT_ID → Log in → Workers & Pages in the left sidebar → your Account ID is shown in the right-hand sidebar.

Once you have both values, go to this repo → SettingsSecrets and variablesActionsNew repository secret and add each one by name.


ADMIN_SECRET — what to set it to

ADMIN_SECRET is the password you'll use to log into the /admin dashboard. Pick any strong password you like — it's completely up to you. When you run npx wrangler secret put ADMIN_SECRET it will prompt you to type it in. When you visit /admin in your browser, use any username and that password.

This is a Wrangler secret (stored encrypted on Cloudflare, not in GitHub), so you don't add it to GitHub Actions.


Preview KV namespace — do you need it?

No, it's optional. You only need the preview namespace if you want to use npx wrangler dev for local development (it uses a separate namespace so test data doesn't pollute production). If you're deploying straight to production without doing local dev, you can skip the --preview command and leave the preview_id line commented out in wrangler.toml.


Setting up share.sillylittle.tech

Three things need to be true:

  1. The sillylittle.tech zone is in your Cloudflare account with its DNS managed by Cloudflare (orange-cloud proxy enabled).
  2. Uncomment the [[routes]] block in wrangler.toml:
    [[routes]]
    pattern   = "share.sillylittle.tech/*"
    zone_name = "sillylittle.tech"
  3. Add a DNS record in the Cloudflare dashboard for share.sillylittle.tech pointing to 100:: (a proxied AAAA record is the standard placeholder — Cloudflare will route it through the Worker before it ever resolves). Then run npm run deploy.

If the zone is already on Cloudflare (which it is for sillylittle.tech), step 3 is just adding the DNS record and deploying.

@kiyarose
Copy link
Copy Markdown
Member

kiyarose commented May 1, 2026

@copilot How to setup preview KV? Can we skill custom domain setup for now and still test until we are ready for prod?

Copy link
Copy Markdown
Author

Copilot AI commented May 1, 2026

@copilot How to setup preview KV? Can we skill custom domain setup for now and still test until we are ready for prod?

Yes, you can absolutely skip the custom domain and test using the default workers.dev URL — Cloudflare assigns one automatically when you deploy.


Setting up the preview KV namespace

Run this once in your terminal (you need to be logged in with npx wrangler login first):

npx wrangler kv namespace create LINKIVERSE --preview

It will print something like:

✨ Success! Created KV namespace "LINKIVERSE_preview" with id "abc123..."

Copy that id value and paste it into wrangler.toml as preview_id:

[[kv_namespaces]]
binding    = "LINKIVERSE"
id         = "your-production-namespace-id"
preview_id = "abc123..."          # ← paste the preview id here

That's it — wrangler dev will now use the preview namespace automatically.


Testing without a custom domain

Yes, skip the [[routes]] block entirely for now. When you run npm run deploy (or npx wrangler deploy), Cloudflare will deploy to a free *.workers.dev subdomain — something like https://plummer.<your-account>.workers.dev. That URL works exactly like the real thing, so you can test all features (short links, /admin, the API) before you're ready to point a custom domain at it.

When you're ready to add share.sillylittle.tech later, just uncomment the [[routes]] block and redeploy.

@kiyarose
Copy link
Copy Markdown
Member

kiyarose commented May 1, 2026

@copilot Do I need to uncomment [[routes]] if I am not adding a custom domain at this time, how do I build to test.

Copy link
Copy Markdown
Author

Copilot AI commented May 1, 2026

@copilot Do I need to uncomment [[routes]] if I am not adding a custom domain at this time, how do I build to test.

No, leave [[routes]] commented out — it's only needed for custom domains. Without it, Cloudflare deploys exclusively to the free workers.dev URL.

To test locally (recommended first step):

npm install          # install wrangler if you haven't yet
npx wrangler dev     # starts a local dev server at http://localhost:8787

wrangler dev runs the Worker on your machine without touching Cloudflare at all. Visit http://localhost:8787 to test the homepage, http://localhost:8787/admin for the dashboard, etc. If you set up the preview KV namespace earlier, it uses that automatically; otherwise it falls back to an in-memory store that resets on each restart (fine for quick testing).

To deploy to Cloudflare and test on a real URL:

npm run deploy

After deploy, the CLI will print a URL like https://plummer.<your-subdomain>.workers.dev — open that in your browser and everything works exactly as it will in production.

@kiyarose
Copy link
Copy Markdown
Member

kiyarose commented May 1, 2026

@copilot can we comment out the code for the local /admin password stuff, we will be likely locking this endpoint behind CF access, while the MAIN page is still public.

@kiyarose kiyarose marked this pull request as ready for review May 1, 2026 05:51
Copilot AI review requested due to automatic review settings May 1, 2026 05:51
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 1, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
plummer 2dfe580 Commit Preview URL

Branch Preview URL
May 01 2026, 05:59 AM

@kiyarose kiyarose merged commit 496b9d8 into main May 1, 2026
1 check passed
@kiyarose kiyarose deleted the copilot/create-link-shortening-service branch May 1, 2026 06:10
Copilot AI review requested due to automatic review settings May 1, 2026 06:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[💡]: SillyLittleTech Custom Link Shortner

2 participants