AACsearch
Solución de problemas

Widget not loading

Widget script tag is on the page but the search UI never appears — diagnose script load failure, missing container, CSP blocks, key issues, and Shadow DOM mounting.

If you embedded widget.js and the search box does not appear, work through this in order. Each check eliminates one cause.

Check 1: script actually loaded

Open browser dev tools → Network → filter for widget.js. You should see a 200. If you see:

StatusCause
0 (failed)CSP blocks script-src from app.aacsearch.com
403Origin not allowed for the search key
404Wrong path; widget.js lives under https://app.aacsearch.com/api/widget/widget.js
Blocked by CORSShould never happen — the script is served with permissive CORS; if it does, file a ticket

For CSP, add app.aacsearch.com to your script-src directive:

<meta
	http-equiv="Content-Security-Policy"
	content="script-src 'self' https://app.aacsearch.com; img-src 'self' data: https:;"
/>

Check 2: container exists at boot time

The widget mounts into the element identified by data-container. If the element does not exist when the script runs, mount silently fails.

<!-- ❌ Container after the script -->
<script src="https://app.aacsearch.com/api/widget/widget.js"
        data-container="#aac-search"
        data-api-key="ss_search_..."
        data-index-slug="products"></script>
<div id="aac-search"></div>

<!-- ✅ Container before the script -->
<div id="aac-search"></div>
<script src="https://app.aacsearch.com/api/widget/widget.js"
        data-container="#aac-search"
        data-api-key="ss_search_..."
        data-index-slug="products"></script>

If the container is rendered by a SPA framework after first paint, defer initialization:

// React example — wait until the container is in the DOM
useEffect(() => {
	const script = document.createElement("script");
	script.src = "https://app.aacsearch.com/api/widget/widget.js";
	script.dataset.container = "#aac-search";
	script.dataset.apiKey = process.env.NEXT_PUBLIC_AACSEARCH_SEARCH_KEY!;
	script.dataset.indexSlug = "products";
	document.body.appendChild(script);
	return () => document.body.removeChild(script);
}, []);

Check 3: API key valid for this origin

The widget calls the public search endpoint on every keystroke. If the search key has allowedOrigins set, the storefront origin must be in that list.

In dev tools → Network → filter for /api/search/...:

Status on first callDiagnosis
200All good — issue is elsewhere (rendering, CSS)
403 origin_not_allowedAdd the storefront origin to the key — see Auth errors
401Key revoked, expired, or wrong prefix — see Auth errors
429Rate limit — see Rate limits
404 index_not_founddata-index-slug does not match an existing index

Check 4: Shadow DOM mount

The widget renders inside a Shadow DOM root attached to your container. If your CSS uses !important or a global selector that targets [shadow-root] ancestors, the widget can render but be invisible.

In dev tools → Elements → expand the container → look for #shadow-root (open). If it is there, the widget loaded. If the inner content has display: none or opacity: 0, your CSS is the culprit.

/* ❌ Common mistake */
* {
	visibility: visible !important;
}

/* ✅ Scope to your own components */
.my-component * {
	visibility: visible !important;
}

Check 5: console errors

Browser console → look for [aacsearch] prefixed messages.

Console messageMeaning
[aacsearch] container "#aac-search" not foundContainer missing — see Check 2
[aacsearch] missing data-api-keydata-api-key attribute not set on the script tag
[aacsearch] failed to fetch translationsNetwork blocked the i18n bundle; widget falls back to English
[aacsearch] failed to render: <error>Bug in the storefront page; share the error in your ticket

Check 6: ad-blocker / extension

A small but real cause: extensions like uBlock with custom rules sometimes block third-party scripts that match a generic pattern. Test in an incognito window with no extensions to rule this out.

Check 7: SPA route change

If the widget mounted on the homepage but disappeared after navigating to a product page, the SPA likely tore down the container. Re-initialize on each route change:

// React example — Next.js App Router
import { useEffect } from "react";
import { usePathname } from "next/navigation";

useEffect(() => {
	window.AACSearch?.mount({
		container: "#aac-search",
		apiKey: process.env.NEXT_PUBLIC_AACSEARCH_SEARCH_KEY!,
		indexSlug: "products",
	});
	return () => window.AACSearch?.unmount("#aac-search");
}, [usePathname()]);

Fix matrix

DiagnosisFix
CSP blocks scriptAdd app.aacsearch.com to script-src
Container missingMove <div> above <script>, or re-mount on route change
Key wrong / origin not allowedSee Auth errors
Index slug typoUse the actual slug from Search → Indexes
Custom CSS hides widgetScope your global selectors to your own components
Extension blocks scriptWhitelist app.aacsearch.com in the user's ad-blocker, or document this as a known caveat

Diagnostics packet

FieldNotes
Organization IDrequired
Index slugrequired
Storefront URLrequired (so we can reproduce)
Browser + versionrequired
Console errorsscreenshot or text
Network logwidget.js row + first /api/search/... row
CSP header in usefrom response headers of the storefront page

On this page