<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=2191750074375425&amp;ev=PageView&amp;noscript=1">
Skip to content
  • There are no suggestions because the search field is empty.

Embedding Options - Technical Details

Every BetterUnite campaign publishes a set of public web pages. Each page has a stable URL, a QR code that resolves to that URL, and an embed code that places the page inside your own website. This article covers all three, including the details a web developer or IT administrator needs before touching a production site: the markup, the query string parameters, the browser and network requirements, and how the embed behaves behind a content security policy.

Everything described here is generated for you. From your campaign dashboard, open Links / Embed / QR. The dialog has tabs for Links, Share, QR Codes and Embed Codes, plus Embedded Forms on online fundraisers and online forms. Copy from that dialog rather than retyping from this article, because the generated code already contains your organization and campaign identifiers.

Page URLs

Public pages are served from https://app.betterunite.com over TLS, and HTTP requests are redirected to HTTPS. URLs use readable routes rather than numeric identifiers. Paths below are relative to that domain:

Page Path
Campaign page /{campaign}
Checkout or registration /{campaign}/donate
Auction /{campaign}/auction
Event offers /{campaign}/eventitems
Raffle /{campaign}/eventitems?raffle=1
RSS feed of donations /{campaign}/feed
Guest check-in, for staff /{org}/campaign/{campaign}/manageparticipants

The route is set when the campaign is created and stays fixed, so links printed months in advance keep working. Activating a campaign does not change its URLs.

Short links

The Links tab also offers a shortened form on the bnte.us domain, shaped as https://bnte.us/sc/{code}. It is a server side HTTP redirect to the full URL. If your organization filters outbound traffic by domain, allow bnte.us alongside app.betterunite.com, or publish the full URL instead.

Source tracking with tags

Append a tags parameter to any campaign link and every resulting gift is tagged automatically in your donor records. Multiple tags are comma delimited:

/{campaign}?tags=springmailer /{campaign}?tags=board,newsletter

This is BetterUnite's own attribution, independent of Google Analytics. You can add utm_ parameters to the same URL if your analytics platform expects them. Unrecognized query parameters are ignored by the page, so the two schemes coexist safely.

QR codes

QR codes are generated on demand by the server, not stored as files. Any supported page URL becomes a QR image by adding qr=1 to its query string:

https://app.betterunite.com/{campaign}?qr=1&w=300&h=300
Parameter Meaning Default
qr=1 Return a QR image instead of the web page Off
w Width in pixels 300
h Height in pixels 300

Technical characteristics

  • Format. PNG, returned with an image content type. Because the URL itself returns the image, you can reference it directly from an img tag, a mail merge or a print template instead of downloading and hosting a copy.
  • Error correction. Level Q, which restores roughly 25 percent of the code. That tolerance is what lets a printed code survive a fold, a scuff, or a small logo placed over the center.
  • Encoded payload. The plain destination URL and nothing else. There is no tracking redirect in between, so the code cannot expire or be revoked, and the destination shows in the scanner's preview. Scan counts are therefore not reported. Add a tags or utm_source parameter to the encoded URL if you need to attribute traffic to a printed piece.
  • Stability. The code encodes the URL, and the URL does not change, so a downloaded code stays valid indefinitely.

Print guidance

Request the pixel dimensions you actually need rather than scaling a small image up in a layout program. A useful rule for print is 10 pixels per millimeter of finished size, so a code printed 30 mm square should be requested at w=300&h=300 or larger. Two further constraints matter:

  • Minimum size. About 25 mm (1 inch) square for a code scanned at arm's length, scaling up with distance. A banner code read from 3 meters away needs to be roughly 300 mm square.
  • Quiet zone. The returned image includes the white margin the specification requires. Do not crop it, and keep that white border intact over dark or patterned backgrounds.

Print dark on light. Inverted codes fail on a significant share of scanning apps.

Which embed option to use

There are three ways to place BetterUnite content in your own site. They differ in how much control the host page keeps.

  • Script embed, recommended. You add a container div and one script tag. The frame resizes itself as the visitor moves through checkout. Works on most sites, including WordPress, Squarespace and Drupal.
  • Embedded URL. You use a supplied URL in your own iframe or CMS embed component, and control the height yourself. Best for teams with an existing framework.
  • Direct link. An ordinary hyperlink or button. The simplest and most reliable option, and the best experience on mobile.

If a site is locked down, runs an aggressive consent manager, or is served where third party frames are blocked, a direct link is not a fallback so much as the correct answer. Nothing about the donor experience is lost by sending someone to a full page.

The script embed

