Troubleshooting
Fix Givebear SDK embeds that do not mount, show an error, or get blocked by a Content Security Policy.
Use this page when a Givebear widget does not behave as expected. Each section starts from a symptom you can see (no widget, an on-page error, a blocked request) and gives the fix.
Before you debug, confirm the basics:
- The script tag points at
https://givebear.io/sdk/givebear.js. - Your
organizationIdmatches the one in your Givebear dashboard. - The browser console and Network tab are open while you reload.
For how the SDK loads and what each method does, see Installation and API. For every config field, see the configuration reference.
The widget does not appear at all
Work through these in order.
Confirm the script loaded
Open the Network tab and reload. Search for givebear.js.
- If the request is missing, your
<script>tag is absent or the URL has a typo. - If it returns
500with a comment like// SDK not built., the served bundle is missing or stale. This is a Givebear-side issue: contact support. - If it is blocked, your Content Security Policy is rejecting it. See Fix Content Security Policy errors.
Check your auto-mount attribute
The SDK only mounts elements carrying one of these exact attributes:
data-givebear-buttondata-givebear-carddata-givebear-embeddata-givebear-thermometerdata-givebear-prayer-timesdata-givebear-calendardata-givebear-events
A typo means nothing mounts. See the configuration reference for the full attribute list.
Check your selector when you call a method directly
renderButton, renderCard, and the other render methods resolve target with
document.querySelector. If the selector matches no element, the method does
nothing and logs no warning.
<!-- Fails silently: no element has id "donate-btn" -->
<div id="donate"></div>
<script>
window.Givebear.renderButton("#donate-btn", { organizationId: "your-org-id" });
</script>Fix the selector, or pass the Element itself instead of a string.
Fix call timing
A direct call runs before the SDK bundle arrives when you use async. Use the
async loader queue so your code runs only after the SDK is ready:
<script>
window.Givebear =
window.Givebear ||
function (cb) {
(window.Givebear.q = window.Givebear.q || []).push(cb);
};
</script>
<script src="https://givebear.io/sdk/givebear.js" async></script>
<script>
window.Givebear(function (gb) {
gb.renderButton("#donate-btn", { organizationId: "your-org-id" });
});
</script>The target element must also exist in the DOM before the render call runs. See Loading patterns.
Auto-mount scans the page once, on DOMContentLoaded (or immediately if the
page is already parsed). Elements you inject later (for example after a
client-side route change in a single-page app) are not picked up automatically.
Call the matching render method on the new element yourself.
The SDK marks every element it mounts with data-givebear-mounted="1" and skips
anything already marked. If an element refuses to re-render, remove that
attribute or mount a fresh element.
The widget shows "Widget not configured"
The SDK rendered, but your config is incomplete. It shows an inline message and
logs a [Givebear] warning to the console.
| On-page message | Console warning | Fix |
|---|---|---|
Widget not configured. Please check the organization ID. | [Givebear] render<Widget>: missing organizationId. | Set organizationId (or orgId). |
Widget not configured. Set the organization and campaign IDs. | [Givebear] renderThermometer: missing organizationId or campaignId. | Set both organizationId and campaignId. |
organizationId must be your organization ID from the Givebear dashboard. A
slug, name, or typo will not work. The thermometer also requires campaignId.
The easiest way to get a correct organization ID is the embed builder in your dashboard. It generates a copy-paste snippet with your ID already filled in.
The widget shows "Couldn't load ..."
The widget mounted and has valid IDs, but a data request failed. You see one of:
Couldn't load this widget.Couldn't load calendar.Couldn't load prayer times.Couldn't load campaign progress.
Check these:
- The request is reaching Givebear. In the Network tab, look for a request
to
givebear.io/api/sdk/...(orgivebear.io/api/prayer-times/...). If it is blocked, see Fix Content Security Policy errors. - The referenced record exists and is live. A
fundIdorcampaignIdmust point at a published, active record in your organization. - The organization is payment-ready. Donation widgets need a connected, fully onboarded payment account. Confirm readiness in the dashboard. See the product guides.
The donation form is blank or never loads
The donation card, inline embed, and modal render the form inside an <iframe>
pointed at https://givebear.io/embed/.... If the frame stays blank:
- Confirm your CSP allows framing
givebear.io. See Fix Content Security Policy errors. - Confirm the organization is payment-ready, as above.
Payment problems that appear after the form loads (declined cards, Stripe errors) happen inside the Givebear-hosted iframe, not in the SDK. Test the full donor path from the dashboard first.
Fix Content Security Policy errors
A strict Content Security Policy can block the SDK in three places. The console
reports a Refused to ... violation naming the directive at fault. Allow
https://givebear.io for each:
| What the SDK does | Directive to allow | Why |
|---|---|---|
Loads givebear.io/sdk/givebear.js | script-src | Run the SDK bundle. |
Fetches widget data from givebear.io/api/... | connect-src | Load card, calendar, prayer times, and thermometer data. |
Frames the donation form from givebear.io/embed/... | frame-src | Show the donation experience. |
A minimal policy that permits the SDK:
Content-Security-Policy:
script-src 'self' https://givebear.io;
connect-src 'self' https://givebear.io;
frame-src 'self' https://givebear.io;The SDK isolates each widget in a shadow root and styles it with a constructable
stylesheet. On older browsers without that support, it falls back to an injected
<style> element, which a strict style-src (no 'unsafe-inline') can block.
If widgets render unstyled only on older browsers, relax style-src for them.
The widget looks unstyled or uses the wrong fonts
This is usually expected. Widgets render in a shadow root with a reset host, but
they deliberately inherit font-family, font-size, and color from your page
so they feel native. Unusual global typography on your site flows into the
widget.
To change the accent, set accentColor to any valid CSS color (the default is
#387A4B). Theme follows the page when theme is "auto". See the
shared fields.
The donation modal appears behind page content
The modal mounts a fixed, full-viewport host at z-index: 2147483647 (the
maximum). If something still covers it, that element sits in a separate stacking
context the modal cannot escape. A parent with transform, filter, or
isolation: isolate creates such a context. Move the trigger out of it, or
contact support with a link to the page.
Still stuck
Installation and API
Loader patterns, auto-mount, and every window.Givebear method.
Configuration reference
Every config field, alias, default, and data attribute.
Snippet examples
Copy-paste markup for each widget.
Analytics and versioning
SDK version and loading behavior.
Givebear Connect
The server-to-server REST API and webhooks.
Product guides
Set up funds, campaigns, and payments in the dashboard.