44
loading...
This website collects cookies to deliver better user experience
shorturl.at/gIUX4
, the slug is gIUX4
)npm
to install itty-router
and nanoid
:npm i itty-router nanoid
wrangler.toml
file, and have set the type
for your project to webpack
to package up these dependencies.gIUX4
), and the value the URL they point to (e.g https://www.youtube.com/watch?v=dQw4w9WgXcQ
).SHORTEN
:$ wrangler kv:namespace create "SHORTEN"
wrangler.toml
file:🌀 Creating namespace with title "rd-test-SHORTEN"
✨ Success!
Add the following to your configuration file:
kv_namespaces = [
{ binding = "SHORTEN", id = "48ae98ff404a460a87d0348bb5197595" }
]
kv_namespaces
entry to the end of my wrangler.toml
file. The binding
key here lets you access the KV namespace by the SHORTEN
variable in your Worker code. If you log in to the Cloudflare Workers dashboard, you should be able to see your namespace listed under KV too:SHORTEN
variable, which we'll see in a moment.wrangler dev
) when previewing your Worker:$ wrangler kv:namespace create "SHORTEN" --preview
preview_id
provided in the output of this command and add it to the wrangler.toml
file, in the same entry as your SHORTEN
KV namespace. For example, if my output was this:🌀 Creating namespace with title "rd-test-SHORTEN_preview"
✨ Success!
Add the following to your configuration file:
kv_namespaces = [
{ binding = "SHORTEN", preview_id = "d7044b5c3dde494a9baf1d3803921f1c" }
]
wrangler.toml
file would now have this under kv_namespaces
:kv_namespaces = [
{ binding = "SHORTEN", id = "48ae98ff404a460a87d0348bb5197595", preview_id = "d7044b5c3dde494a9baf1d3803921f1c" }
]
_preview
and one not.POST /links
, that takes in a JSON payload like { "url": "https://google.com" }
, then:nanoid
SHORTEN
KV namespace with the key as the slug in (1) and the value as the URL in the request payloadindex.js
in your project folder. Let's import some functions we'll need from itty-router
and nanoid
, create a router, and set up a custom alphabet to pick our URL slugs from (the 6
ensures they're 6 characters):import { Router } from 'itty-router';
import { customAlphabet } from 'nanoid';
const router = Router();
const nanoid = customAlphabet(
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
6,
);
router.post('/links', async request => {
let slug = nanoid();
let requestBody = await request.json();
if ('url' in requestBody) {
// Add slug to our KV store so it can be retrieved later:
await SHORTEN.put(slug, requestBody.url, { expirationTtl: 86400 });
let shortenedURL = `${new URL(request.url).origin}/${slug}`;
let responseBody = {
message: 'Link shortened successfully',
slug,
shortened: shortenedURL,
};
return new Response(JSON.stringify(responseBody), {
headers: { 'content-type': 'application/json' },
status: 200,
});
} else {
return new Response("Must provide a valid URL", { status: 400 });
}
});
/links
to accept POST requests, and consuming the request
object passed from our fetch event the worker listens for. We're using our custom alphabet nanoid
to generate a 6-character random slug, and then pulling the URL out of the request body. We also add this to our KV namespace we generated earlier:await SHORTEN.put(slug, requestBody.url, { expirationTtl: 86400 });
SHORTEN
variable is bound to your Worker after adding it in wrangler.toml
. Here we're setting the key to automatically expire in a day, but you can choose to set this to any value you want (or not make it expire at all!) If all goes well, we'll return the slug and the full shortened URL so the front-end can make use of it.index.js
that came with the template Wrangler used to create the project:addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
router
function instead:addEventListener('fetch', event => {
event.respondWith(router.handle(event.request))
})
Request
object in the fetch event and can act on it, passing the request off to the correct route (like the one we defined above). Let's test it out! Run wrangler dev
and make a test request to your Worker:$ curl -X "POST" "http://127.0.0.1:8787/links" \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
}'
{"message":"Link shortened successfully","slug":"TCqff7","shortened":"https://redirect.mascioni.workers.dev/TCqff7"}
shortened
depends on your Workers subdomain and project name you chose in the beginning. If you head over to your SHORTEN_preview
KV namespace in the Workers dashboard, you should see the entry was added too!handleRequest
function the template comes with from index.js
..get
on our KV namespace and returning a redirect. index.js
:router.get('/:slug', async request => {
let link = await SHORTEN.get(request.params.slug);
if (link) {
return new Response(null, {
headers: { Location: link },
status: 301,
});
} else {
return new Response('Key not found', {
status: 404,
});
}
});
GET /:slug
route, and making use of the slug
parameter to fetch a value from our KV namespace. If a value exists, we'll return it with a 301
status code and set the Location
header appropriately to do the redirect, otherwise we'll throw a 404
error.wrangler dev
isn't running anymore, run it again, and now make a GET
request from your browser to try and retrieve the URL you stored earlier! In my case, my Worker is listening for requests on port 8787
, and I saved a URL with slug TCqff7
, so I'd go to http://127.0.0.1:8787/TCqff7
.