From 8a9aae205012d3e7de217e97d8b13c89689e7352 Mon Sep 17 00:00:00 2001 From: Tien Tran Date: Tue, 29 Sep 2026 00:06:59 -0700 Subject: [PATCH] feat: non-blocking background URL title fetching via Next.js after() --- src/app/api/shorten/route.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/app/api/shorten/route.ts b/src/app/api/shorten/route.ts index 0513c77..d641eca 100644 --- a/src/app/api/shorten/route.ts +++ b/src/app/api/shorten/route.ts @@ -1,9 +1,10 @@ -import { NextResponse } from "next/server"; +import { NextResponse, after } from "next/server"; import bcrypt from "bcryptjs"; import { prisma } from "@/lib/prisma"; import { getCurrentUser } from "@/lib/auth"; import { generateRandomCode, getDefaultUrlLength } from "@/lib/short-code"; import { generateQRCodeDataUrl } from "@/lib/qr"; +import { fetchUrlTitle } from "@/lib/url-metadata"; export async function POST(req: Request) { try { @@ -140,6 +141,22 @@ export async function POST(req: Request) { // Generate QR Code const qrCodeDataUrl = await generateQRCodeDataUrl(fullShortUrl, { size: 240 }); + // Non-blocking background task via Next.js after() + // Response is returned immediately to the client; title is fetched & updated afterward. + after(async () => { + try { + const pageTitle = await fetchUrlTitle(url.trim()); + if (pageTitle) { + await prisma.shortUrl.update({ + where: { id: createdUrl.id }, + data: { title: pageTitle }, + }); + } + } catch { + // Silently ignore background scraping errors + } + }); + return NextResponse.json({ success: true, data: {