Web Component
Use the same package from Vue, Svelte, Astro, or plain HTML with the custom element export.
Web Component
If the host app is not React-first, register the custom element:
import { registerEmbedCard } from "embed-card/web-component"
registerEmbedCard()Then use it anywhere HTML is allowed:
<embed-card
url="https://www.google.com/maps?q=Tokyo+Station&output=embed"
accent-color="#0f766e"
radius="26px"
></embed-card>The shadow attribute is optional (same as theme.shadow in React). Omit it for no drop shadow, or set it to any CSS box-shadow value (for example 0 20px 60px rgba(15, 23, 42, 0.12)).
For fallback link previews (URLs that do not match a built-in provider), the cta-label attribute overrides the default Open original label inside the card. It has no effect on iframe or Reddit embeds.
<embed-card url="https://example.com" cta-label="Visit site"></embed-card>Styling the shadow tree
The embed surface is a <figure class="root" part="root">. Expose one part for host-page CSS:
| Part | Element |
|---|---|
root | The card surface root (<figure>) |
embed-card::part(root) {
border-radius: 18px;
}Older releases exposed additional shadow parts (header, footer, preview); those are removed—style ::part(root) or rely on attributes and CSS variables from Custom Rendering → Theming reference.
Dark mode
The appearance attribute controls the embed surface palette — the same three values as the React theme.appearance prop:
<!-- always dark -->
<embed-card url="..." appearance="dark"></embed-card>
<!-- always light (default) -->
<embed-card url="..." appearance="light"></embed-card>
<!-- follow OS preference; re-renders when prefers-color-scheme changes -->
<embed-card url="..." appearance="system"></embed-card>When appearance="system" the element subscribes to matchMedia("(prefers-color-scheme: dark)") and re-renders automatically on OS theme changes. The listener is removed in disconnectedCallback so there are no leaks.
Good fit for
- Vue apps that want a tiny integration surface
- Svelte or Astro pages with isolated embeds
- CMS-driven frontends rendering HTML fragments
- Plain JS projects that still want the package logic
Runnable examples
Starter apps that call registerEmbedCard() and render <embed-card> are in examples/vue-vite, examples/svelte-vite, and examples/vanilla-vite. See Getting Started for how to run or copy them.
Reddit inside the shadow root
For Reddit thread URLs, the custom element shows a skeleton first, then hydrates the shadow tree with the same JSON-driven card as React: it fetches the public .json endpoint and replaces the mount region with markup built in the component (no redditmedia iframe).