embed-card
Frameworks

Manual Rendering

Build your own UI on top of the low-level resolver helpers.

Manual Rendering

For teams that want total control over markup, use the manual helpers:

import { RedditEmbedPreview, TikTokEmbedPreview } from "embed-card"
import { resolveEmbed } from "embed-card/manual"

export function CustomShell({ url }: { url: string }) {
  const embed = resolveEmbed(url)

  if (embed.renderer.type === "iframe") {
    return (
      <iframe
        allow={embed.renderer.allow}
        src={embed.renderer.src}
        title={embed.renderer.title}
      />
    )
  }

  if (embed.renderer.type === "reddit_client") {
    return <RedditEmbedPreview postUrl={embed.renderer.postUrl} />
  }

  if (embed.renderer.type === "tiktok_client") {
    return <TikTokEmbedPreview shareUrl={embed.renderer.shareUrl} />
  }

  if (embed.renderer.type === "link") {
    return <a href={embed.renderer.href}>{embed.displayUrl}</a>
  }

  return <p>{embed.renderer.message}</p>
}

Reddit resolves to reddit_client: the package fetches postUrl + ".json" in the browser. For a fully custom card, call fetchRedditPost(postUrl) from embed-card/manual and shape the JSON yourself.

TikTok vm.tiktok.com links resolve to tiktok_client: render TikTokEmbedPreview with shareUrl, or call fetchTikTokVideoIdFromOEmbed(shareUrl) from embed-card/manual if you only need the numeric video id for your own iframe.

Why this export matters

  • Design systems can keep their own primitives
  • Teams can wire analytics around embed decisions
  • Framework adapters can share the same provider registry logic

For a full React integration that still uses the default card UI, prefer EmbedCard or the starter apps instead of re-implementing every renderer by hand.