Public
HTTP
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Readme

Short URLs

A URL shortener in Val Town! This turns URLs into strings like

https://vawogbemi-short.web.val.run/JK

An implementation of https://www.val.town/v/tmcw/short

It uses SQL instead of express persistent storage.

Table Schema

Short(id INT, url TEXT)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/** @jsxImportSource https://esm.sh/hono@latest/jsx **/
import { sqlite } from "https://esm.town/v/std/sqlite";
import { Hono } from "npm:hono";
import Sqids from "npm:sqids";
const app = new Hono();
const sqids = new Sqids();
app.get("/", (c) => {
return c.html(
<html>
<head>
<title>URL Shortener</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://the.missing.style" />
<script src="https://unpkg.com/htmx.org@1.9.2"></script>
</head>
<body>
<main>
<h1>Val Town shortener</h1>
<form class="f-row" hx-target="#result" hx-post="/">
<input style="width:100%" type="url" required name="url" />
<button type="submit">Shorter</button>
</form>
<div id="result"></div>
</main>
<footer>
<a href="https://www.val.town/v/vawogbemi/short">Powered by Val Town</a>
<p>
Okay, so let's be honest, this might actually give you a longer URL because it's at a pretty long subdomain.
But go with me here, isn’t it cool to have such a tiny URL shortener?
</p>
</footer>
</body>
</html>,
);
});
app.post("/", async (c) => {
const idx = await sqlite.execute("SELECT id FROM Short");
const body = await c.req.parseBody();
const id = sqids.encode([idx.rows.length]);
await sqlite.execute({
sql: `insert into Short(id, url) values (:id, :url)`,
args: { id: idx.rows.length, url: body.url as string },
});
return c.html(
<div class="box ok">
Created!{" "}
<a href={`https://vawogbemi-short.web.val.run/${id}`}>
{`https://vawogbemi-short.web.val.run/${id}`}
</a>
<br />
<button
type="button"
value={`https://vawogbemi-short.web.val.run/${id}`}
onclick="navigator.clipboard.writeText(this.value)
.then(() => { this.innerText = 'Copied!'; })
.catch(() => me.parentElement.remove(me));"
>
Copy link
</button>
</div>,
);
});
app.get(`/:path{.+}`, async (c) => {
const id = sqids.decode(c.req.param("path"));
const idx = await sqlite.execute(`SELECT * FROM Short WHERE id = ${id}`);
return c.redirect(idx.rows[0][1]);
});
export default app.fetch;
vawogbemi-short.web.val.run
August 4, 2024