DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
Astro

Building Link Preview Components with React, Vue, Svelte, and Astro

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Build link previews as two separate layers: a server or build step obtains metadata for a destination URL, and a normal UI component renders that metadata as an accessible card. Keeping those responsibilities separate lets you change from a hosted extractor to your own endpoint or cache without rewriting the React, Vue, Svelte, or Astro presentation.

The examples below use one small metadata contract, explicit loading and error states, safe URL handling at the input boundary, and framework-specific rendering patterns. A visible preview card is page content; it is not the same thing as adding <meta> or <link> elements to your document head.

Design the data contract before choosing a framework

Define the object that crosses the fetch/render boundary. Fields are optional because real pages may omit descriptions or images, redirects may change the final URL, and extraction can fail.

type LinkMetadata = {
  resolvedUrl?: string;
  title?: string;
  description?: string;
  imageUrl?: string;
  siteLabel?: string;
};

type PreviewState =
  | { status: 'loading' }
  | { status: 'ready'; data: LinkMetadata }
  | { status: 'error'; message: string };

Validate that the submitted value is an allowed http: or https: URL before sending it to an extractor. Treat title, description, host names, and image URLs as untrusted text or URLs: render text through framework escaping, and validate image protocols at the boundary. This guide does not prescribe a complete SSRF or sanitization policy; your server should apply the controls required by its network architecture.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep the extractor behind an application function such as getLinkMetadata(url). The function can call a hosted metadata API, your own backend, or a cache. Components consume the same contract either way.

Choose where metadata is fetched

Build-time Astro generation

For a static page whose previews change infrequently, fetch in an .astro component. Astro executes that fetch at build time and exposes the result to the template. Visitors receive generated HTML, but the value does not automatically refresh on every request.

Request-time server rendering

With Astro SSR enabled, the same component fetch can run at request time. Use this when previews depend on request data or must be current. Account for server execution, upstream latency, timeouts, and a cache policy; the documentation establishes timing, not a performance benchmark.

Browser-triggered retrieval

Hydrate a framework component only when interaction or refresh requires it. In Astro, the selected client:* directive controls when the island loads. A hydrated React, Vue, or Svelte component brings the JavaScript required by that framework, while a plain Astro component emits static HTML.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Hosted extraction versus your endpoint

A hosted service can provide extraction rules, cache behavior, image handling, and framework integrations. LinkMetadata documents those capabilities, including rendering pre-fetched metadata without another API request. Compare its fields, cache controls, safety data, privacy terms, and current service conditions with an extractor you operate before adopting it.

Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

Render the card in React

The component below renders ordinary body UI. It does not attempt to put destination metadata in the current document head.

type Props = { data: LinkMetadata };

export function LinkPreview({ data }: Props) {
  const href = data.resolvedUrl;
  const label = data.siteLabel || (href ? new URL(href).hostname : 'Link');

  return (
    <article className="preview-card">
      {data.imageUrl && (
        <img src={data.imageUrl} alt="" loading="lazy" />
      )}
      <div>
        <p className="preview-site">{label}</p>
        <h3>{data.title || 'Untitled page'}</h3>
        {data.description && <p>{data.description}</p>}
        {href && (
          <a href={href} rel="noreferrer">Open link</a>
        )}
      </div>
    </article>
  );
}

React’s built-in <meta> component places document metadata in the head. Its <link> component is likewise for document links and metadata and is generally placed in the head, subject to documented exceptions. Neither component fetches arbitrary URL metadata or creates a visible card. Use them for the page your application is rendering, and use the component above for the destination preview.

Show a preview in Vue

Keep the same contract and let Vue escape interpolated text. Guard image and destination fields so missing extraction data produces a useful fallback.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<script setup lang="ts">
defineProps<{ data: LinkMetadata }>();
</script>

<template>
  <article class="preview-card">
    <img v-if="data.imageUrl" :src="data.imageUrl" alt="" loading="lazy" />
    <div>
      <p class="preview-site">{{ data.siteLabel || 'Link' }}</p>
      <h3>{{ data.title || 'Untitled page' }}</h3>
      <p v-if="data.description">{{ data.description }}</p>
      <a v-if="data.resolvedUrl" :href="data.resolvedUrl" rel="noreferrer">Open link</a>
    </div>
  </article>
</template>

Put fetching in a composable, server route, or parent component rather than coupling the card to one vendor. Represent loading and error states explicitly so a failed extraction does not leave an empty box.

Show a preview in Svelte

<script lang="ts">
  export let data: LinkMetadata;
</script>

