Embed documentation

Embed WebDYI widgets anywhere.

Everything you need to integrate WebDYI: URL pattern, embed snippets, oEmbed endpoint, Open Graph + Twitter Card meta, sandbox model, caching.

URL pattern

Public widget URLs follow this pattern:

https://cdn.webdyi.com/w/{instanceId}

{instanceId} is a UUID identifying one user-customized widget instance. Each customer-customized version of a developer's template is its own instance with its own URL.

Sample: cdn.webdyi.com/w/ceaf0f1d-8ff1-41aa-b779-f295fe0765b2

Embed snippet

Paste this anywhere an iframe is allowed (blog posts, CMSes, dashboards):

<iframe src="https://cdn.webdyi.com/w/{instanceId}"
        title="WebDYI widget"
        loading="lazy"
        style="width:100%;height:400px;border:0;border-radius:8px"></iframe>

The widget content runs in a nested sandboxed <iframe srcdoc> inside the page (with no allow-same-origin → opaque origin), so it is fully isolated from any host page that embeds it.

Responsive variant

<div style="position:relative;width:100%;padding-bottom:56.25%;overflow:hidden;border-radius:8px">
  <iframe src="https://cdn.webdyi.com/w/{id}"
          title="WebDYI widget"
          loading="lazy"
          style="position:absolute;inset:0;width:100%;height:100%;border:0"></iframe>
</div>

Discovery (oEmbed + Open Graph + Twitter Card)

The widget page is fully server-side rendered. All discovery metadata is in the static HTML response — no JavaScript execution required for crawlers / link-preview tools to extract it.

Open Graph + Twitter Card meta (in <head>)

<title>{template name}</title>
<link rel="canonical" href="https://cdn.webdyi.com/w/{id}">
<meta name="description" content="An interactive WebDYI widget — {template}.">

<meta property="og:type" content="website">
<meta property="og:site_name" content="WebDYI">
<meta property="og:title" content="{template}">
<meta property="og:description" content="An interactive WebDYI widget.">
<meta property="og:url" content="https://cdn.webdyi.com/w/{id}">
<meta property="og:image" content="https://cdn.webdyi.com/livecodes/assets/images/android-chrome-512x512.png">

<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{template}">
<meta name="twitter:description" content="An interactive WebDYI widget.">
<meta name="twitter:image" content="https://cdn.webdyi.com/livecodes/assets/images/android-chrome-512x512.png">

oEmbed auto-discovery — two paths

HTML <link> in <head>:

<link rel="alternate"
      type="application/json+oembed"
      href="https://cdn.webdyi.com/oembed?url={encoded widget URL}"
      title="{template}">

HTTP Link header (same content, for crawlers that prefer headers):

Link: <https://cdn.webdyi.com/oembed?url={encoded}>; rel="alternate"; type="application/json+oembed"; title="{template}"

oEmbed endpoint

GET https://cdn.webdyi.com/oembed?url={encoded widget URL}[&maxwidth=N][&maxheight=N][&format=json]
  • format: only json is supported.
  • maxwidth / maxheight: optional; defaults to 800 × 400.
  • CORS: Access-Control-Allow-Origin: *.

Sample response:

{
  "success": true,
  "type": "rich",
  "version": "1.0",
  "provider_name": "WebDYI",
  "provider_url": "https://webdyi.com",
  "title": "Carousel",
  "width": 800,
  "height": 400,
  "html": "<iframe src=\"https://cdn.webdyi.com/w/...\" title=\"Carousel\" loading=\"lazy\" style=\"border:0;width:100%;height:400px;border-radius:8px\"></iframe>"
}

Editor and customizer URLs (app.webdyi.com/?instance=…&customize=only, app.webdyi.com/?embed=true&view=split) carry secret tokens and are not oEmbed-discoverable — only /w/:id widget URLs return rich oEmbed responses.

Sandbox & security model

WebDYI widgets are nested-iframe sandboxed for safety:

  1. The outer iframe (the embed) loads cdn.webdyi.com/w/{id} — a tiny static HTML shell from WebDYI's CDN subdomain. Cookieless host, isolated from app.webdyi.com.
  2. The shell contains a nested <iframe srcdoc> with the user's widget content. This iframe uses sandbox="allow-scripts allow-popups allow-popups-to-escape-sandbox allow-forms allow-modals allow-presentation" — notably without allow-same-origin, giving the widget code an opaque origin.
  3. The "Made with WebDYI" badge (free-tier only) lives in the shell, outside the sandboxed iframe — widget JS can't remove it.

Net effect: a widget loading on any host page (Notion, Medium, your blog) cannot access the host page's cookies, storage, or DOM, and cannot reach into cdn.webdyi.com's storage either.

Caching

Cache-Control: public, max-age=60, stale-while-revalidate=86400
X-Content-Type-Options: nosniff

Widget content updates within ~60s of a client save (precompiled HTML is written back to the backend on save; the next edge cache miss picks it up).

Integration examples

Iframely-powered surfaces (Notion, Medium, Confluence, Ghost, dev.to, …)

Just paste the URL https://cdn.webdyi.com/w/{id}. Iframely's crawler will follow the oEmbed link and render the widget inline. No special embed code needed.

WordPress / static site generators

Paste the iframe snippet directly into your post HTML.

React

function WebdyiWidget({ id, height = 400 }) {
  return (
    <iframe
      src={`https://cdn.webdyi.com/w/${id}`}
      title="WebDYI widget"
      loading="lazy"
      style={{ width: "100%", height, border: 0, borderRadius: 8 }}
    />
  );
}

Provider summary

Provider name WebDYI
Provider URL https://webdyi.com
App https://app.webdyi.com
Widget CDN https://cdn.webdyi.com
Canonical pattern https://cdn.webdyi.com/w/{instanceId}
Discovery oEmbed (HTML + Link header) + Open Graph + Twitter Card
Server-side rendered Yes (no JS required for meta extraction)
Embed type Rich (sandboxed iframe)

Got questions?

Tell us where you're trying to embed and what's not working — we'll dig in.