How to Build Your Own Link Shortener with Cloudflare Workers

· 10 minutes · Tutorial

I’m sure that you’ve used URL shorteners like bit.ly or tinyurl.
They are great for sharing links on social media, emails, or even behind a QR code.
In this tutorial, we’ll build our own URL shortener using the Cloudflare Workers platform.

Prerequisites

Knowing the tools

Cloudflare Workers is a serverless platform that allows you to run code at the edge.
We’ll write a Worker that listens for incoming requests, checks if the path is a valid shortened URL, and redirects the user to the original one.

CLoudflare KV is a key-value store that allows you to store and retrieve data at the edge.
We can store the original and shortened URLs as key-value pairs in KV.
When someone visits the shortened URL, we’ll look up the original URL.

Step 1: Create a KV namespace

Log in to your Cloudflare account and navigate to the Storage & Databases option in the sidebar.
Click the “Create” button at the top right corner to create a new KV namespace. Name your namespace and click “Add”.

I named my namespace “URLS”, you can name it whatever you want.

Now you can see the URLS namespace in the list of KV namespaces.
You can click on the namespace to see the details and copy the ID of the namespace (we’ll need it later).

You can also add some key-value pairs to the namespace in the “KV Pairs” tab.

Step 2: Create the Worker project

Before we start coding, let’s create the Worker project using the Wrangler CLI.
Wrangler is a command-line tool that helps you build, test, and deploy Cloudflare Workers.

Go to your work directory and run the following command:

npx wrangler generate shortener

Wrangler will ask you a few questions about your project.
You can use the next answers:

? Would you like to use git to manage this Worker? › (Y/n)
 Y
? No package.json found. Would you like to create one? › (Y/n)
 Y
? Would you like to use TypeScript? › (Y/n)
 Y
? Would you like to create a Worker at shortener/src/index.ts?
- Use arrow-keys. Return to submit.
    None
   Fetch handler
    Scheduled handler
? Would you like us to write your first test with Vitest? › (Y/n)
 N

This will create a new directory with the Worker project files.
Navigate to the project directory:

cd shortener

The project structure looks like this:

shortener
├── node_modules
├── package-lock.json
├── package.json
├── src
│   └── index.ts
├── tsconfig.json
└── wrangler.toml

We’ll focus on the following files:

You can run the Worker locally using:

npx wrangler dev
# or
npm run start

Go to localhost:8787 to see the Worker running.

Step 3: Setup the KV binding

To use the KV namespace in the Worker code, we need to add a binding in the wrangler.toml file.
Open the wrangler.toml file in your code editor and add the following bindings:

kv_namespaces = [
  { binding = "URLS", id = "YOUR_KV_NAMESPACE_ID" }
]

The binding name URLS is the name of the KV namespace that we’ll use in the Worker code.
Replace YOUR_KV_NAMESPACE_ID with the ID of the KV namespace you created in the first step.

Step 4: Write the Worker code

Open the src/index.js file in your code editor and see the default Worker code.
Looks like this:

export interface Env {}

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};

We need to modify this code to check if the path is a shortened URL and redirect the user.

First of all, we need to read the url path used to call the Worker.
We can do this by using the URL object.

The structure of a short URL is a single slash followed by some characters.

// Inside the fetch function
const url = new URL(request.url)
const short = url.pathname

// Check if the path is a valid path (one slash and some characters)
if (!short.match(/^\/[a-zA-Z0-9]+$/)) {
  return new Response("Invalid url", { status: 404 })
}

Next, we need to check if the path is a shortened URL.
You can use the env object to access the KV namespace and get the value.

If you’re using TypeScript, you need to add the KV namespace type to the Env interface.

// Continue inside the fetch function
interface Env {
  URLS: KVNamespace
}

Now you can access the KV namespace in the Worker code.
You can use the get method to get the value of a key in the KV namespace.
If the key does not exist, the method will return null, and we can return a 404 response.

// Continue inside the fetch function
const long = await env.URLS.get(path.slice(1))

if (!long) {
  return new Response("Not found", { status: 404 })
}

If we found an original URL, we can redirect the user to that.

// Continue inside the fetch function
return Response.redirect(long, 301)

The final code looks like this:

export interface Env {
  URLS: KVNamespace
}

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url)
    const short = url.pathname

    if (!short.match(/^\/[a-zA-Z0-9]+$/)) {
      return new Response("Invalid url", { status: 404 })
    }

    const long = await env.URLS.get(short.slice(1))

    if (!long) {
      return new Response("Not found", { status: 404 })
    }

    return Response.redirect(long, 301)
  },
};

And that’s it! We have written all the required code! ✨
That’s the beauty of Cloudflare Workers, you can write and deploy functionality in a few lines of code.

Step 4: Test the redirection

Now that we have written the Worker code, let’s test the redirection.

First of all, you need create some shorts in the KV namespace.
You can do this using the Wrangler CLI or the Cloudflare dashboard.

npx wrangler kv:key put URLS /blog https://diananerd.com/blog

Feel free to add some real links in this step, like your website or social media profiles.
See how we can use the slash character to create a special redirection in the root path.

npx wrangler kv:key put URLS / https://diananerd.com

If you’re not running the Worker locally, you run it using:

npm run start

Open your browser and visit the Worker URL with the short path: localhost:8787/blog

You should be redirected to the original URL. 🚀

Step 5: Deploy the Worker

Now that we have written the Worker code, let’s deploy it to the Cloudflare Workers platform.
You can deploy the Worker using the following command:

npm run deploy

This will upload the Worker code to Cloudflare and give you a URL to access the Worker.
Another way to deploy the Worker is to use the GitHub integration in the Cloudflare dashboard.

Final thoughts

Now that the Worker is deployed, you can test the URL shortener by visiting the Worker URL.
You can also create a custom domain and point it to the Worker URL.

I have my own shortener built using this code, you can try it out:
dnrd.dev/shortener

This will redirect you to this post. 😋

That’s it! You’ve built your own URL shortener using Cloudflare Workers and KV. 🥳

If you liked this tutorial, consider sharing it with your friends and followers.
You can also follow me on Bluesky for more tutorials and tips.