DEV Community

Evan
Evan

Posted on

Build link previews in 5 minutes

Build link previews in 5 minutes

When someone pastes a URL into your chat app, bookmark tool, or CMS, you usually want a small card: title, description, and an image. Parsing Open Graph tags yourself is tedious and easy to get wrong (redirects, relative image URLs, favicon fallbacks).

This walkthrough builds a minimal link-preview helper that calls a metadata API over HTTPS and renders a card. We’ll use the public URL Metadata & Open Graph Extractor on RapidAPI:

https://rapidapi.com/evan-DewNPsuYp/api/url-metadata-open-graph-extractor

You need a free RapidAPI account and an API key from the dashboard. The listing’s free tier is enough to try this locally.

What you get back

One GET request with a url query parameter returns JSON roughly like:

  • title, description, image, favicon
  • openGraph / twitter objects
  • canonical, siteName, jsonLd when present

The service fetches public HTML only (no login walls, no headless browser). SPA shells that don’t put meta tags in the initial HTML may return sparse results — that’s expected for v1.

1. Grab a key

  1. Open the listing above and subscribe to a plan (start with Basic/Free if available).
  2. Copy your X-RapidAPI-Key from https://rapidapi.com/developer/dashboard .
  3. Host header for this API (from the public page): url-metadata-open-graph-extractor.p.rapidapi.com

Store the key in an environment variable — never commit it.

export RAPIDAPI_KEY='your-key-here'
Enter fullscreen mode Exit fullscreen mode

2. One request with curl

curl --request GET \
  --url 'https://url-metadata-open-graph-extractor.p.rapidapi.com/v1/metadata?url=https%3A%2F%2Fwww.wikipedia.org%2F' \
  --header "X-RapidAPI-Key: $RAPIDAPI_KEY" \
  --header 'X-RapidAPI-Host: url-metadata-open-graph-extractor.p.rapidapi.com'
Enter fullscreen mode Exit fullscreen mode

You should see JSON with "ok": true, a title like "Wikipedia", a description, and an image URL pointing at the Wikipedia logo.

3. Tiny Node helper

// preview.mjs
const HOST = "url-metadata-open-graph-extractor.p.rapidapi.com";

export async function fetchLinkPreview(targetUrl) {
  const endpoint = new URL(`https://${HOST}/v1/metadata`);
  endpoint.searchParams.set("url", targetUrl);

  const res = await fetch(endpoint, {
    headers: {
      "X-RapidAPI-Key": process.env.RAPIDAPI_KEY,
      "X-RapidAPI-Host": HOST,
    },
  });

  const data = await res.json();
  if (!res.ok || !data.ok) {
    const err = new Error(data.error || `HTTP ${res.status}`);
    err.code = data.code;
    throw err;
  }

  return {
    title: data.title,
    description: data.description,
    image: data.image,
    favicon: data.favicon,
    url: data.finalUrl || data.url,
  };
}

// demo
const preview = await fetchLinkPreview("https://www.wikipedia.org/");
console.log(preview);
Enter fullscreen mode Exit fullscreen mode

Run with:

node preview.mjs
Enter fullscreen mode Exit fullscreen mode

4. Render a card (plain HTML)

function renderCard(p) {
  const img = p.image
    ? `<img src="${p.image}" alt="" width="120" height="120" />`
    : "";
  return `
<article class="link-card">
  ${img}
  <div>
    <a href="${p.url}" rel="noopener noreferrer">${p.title || p.url}</a>
    <p>${p.description || ""}</p>
  </div>
</article>`;
}
Enter fullscreen mode Exit fullscreen mode

Wire fetchLinkPreview into your backend route so the RapidAPI key never ships to the browser.

Practical tips

  • Encode the URL. Always encodeURIComponent / searchParams.set the target.
  • Timeouts. Upstream sites can be slow; set a client timeout (e.g. 15–30s) and show a fallback card.
  • Errors. Watch for ssrf_blocked (private IPs), unsupported_media, and upstream_error. Surface a generic “preview unavailable” UI.
  • Caching. Cache successful previews by normalized URL for a few hours to stay inside your monthly quota.

What’s next

  • Add a small in-memory or Redis cache keyed by URL.
  • Fall back to the hostname when title is null.
  • If you also need the page body as Markdown for RAG, see the companion API: URL to Markdown (LLM-ready).

That’s it — a working link preview path in a few minutes without maintaining your own HTML meta parser.

Top comments (0)