<article class="preview-card">
  {#if data.imageUrl}
    <img src={data.imageUrl} alt="" loading="lazy" />
  {/if}
  <div>
    <p class="preview-site">{data.siteLabel || 'Link'}</p>
    <h3>{data.title || 'Untitled page'}</h3>
    {#if data.description}
      <p>{data.description}</p>
    {/if}
    {#if data.resolvedUrl}
      <a href={data.resolvedUrl} rel="noreferrer">Open link</a>
    {/if}
  </div>
</article>

Whether the component is rendered on the server or in the browser, keep extraction in a separate module. That makes retries, caching, and provider replacement independent of the card markup.

Use React, Vue, or Svelte inside Astro

Astro pages can render React, Vue, and Svelte components. Only Astro components can contain components from multiple frameworks. Framework components are islands; use serializable props when passing metadata from an Astro component.

---
import ReactPreview from '../components/ReactPreview.jsx';
import VuePreview from '../components/VuePreview.vue';
import SveltePreview from '../components/SveltePreview.svelte';

const response = await fetch('https://your-app.example/api/metadata?url=https%3A%2F%2Fexample.com');
const data = await response.json();
---

<ReactPreview data={data} client:visible />
<VuePreview data={data} client:load />
<SveltePreview data={data} client:idle />

Choose one framework component for a real page rather than rendering all three; the example shows the available integration points. For a static card, a plain Astro component can avoid hydration entirely:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
---
const data = await getLinkMetadata(Astro.props.url);
---

<article class="preview-card">
  <h3>{data.title || 'Untitled page'}</h3>
  {data.description && <p>{data.description}</p>}
  {data.resolvedUrl && <a href={data.resolvedUrl}>Open link</a>}
</article>

Use framework syntax and imports inside each framework island. Astro’s render props cannot supply missing client-runtime behavior; use slots when child content belongs in an Astro component.

Loading, fallback, and accessibility states

  • Loading: reserve card space and expose a short status such as “Loading preview” without shifting surrounding content.
  • Ready: show title, optional description, a recognizable site label, and a clear destination link. Use an empty image alt when the image is decorative.
  • No image: retain text layout; do not invent a broken-image icon.
  • No title: display “Untitled page” or the host name, whichever is more useful to your product.
  • Error or timeout: offer the original URL as a normal link and explain that a preview is unavailable.
  • Malformed input: reject before extraction and identify the required URL format.

Use semantic links and headings, visible focus styles, sufficient contrast, and keyboard-accessible controls. If the card itself is clickable, avoid nesting an interactive link inside another interactive element; make one clear link target instead.

Caching, freshness, and reliability

Cache by canonical or resolved URL when possible, with a bounded TTL appropriate to the source. Store successful metadata separately from negative results so a temporary outage does not become a long-lived blank card. Apply request timeouts, bounded retries with backoff, and a maximum response size in your server layer. Do not let a slow remote page block the entire document when a fallback link can render immediately.

Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Decide whether stale metadata is preferable to an error. For build-time Astro pages, schedule rebuilds when freshness matters. For SSR, cache at the server or edge and include a stale-while-revalidate strategy if your runtime supports it. Browser fetching should call your own endpoint rather than exposing extractor credentials.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

ScreenshotNeo can capture the destination directly when your feature needs a rendered image or PDF rather than parsed metadata. One GET request returns PNG, JPEG, WebP, or PDF. It accepts cookie and consent banners like a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

Using the documented endpoint (see the ScreenshotNeo API documentation):

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo also supports full-page and selector captures, lazy-image loading, dark mode, device presets, custom viewport and retina scale, PDF controls, custom CSS and JavaScript, clicks, waits, blocked resources, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen TTL caching, signed links, async webhooks, bulk capture of 100 URLs per call, a usage API, and an OpenAPI specification. Every feature is on every plan: 1,000 shots per month free with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common failures

The card is blank

Inspect the network response and verify that your component receives the agreed contract, not the provider’s raw shape. Log status and validation errors server-side, then render the original URL as the fallback.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The image fails while text works

The image host may block hotlinking or disallow browser CORS. Proxy and cache approved images through your server, or omit the image while retaining text. Validate protocols before emitting src.

Astro data is stale

A build-time fetch runs only during generation. Move the fetch to an SSR route, shorten your cache TTL, or schedule rebuilds.

Hydration warnings appear

Ensure props are serializable and that server and client render the same fallback values. Choose the client:* directive deliberately; static cards need no hydration.

Extraction times out

Set a finite timeout, return a normal link promptly, and retry asynchronously rather than holding the page open indefinitely. Cache a prior successful response when its age is acceptable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Implementation checklist

  • Define optional metadata, loading, ready, and error states.
  • Validate URL scheme and untrusted fields at the server boundary.
  • Choose build-time, request-time, or browser retrieval based on freshness and interaction needs.
  • Keep React, Vue, Svelte, and Astro card markup independent from the extractor.
  • Use document-head metadata only for the current page, never as a destination-card substitute.
  • Provide image, title, timeout, malformed-input, and unreachable-page fallbacks.
  • Cache successes and negative responses with explicit TTLs and bounded retries.
  • Hydrate Astro islands only when interaction requires framework JavaScript.

Frequently Asked Questions

Can Open Graph tags on my page fetch metadata for a user-entered URL?

No. Head metadata describes the document being rendered. Fetch destination metadata on the server, at build time, or through a controlled client endpoint, then render it as visible card UI.

Should every Astro preview be a hydrated framework island?

No. A static card can be a plain Astro component. Hydrate React, Vue, or Svelte only when the preview needs client-side interaction or refresh.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.