Embeds
Put a product's order form, or any store page, on another website. The frame sizes itself, follows the site's theme and tells the site about each order.
An embed shows a product or a store page inside an <iframe> on any other website: a blog,
a WordPress or Blogger site, a link-in-bio page. The shopper orders without leaving that site.
Helium serves every embed. It owns the frame (sizing, theme, links, framing rules, the order message); the store's template and the merchant own what is inside.
Add one to a site
Two lines, on any page:
<feeef-embed product-id="your-product" theme-mode="auto"></feeef-embed>
<script src="https://your-store.feeef.store/_h/embed.js" async></script>embed.js defines the <feeef-embed> element: a frame that is always exactly as tall as its
content, with no scroll bar inside. It is about 2 KB gzipped, has no dependencies, and works for
elements added later (single-page sites, page builders). product-id takes the product's id or
its slug; the store is the one that served the script.
Without the script, a plain frame works too; it keeps a fixed height and scrolls inside:
<iframe src="https://your-store.feeef.store/embed/products/your-product"
style="width:100%;height:640px;border:0" allow="geolocation"></iframe>What can be embedded
| URL | Shows |
|---|---|
/embed/products/<slug> | The product's order form: its options, offers and add-ons, the customer fields, the summary and the order button, across the whole width, then a small "Protected by feeef" line |
/embed/pages/<slug> | A published store page (an offer, a product landing page, a banner) |
No gallery, title or price by default: the site around the embed already shows the product. An unknown product or page, or a store that turned embeds off, shows the not-found page.
After an order, the thanks page opens inside the frame (/embed/thanks); the site's own page
never changes.
Attributes
| Attribute | Values | Default |
|---|---|---|
product-id | a product's id or slug | shows that product's order form |
page | a store page's path (summer-offer) | shows that page instead |
store | the store's host (your-store.feeef.store, or its own domain) | the store that served embed.js; set it when one page shows products from several stores |
src | a full /embed/... URL | instead of the three above |
theme-mode | light, dark, auto | auto: follows the site (its data-theme, a dark class, color-scheme, then the visitor's system) and keeps following when the site switches |
variant | the name of a first-level option (Red) | none; preselects that option |
quantity | 1–99 | none; preselects the quantity |
background | surface, transparent | surface; transparent lets the site's background show through |
height | pixels | 600; the height before the frame reports its own |
label | text | the page title; the frame's accessible name |
Changing theme-mode or variant updates the frame in place; changing any other attribute loads
the new embed. On a plain frame, theme, bg, variant and qty are query parameters.
Listen to orders
Every message from the frame is a DOM event on its container, so the site can count a sale in its own analytics or ad pixel:
| Event | When | detail |
|---|---|---|
feeef:ready | The frame's page is ready (again after each page in the frame) | { height, title } |
feeef:resize | Its content height changed | { height } |
feeef:order | An order was saved | { orderId, total, currency, items: [{ productId, quantity, price }] } |
feeef:navigate | A link left the embed (it opens in a new tab) | { url } |
feeef:overlay | A full-screen view (photos, a dialog) opened or closed; the frame covers the page meanwhile | { open } |
Only the page that loaded embed.js receives order and navigate: the frame sends them to the
origin that greeted it, never to *. Bot orders caught by the store's protection never send
order.
JavaScript API
Which sites may show your embeds
By default any site may. A store can turn embeds off or limit them to its own sites in
configs.embed:
{ "configs": { "embed": { "enabled": true, "allowedHosts": ["blog.example.com", "*.myshop.dz"] } } }Up to 20 hostnames; *. covers subdomains. With a list, browsers refuse to show the embed
anywhere else (frame-ancestors). Every other page of a store (home, products, checkout) can only
be framed by the store itself.
Orders from embeds
- They go through the normal checkout, so Order protection treats them as orders from the store's own page.
- Their
sourceisembed, andmetadata.attribution.embedHostnames the site that showed the embed: merchants see which sites sell. UTM tags on the embed URL are kept like on any page. - The embed is the store's own order form, so the store's ad pixels (Meta, TikTok, Snapchat) see
the visit, the lead and the purchase like on the store, and server-side conversions go out too,
deduplicated with the browser events. Some browsers limit pixel cookies inside frames; the
server-side conversions cover that. The site can also fire its own pixel from
feeef:order.
Design the embed in a template
Embeds render in the embed layout: the template's app/layouts/embed.tsx when it ships one,
otherwise its default layout with every slot left empty (its styles, fonts and theme stay; its
header and footer go). Style embeds with html[data-embed]:
html[data-embed] .my-hero { display: none; }
html[data-embed][data-theme="dark"] .my-card { background: #111; }The "Protected by feeef" line is the core block core/feeef-credit: any page can place it, and a
template's own embed design can move it or leave it out.