Skip to content

Embed Host Integration

This page is for the main-site host that embeds a generator page through iframe and needs to coordinate with @atomm-developer/generator-workbench in ?mode=embed.

If you are changing the generator shell itself, read Generator Workbench first. If you are changing the parent page that owns the iframe, read this page.

What Changes In mode=embed

When the embedded generator URL contains ?mode=embed, generator-workbench changes in two important ways:

  1. It hides shell-owned platform UI inside the iframe, including .app-topbar and #sidebar-footer.
  2. It starts an iframe bridge and exchanges postMessage events with the host page.

The runtime, export, template, and bridge capabilities still exist. Only the shell chrome is reduced.

Host Checklist

The host page should update all of the following:

  1. Append mode=embed to the iframe URL.
  2. Register the host-side message listener before relying on any bridge command.
  3. Wait for generator_pageLoaded before flushing template or state payloads.
  4. Prefer generator_loadTemplateData for template bootstrap.
  5. Keep generator_setGeneratorData for runtime snapshot restore.
  6. Handle success and error events from the iframe.

Do Not Use iframe.onload As Bridge Ready

iframe.onload only means the browser finished loading the page resource. It does not guarantee that generator-workbench has already mounted the runtime and attached the bridge listener.

For bridge commands, the only ready signal is:

  • generator_pageLoaded

The iframe sends this event only after the bridge listener has been attached.

Use this order:

  1. Create the iframe URL with mode=embed.
  2. Register the parent-page message listener.
  3. Cache outgoing bridge payloads locally.
  4. Wait for generator_pageLoaded.
  5. Flush the cached payloads.
  6. Wait for response events such as generator_toTemplateLoaded.

Minimal Host Example

js
const iframe = document.querySelector('#generator-frame')
const iframeOrigin = new URL(iframe.src, window.location.href).origin

const pendingMessages = []
let bridgeReady = false

function postToWorkbench(type, data) {
  const payload = { type, data }

  if (!bridgeReady) {
    pendingMessages.push(payload)
    return
  }

  iframe.contentWindow?.postMessage(payload, iframeOrigin)
}

function flushPendingMessages() {
  while (pendingMessages.length > 0) {
    const payload = pendingMessages.shift()
    iframe.contentWindow?.postMessage(payload, iframeOrigin)
  }
}

window.addEventListener('message', (event) => {
  if (event.origin !== iframeOrigin) {
    return
  }

  const message = event.data || {}

  switch (message.type) {
    case 'generator_pageLoaded':
      bridgeReady = true
      flushPendingMessages()
      return

    case 'generator_toTemplateLoaded':
      console.log('template applied', message.data)
      return

    case 'generator_toSelectTemplate':
      console.log('runtime selected template', message.data)
      return

    case 'generator_toTemplateError':
      console.error('bridge template error', message.data)
      return

    case 'generator_toFile':
      console.log('file payload', message.data)
      return
  }
})

postToWorkbench('generator_loadTemplateData', {
  title: 'Pendant 140x128',
  template: {
    type: 'generator-template',
    version: '1.0.0',
    generatorId: 'pendant-generator',
    defaults: {
      meta: {
        generatorId: 'pendant-generator',
        schemaVersion: '1.0.0',
      },
      params: {
        height: 150,
        width: 128,
      },
      version: '1.0.0',
    },
  },
})

Which Command To Use

Prefer generator_loadTemplateData

Use generator_loadTemplateData when the host wants to apply template data into the current generator runtime.

Why this is the preferred bootstrap path:

  • it maps directly to sdk.template.applyToRuntime(...)
  • it returns generator_toTemplateLoaded
  • it is easier to retry safely
  • it matches the workbench template import behavior

Use generator_setGeneratorData Carefully

Use generator_setGeneratorData when the host wants to restore runtime snapshot-like data through runtime.setState(...).

Important behavior:

  • it does not emit a dedicated success ack event
  • if it fails, the iframe reports generator_toTemplateError with action: 'setGeneratorData'
  • because there is no success ack, it is less suitable as the primary template bootstrap command

Event Table

DirectionEventHost action
iframe -> hostgenerator_pageLoadedMark bridge ready and flush queued payloads
host -> iframegenerator_loadTemplateDataApply template data into workbench
iframe -> hostgenerator_toTemplateLoadedTreat template bootstrap as completed
host -> iframegenerator_setGeneratorDataRestore runtime snapshot data
iframe -> hostgenerator_toTemplateErrorHandle template or state bridge failure
iframe -> hostgenerator_toSelectTemplateReceive runtime-reported template selection
host -> iframegenerator_getTemplateDataPull current template from the iframe
iframe -> hostgenerator_toTemplateDataRead pulled template payload
host -> iframegenerator_getFileAsk the iframe for export data
iframe -> hostgenerator_toFileConsume returned file payload
iframe -> hostgenerator_toFileErrorHandle export bridge failure

New Runtime-Side Contract

If the runtime inside the iframe needs to tell the main site that the user clicked a template card, it can now emit:

ts
emit({
  type: 'select_template',
  data: {
    name: 'Spring Sale',
    category: 'marketing',
  },
})

When the route is ?mode=embed, generator-workbench automatically forwards it to the parent page bridge as:

  • generator_toSelectTemplate

Error Handling Recommendations

  • Log all generator_toTemplateError and generator_toFileError events in the host.
  • Add a timeout around generator_loadTemplateData and treat missing generator_toTemplateLoaded as a failed bootstrap attempt.
  • If the host sends commands before generator_pageLoaded, keep them in memory and retry only after ready arrives.
  • Use ?bridgeDebug=1 temporarily on the iframe URL during integration debugging.

Suggested Host Migration

If your current host logic sends data immediately after creating the iframe, migrate it in this order:

  1. Move the parent-page message listener registration earlier.
  2. Add a local pending queue for outbound bridge payloads.
  3. Gate payload flushing on generator_pageLoaded.
  4. Convert template bootstrap from generator_setGeneratorData to generator_loadTemplateData where possible.
  5. Keep generator_setGeneratorData only for real runtime snapshot restore cases.

MIT Licensed