MCPcopy Create free account
hub / github.com/9d8dev/directory / GET

Function GET

app/api/metadata/route.ts:4–111  ·  view source on GitHub ↗
(request: Request)

Source from the content-addressed store, hash-verified

2import { load } from "cheerio";
3
4export async function GET(request: Request) {
5 try {
6 const { searchParams } = new URL(request.url);
7 const url = searchParams.get("url");
8
9 if (!url) {
10 return NextResponse.json({ error: "URL is required" }, { status: 400 });
11 }
12
13 // Validate and normalize URL
14 let validUrl: URL;
15 try {
16 validUrl = new URL(url);
17 // Add https if no protocol is specified
18 if (!validUrl.protocol || validUrl.protocol === ":") {
19 validUrl = new URL(`https://${url}`);
20 }
21 } catch (error) {
22 console.error("Invalid URL format:", error);
23 return NextResponse.json(
24 { error: "Invalid URL format" },
25 { status: 400 },
26 );
27 }
28
29 console.log("Fetching metadata for URL:", validUrl.toString());
30
31 const response = await fetch(validUrl.toString(), {
32 headers: {
33 "User-Agent":
34 "Mozilla/5.0 (compatible; DirectoryBot/1.0; +http://localhost)",
35 },
36 });
37
38 if (!response.ok) {
39 return NextResponse.json(
40 { error: `Failed to fetch URL: ${response.statusText}` },
41 { status: response.status },
42 );
43 }
44
45 const html = await response.text();
46 const $ = load(html);
47
48 // Get favicon
49 let faviconUrl =
50 $('link[rel="icon"]').attr("href") ||
51 $('link[rel="shortcut icon"]').attr("href") ||
52 $('link[rel="apple-touch-icon"]').attr("href") ||
53 "/favicon.ico"; // Default fallback
54
55 // If favicon is relative, make it absolute
56 if (faviconUrl && !faviconUrl.startsWith("http")) {
57 try {
58 faviconUrl = new URL(faviconUrl, validUrl.origin).toString();
59 } catch (e) {
60 console.warn("Failed to parse favicon URL:", e);
61 faviconUrl = "/favicon.ico";

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected