Media
Embed for cross-page block reuse, Video for any video provider, LightboxImage for click-to-zoom.
~ 2 min read
| Component | Use for |
|---|---|
<Embed> | Reuse a labeled block from another page (cross-page transclusion) |
<Video> | YouTube / Vimeo / mp4 — auto-detects provider, lazy-loads |
<LightboxImage> | Click-to-zoom image — used by default for inline <img> |
Embed
Cross-page block reuse. Tangly’s manifest extracts blocks during build (anything between two headings, optionally with an explicit {#id} marker) so you can pull a section into another page without copy-paste drift.
| Prop | Type | Default | Description |
|---|---|---|---|
page | string | — | Page slug (no leading slash) |
block | string | — | Heading ID or explicit {#id} marker on the source page |
<Embed page="reference/billing" block="rate-limits" />Embedded blocks render as Markdown only — no MDX/JSX. This keeps the cycle invariant honest: there’s no way for an embed to load another embed at render time. Build fails with a trail (a#one → b#two → a#one) when a cycle is detected.
For full authoring guidance — when to embed vs duplicate vs link — see Embedded blocks.
Video
Universal video block. Detects the provider from src:
- YouTube (
youtube.com/watch,youtu.be/...) →youtube-nocookie.comiframe - Vimeo (
vimeo.com/...) → Vimeo player iframe - Direct file (
.mp4,.webm,.mov,.m4v) → native<video>with controls - Anything else → generic iframe
Iframes load lazily via IntersectionObserver — no embed traffic until the player enters the viewport.
| Prop | Type | Default | Description |
|---|---|---|---|
src | string | — | Video URL or path |
poster | string | — | Image shown until the iframe loads |
transcript | string | — | Path to a transcript file — rendered as a link below the player |
title | string | "Embedded video" | Accessible title |
YouTube
<Video src="https://www.youtube.com/watch?v=dQw4w9WgXcQ" />Vimeo
<Video src="https://vimeo.com/123456789" />Self-hosted mp4
<Video
src="/videos/demo.mp4"
poster="/videos/poster.jpg"
transcript="/transcripts/demo.txt"
title="Tangly install demo"
/>LightboxImage
Click-to-zoom wrapper around a regular <img>. Tangly’s MDX renderer wraps every inline image in <LightboxImage> by default — so  already gives you a lightbox.
| Prop | Type | Default | Description |
|---|---|---|---|
src | string | — | Image URL |
alt | string | "" | Accessible alt text |
width | number | string | — | Native width attribute |
height | number | string | — | Native height attribute |
lightbox | boolean | true | Set false to opt out — renders a plain <img> instead |
Default (lightbox on)
Inline images in MDX get the lightbox treatment automatically:
Click the image — it opens fullscreen. Esc or outside-click closes.
Plain image (no lightbox)
<LightboxImage src="/images/tangly-icon.png" alt="Tangly icon" lightbox={false} />For inline <img> written in plain Markdown, opt out by wrapping in a <Frame> (the frame variant reads lightbox={false} from its props). The <LightboxImage> component itself isn’t auto-injected as a JSX tag — author images as Markdown and they get the lightbox via the default img mapper.