Docs menu
Guides
Live embeds
Load embeds of sites you trust in a sandboxed iframe.
Embeds render as preview cards by default: many sites refuse to be framed, and an embedded page runs its own scripts. Pass embeds to load the sites you trust live, in a sandboxed iframe with the caption below.
<NotionRenderer blocks={blocks} embeds={["codepen.io", "figma.com", "loom.com"]} />embeds takes an EmbedPolicy, exported from notionic:
- A list of hosts. A listed host includes its subdomains, so
figma.commatcheswww.figma.combut notnotfigma.com. Hosts match ignoring case. trueloads every embed.- A function gets the embed's URL and returns whether it loads:
<NotionRenderer blocks={blocks} embeds={(url) => url.startsWith("https://codepen.io/your-name/")}/>It's off by default, so embeds stay cards until you opt in. Only http(s) URLs are ever framed, and an embed of …/demos/<name> that matches one of your Interactive demos renders the demo instead.
The iframe is 16:9 with the same outline as a YouTube video. To set its height instead, add ?height= in pixels to the embed URL, as for demos: with embeds={["sanding.space"]}, an embed of https://www.sanding.space/demos/surface?height=600 renders 600px tall. Heights are whole numbers from 1 to 9999; anything else keeps 16:9. The URL isn't rewritten, so height also reaches the embedded page, which most sites ignore.
It loads lazily and sends a strict referrer. Its title is the caption, or the page's title from fetchBlocks. It's sandboxed to allow scripts, forms, popups and presentation, which most embeds need to work.
A fixed height clips content that grows, or that wraps taller on a phone. If you run the embedded site, let it report its own height: post { type: "notionic:resize", height } to the parent, and the frame becomes that many pixels tall.
new ResizeObserver(([entry]) => { const height = Math.ceil(entry.borderBoxSize[0].blockSize) window.parent.postMessage({ type: "notionic:resize", height }, "*")}).observe(document.documentElement)- Starting size.
?height=, or 16:9, holds until the first message. - Heights are rounded, at least 1px and at most 9999px. Anything that isn't a positive number is ignored.
- Who can resize. A message counts only from one of the page's live embed frames, and from an origin
embedsallows. With a host list, subdomains count too, so asanding.spaceembed that redirects towww.sanding.spacestill resizes. A function can't run in the browser, so with one only the embed URL's own origin counts: embed a redirecting URL by its final address. - What it costs. A page with live embeds ships a small listener for these messages; pages without them ship nothing new. Demos aren't iframes, so they don't use it.
A page framed from your own origin with both scripts and same-origin access can lift its sandbox. Embed your own components as Interactive demos instead.
A site that refuses to be framed shows an empty box, so try an embed before you list its host.