feat: add proxy to url shortner

This commit is contained in:
gosangam
2026-05-11 17:28:04 +05:30
parent cc94296b46
commit 30d08c665d
3 changed files with 80 additions and 44 deletions
+23 -7
View File
@@ -1,18 +1,22 @@
/**
* Short link client — talks to the BFF /share endpoints.
* Short link client.
*
* Used by the text-selection toolbar (`buildShortHighlightUrl`) and the
* `/share/[code]` page (`resolveShortLink`).
* - `createShortLink` runs in the browser and POSTs to `/api/share`, a Next.js
* route handler that proxies to the BFF. We can't call the BFF directly
* from the browser because `BFF_URL` is not exposed to the client bundle
* (no `NEXT_PUBLIC_` prefix). Same-origin proxy also avoids CORS.
*
* - `resolveShortLink` is only called from the `/share/[code]` server
* component, so it can use `bff()` directly with the server-side env var.
*/
import { bff, bffPost } from "@/lib/bff";
import { bff } from "@/lib/bff";
// Module-scoped cache: a single user shouldn't generate a fresh code every
// time they re-click Share on the same selection. Keyed by the relative path
// (including ?hl=…), this returns the same promise for repeat calls.
const createCache = new Map<string, Promise<string | null>>();
type CreateResponse = { code: string };
type ResolveResponse = { url: string };
/**
@@ -23,8 +27,20 @@ export function createShortLink(longPath: string): Promise<string | null> {
const cached = createCache.get(longPath);
if (cached) return cached;
const promise = bffPost<CreateResponse>("/share", { url: longPath })
.then((r) => r.code)
const promise = fetch("/api/share", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({ url: longPath }),
})
.then(async (res) => {
if (!res.ok) return null;
const json = await res.json().catch(() => null);
const code = json?.data?.code;
return typeof code === "string" ? code : null;
})
.catch(() => null);
createCache.set(longPath, promise);