This is what the Embed Codes tab produces. There are two variants, one for the full campaign page and one for checkout only. Each is a container plus one script tag:

<!-- Campaign page --> <div id="bu-checkout"></div> <script src="https://app.betterunite.com/embedjs?u=https://app.betterunite.com/{campaign}?embedded=true"></script>
<!-- Checkout only --> <div id="bu-checkout"></div> <script src="https://app.betterunite.com/embedjs?u=https://app.betterunite.com/{campaign}/donate?embedded=true"></script>

What the script does

The /embedjs endpoint is not a library. It returns a few lines of JavaScript, generated for the URL you passed, that run once and then do nothing further. Specifically it:

  1. Finds the container element, by default bu-checkout, skipping any container that already holds a BetterUnite frame. Several embeds can therefore sit on one page even when a CMS repeats the same id.
  2. Creates an iframe pointing at the URL you passed, at full width with no border.
  3. Sets allow="payment; publickey-credentials-get" on that frame. Without this permissions policy delegation the browser blocks Apple Pay, Google Pay, and the PayPal and Venmo buttons inside the frame.
  4. Listens for height messages posted by the embedded page and resizes the frame to match. It checks both the message source and the origin, so one embed cannot resize another.

The script sets no cookies on your domain, sends no analytics beacons, and has no external dependencies. It changes nothing on the host page outside the container element.

Parameters on the embedjs URL

Parameter What it does
u Required. The absolute URL to load in the frame. Must be an absolute http or https URL; anything else returns an inert comment instead of script.
c Optional. The id of your container element, defaulting to bu-checkout. Use it when that id collides with something on your page. Letters, digits, hyphen and underscore only, up to 64 characters.
h Optional. A fixed frame height in pixels. Setting it turns automatic resizing off, so use it only where your layout demands a fixed height, such as inside a slider or accordion.

A custom container with a fixed height looks like this:

<div id="give-now"></div> <script src="https://app.betterunite.com/embedjs?u=https://app.betterunite.com/{campaign}/donate?embedded=true&c=give-now&h=1100"></script>

The embedded flag

The ?embedded=true on the framed URL tells the campaign page it is running inside a host site. It suppresses the surrounding site chrome and enables the height messages the script listens for, so keep it on the URL passed in u. The Embedded Web Page URL and Embedded Checkout URL shown in the dialog are the same URLs with this flag already applied, ready for your own iframe.

Writing your own iframe

If your CMS or framework has its own embed component, use the embedded URL directly:

<iframe   src="https://app.betterunite.com/{campaign}/donate?embedded=true"   title="Donate to our campaign"   style="width:100%; min-height:900px; border:0;"   allow="payment; publickey-credentials-get"   loading="lazy"> </iframe>

Two things are easy to get wrong here.

  • Include the allow attribute. Omitting it produces no error message. The digital wallet buttons simply do not appear, which looks like a configuration problem on our side.
  • Handle the height yourself. The embedded page posts its height to the parent window whenever content changes. Listen for it, or the frame stays at your fixed height and the last step of checkout is cut off.
window.addEventListener("message", function (e) {   if (e.origin !== "https://app.betterunite.com") return;   if (!e.data || e.data.type !== "iframe-resize") return;   var frame = document.getElementById("bu-frame");   frame.style.height = e.data.height + "px"; });

Always compare the message origin before acting on it. Any page in any frame can post to your window.

Do not pin the frame open with CSS. A theme rule such as a 1200 pixel minimum height on iframes beats the height the script sets, so short steps of checkout render as a tall blank area. The script neutralizes minimum and maximum height on the frame it creates for exactly this reason. If you write your own iframe, keep any minimum height modest.

Embedded forms

Online fundraiser and online form campaigns have an extra Embedded Forms tab producing a form specific snippet: a container div plus a small loader script carrying data-org and data-form-id attributes. The loader creates the frame and handles resizing the same way, and additionally fires a DOM event on the container when a submission completes, so the host page can react:

