Embeds API
API Reference: Engine · Types · Storage · Events · Security · Servers · Placement · Lightbox · Lens · This Page · Coordinators · Config Registry
Iframe rendering for rich media (YouTube, Vimeo, Spotify, CodePen, CodeSandbox) with consent management and provider detection.
See also: Cookbook: Embeds for usage patterns.
Quick start
import { createEmbed } from 'alap';
const el = createEmbed('https://youtu.be/dQw4w9WgXcQ', 'video', {
embedPolicy: 'prompt',
});
document.body.appendChild(el);createEmbed(url, embedType?, options?)
DOM builder for embed iframes. Returns one of three results depending on policy and consent:
- Iframe wrapper — for allowlisted domains with consent
- Consent placeholder — clickable prompt that replaces itself with an iframe on click
- Plain link — fallback for unknown domains or blocked policy
function createEmbed(
url: string,
embedType?: EmbedType,
options?: AlapEmbedOptions,
): HTMLElementAlapEmbedOptions
| Option | Type | Default | Description |
|---|---|---|---|
embedPolicy | EmbedPolicy | 'prompt' | Consent policy for this embed |
embedAllowlist | string[] | all providers | Restrict to these domains only |
maxWidth | number | none | Maximum iframe width |
maxHeight | number | none | Maximum iframe height |
Provider functions
matchProvider(url)
Finds the matching provider for a URL.
function matchProvider(url: string): EmbedProvider | null
matchProvider('https://youtu.be/abc123') // → YouTube provider
matchProvider('https://example.com/random') // → nulltransformUrl(url)
Transforms a public URL to an embeddable iframe src.
function transformUrl(url: string): string | null
transformUrl('https://youtu.be/dQw4w9WgXcQ')
// → 'https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ'
transformUrl('https://vimeo.com/123456')
// → 'https://player.vimeo.com/video/123456'
transformUrl('https://example.com')
// → nullisAllowlisted(url, customAllowlist?)
Checks if a URL is from an allowlisted provider. If customAllowlist is provided, only those domains are considered.
function isAllowlisted(url: string, customAllowlist?: string[]): booleangetEmbedHeight(url)
Gets the appropriate iframe height for a URL. Spotify playlists and albums get a taller player than individual tracks.
function getEmbedHeight(url: string): numberConsent management
Consent is stored per-domain in localStorage. The EmbedPolicy controls behavior:
| Policy | Behavior |
|---|---|
'prompt' | Privacy-first (default): Shows a placeholder and only loads the iframe after the user clicks to grant consent. |
'allow' | Always load for allowlisted domains |
'block' | Never load; ignores stored consent |
Functions
function shouldLoadEmbed(domain: string, policy: EmbedPolicy): boolean
function grantConsent(domain: string): void
function revokeConsent(domain: string): void
function hasConsent(domain: string): booleanExample: consent flow
import { shouldLoadEmbed, grantConsent, hasConsent } from 'alap';
// Check before loading
if (shouldLoadEmbed('youtube.com', 'prompt')) {
// User previously granted consent, load iframe
}
// Grant consent (persists in localStorage)
grantConsent('youtube.com');
// Check consent directly
hasConsent('youtube.com'); // → true
// Revoke
revokeConsent('youtube.com');Types
EmbedType
type EmbedType = 'video' | 'audio' | 'interactive';EmbedPolicy
type EmbedPolicy = 'prompt' | 'allow' | 'block';EmbedProvider
interface EmbedProvider {
name: string; // e.g. "YouTube"
domains: string[]; // matching domains (www stripped)
transform: (url: string) => string | null; // public URL → iframe src
defaultType: EmbedType;
defaultHeight: number; // iframe height in px
}Supported providers
| Provider | Domains | Type | Transform |
|---|---|---|---|
| YouTube | youtube.com, youtu.be | video | youtube-nocookie.com/embed/{id} |
| Vimeo | vimeo.com | video | player.vimeo.com/video/{id} |
| Spotify | open.spotify.com | audio | open.spotify.com/embed/{type}/{id} |
| CodePen | codepen.io | interactive | codepen.io/{user}/embed/{id} |
| CodeSandbox | codesandbox.io | interactive | codesandbox.io/embed/{id} |
YouTube uses the youtube-nocookie.com domain for privacy-enhanced embedding.
Security posture
Embeds are scoped by three layers working together:
- Provider allowlist.
isAllowlisted()gates which URLscreateEmbedaccepts. The built-in list covers only the supported providers above; extend it per-page via thecustomAllowlistargument if needed. - Per-domain consent.
createEmbedreturns a placeholder untilgrantConsent(domain)opts in — domain by domain, revocable at any time. - Iframe hardening. Iframes render with
referrerpolicy="strict-origin-when-cross-origin",loading="lazy", and a lockedallowattribute scoped to the providers' oembed needs.sandboxis intentionally not set — several providers fail in sandboxed iframes; hardening relies on theallowpolicy and the provider allowlist instead. See Security in the cookbook for the full list.
Embeds are protected by Alap's standard URL sanitization. For more on how Alap ensures that data from different sources is handled safely, see our Security Trust Model.