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: onlyjsonis 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:
-
The outer iframe (the embed) loads
cdn.webdyi.com/w/{id}— a tiny static HTML shell from WebDYI's CDN subdomain. Cookieless host, isolated fromapp.webdyi.com. -
The shell contains a nested
<iframe srcdoc>with the user's widget content. This iframe usessandbox="allow-scripts allow-popups allow-popups-to-escape-sandbox allow-forms allow-modals allow-presentation"— notably withoutallow-same-origin, giving the widget code an opaque origin. - 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) |