var box = document.getElementById("your-form-container"); box.addEventListener("phil:form:submitted", function (e) {   // e.detail.refNo is the confirmation reference number.   // Fire a conversion event, redirect, or show a message. });

Copy the snippet from the product rather than composing it by hand, because the container id must match the identifier the loader looks for. Save the form at least once before copying, since an unsaved form has no identifier yet.

Security, cookies and browser requirements

Framing

Public campaign, checkout and form pages are served without a restrictive X-Frame-Options or frame-ancestors policy, so any site may frame them. Framing is permitted by design and needs no allowlisting request from us. Administrative pages are a different matter and are not intended to be embedded.

Cookies

Inside a frame on your domain, every request to BetterUnite is a cross site request. The session cookie is therefore issued as SameSite=None; Secure, which is what lets checkout state persist from step to step. Two consequences:

  • The host page must be HTTPS. A Secure cookie is not sent from a page loaded over plain HTTP, so an embed on an HTTP page loses state mid checkout.
  • Third party cookie blocking affects the embed. Browsers that block third party cookies outright, notably Safari on iOS and hardened enterprise profiles, will not send the cookie from inside a frame. The pages tolerate this, but where strict blocking is enforced across managed devices, a direct link is more predictable than an embed.

Consent managers that hold scripts until the visitor accepts cookies will also hold the embed script. If your banner categorizes scripts, classify this one as strictly necessary or functional. Otherwise the donation area renders as empty space for anyone who has not yet answered the banner.

Content security policy on your site

If your website sends a Content-Security-Policy header, the host page must permit our script and our frame. Your policy governs what your page loads; it does not apply inside our frame, so you do not need to list our payment or media providers in it.

Content-Security-Policy:   script-src 'self' https://app.betterunite.com;   frame-src  'self' https://app.betterunite.com;   img-src    'self' data: https://app.betterunite.com;

The img-src entry is needed only if you also display QR images served from our domain. If your policy relies on default-src without the more specific directives, add the domain there instead.

Network allowlisting

Web filters and proxies are a separate concern from content security policy, and here the destinations inside the frame do matter, because the visitor's browser reaches them directly. For staff processing gifts on a managed network, allow app.betterunite.com and bnte.us, and expect checkout to also contact the payment and media providers used for card processing, digital wallets, images and employer matching lookups. If a card form appears everywhere except your office network, filtering is the first thing to check.

Accessibility

Give every frame you author a meaningful title attribute, as in the example above. Screen readers announce it when the visitor reaches the frame, and an untitled frame is announced only as "frame". Do not set a negative tabindex on the frame element, because that stops keyboard users reaching the form inside it.

Troubleshooting

  • Nothing renders where the embed should be. The container div is missing or its id does not match, or a consent manager or ad blocker held the script. Confirm the div is present with the expected id, then check the browser console and network tab for a blocked request to the embed script.
  • The CMS stripped the code on save. The editor is sanitizing script tags, which is common in page builders and restricted author roles. Paste into a raw HTML or custom code block, or use the embedded URL in the platform's own embed component.
  • The frame is very tall, with blank space below the content. Host CSS is forcing a minimum height on iframes, or a fixed h value is set. Remove or rescope the CSS rule and drop the h parameter so automatic sizing resumes.
  • The frame is cut off at the bottom. A hand written iframe with no resize listener. Add the message listener shown above, or switch to the script embed.
  • Apple Pay, Google Pay, PayPal or Venmo buttons are missing. The frame lacks the allow attribute, or a permissions policy header on the host page revokes payment. Add the attribute and confirm your site does not disable payment in a Permissions-Policy header.
  • Checkout restarts or loses the cart between steps. The host page is not on HTTPS, or the browser is blocking third party cookies. Serve the host page over HTTPS; where blocking is enforced by policy, link to the full page instead.
  • Two embeds on one page interfere with each other. Both containers use the default id because the page builder duplicated it. Give the second embed its own container id and pass it with the c parameter.
  • A QR code will not scan. Printed too small, quiet zone cropped, low contrast, or scaled up from a small image. Re-request at larger w and h values, keep the white border, and print dark on light.
  • The embed works locally but not on the live site. A content security policy applied only in production. Add https://app.betterunite.com to script-src and frame-src.

Notes for specific platforms

  • WordPress. Use a Custom HTML block, not a Paragraph block. On WordPress.com, script embedding requires a Business plan or higher. Themes that set a global iframe minimum height are the most common cause of the tall blank frame above.
  • Squarespace. A Code Block accepts the script on Business plans and above. On lower plans, use the embedded URL with the platform's own embed element.
  • Wix. Use Embed a Widget for the script embed, or Embed a Site for the embedded URL. Wix places embeds in a nested frame of its own, so allow extra height.
  • SharePoint and intranets. The Embed web part requires the source domain to be listed as an allowed HTML field security domain by a tenant administrator. Add app.betterunite.com there first.
  • Email. Scripts and iframes do not run in email clients. Use a direct link or a QR image in email, never an embed.

Getting help

Send questions to support@betterunite.com. For an embedding issue, include the page URL where the embed lives, the snippet exactly as it appears in your page source, the browser and version, and any console or network errors. That is usually enough to identify the cause on the first reply.