Embed Script

The Inlay embed script is a self-contained IIFE served from Inlay's servers. Publishers include a single <script async> tag; all logic lives server-side so updates ship without publisher action.

Overview

The embed tag installs a tiny JavaScript runtime on the publisher's page. On each page load, the script:

  1. Detects any _inlay_preview query parameter (preview mode)
  2. Fingerprints the page's DOM structure near the target selector
  3. POSTs to the serve endpoint with the page URL, DOM snapshot, and optional preview token
  4. If a response with available: true is received, injects the rendered HTML into the DOM
  5. If isPreview: true, also renders the floating approval panel

The script is an ES5-compatible IIFE (immediately-invoked function expression) with no external dependencies. It uses only standard browser APIs: fetch, URLSearchParams, and document.querySelector.

Script endpoint

GET/api/script/{siteScriptId}

Returns the full embed script as application/javascript. The script content is dynamically generated per-site (the serve endpoint URL and preview approve URL are baked in).

Path parameters

ParamTypeDescription
siteScriptIdstringUnique identifier for the site. Found on the site detail page in the dashboard.

Response headers

http
Content-Type: application/javascript; charset=utf-8
Cache-Control: public, max-age=3600, must-revalidate
Access-Control-Allow-Origin: *

If the siteScriptId does not correspond to a known site, the endpoint returns a 404 with a comment:

javascript
// Inlay: site not found

What the script does

Placement detection

The script POSTs to /api/serve/[siteScriptId] with { url: location.href, domStructure: ... }. The serve endpoint performs URL pattern matching server-side. If no placement matches, the script receives { available: false } and exits silently.

Ad injection

When available: true, the response includes:

  • html — server-rendered HTML string (template + creative merged)
  • selector — CSS selector of the target element
  • position"before" or "after"
  • placementId — used for impression and click tracking
  • beaconUrl — URL for firing impression beacons
  • impressionTrackers — array of third-party impression pixel URLs

The script creates a wrapper <div>, sets its innerHTML to the rendered HTML, and inserts it before or after the target element.

DOM fingerprinting

Before making the serve request, the script captures a DOM fingerprint — a snapshot of the HTML structure near the target selector — and sends it as domStructure in the request body:

json
{
  "url": "https://example.com/blog/my-post",
  "domStructure": {
    "selector": "article .content p",
    "position": "after",
    "count": 8,
    "samples": [
      "<p class="body-text">The first paragraph of the article...</p>",
      "<p class="body-text">The second paragraph continues...</p>"
    ]
  }
}

This snapshot is used by the AI on the first visit to generate a template that matches the surrounding content. On subsequent visits (after template generation), the serve endpoint ignores the domStructure field.

Preview mode

If the page URL contains a _inlay_preview query parameter, the script extracts its value and includes it as previewTokenin the serve request body. The serve endpoint routes the request through the preview branch, bypassing URL matching and auction logic. See Preview & Approval for the full flow.

Caching

The script is served with a 1-hour browser cache (max-age=3600). The must-revalidate directive ensures that after expiry, the browser fetches a fresh copy rather than serving stale content. When Inlay pushes a script update, publishers automatically receive it within one hour.

The script URL includes the siteScriptId, so Inlay can serve a site-specific version (with baked-in serve URL) while still using CDN caching effectively.