AACSearch
Anleitungen

Einbettbares Widget

Eine vollständige Suchoberfläche mit einem Script-Tag und einem kurzlebigen Session-Token — Session-Vertrag, alle Datenattribute, Events, Theming und CSP-Hinweise.

aacsearch.js ist ein eigenständiges InstantSearch-Bundle: Suchfeld, Trefferliste mit Hervorhebung, Facetten, Sortierung, Paginierung, letzte Suchen. Kein Framework, keine Build-Kette, ein <script>-Tag. Es spricht über den Embed-Proxy von AACSearch mit Ihrem Index und legt nie einen Plattform-API-Schlüssel offen.

Die Seite hält nie den API-Schlüssel. Ihr Server tauscht den Schlüssel über POST /api/v1/embed/session gegen ein kurzlebiges, reines Such-Session-Token und rendert dieses Token als data-aac-token in die Seite.

Einbinden

Stellen Sie zuerst in Ihrem Backend ein Token aus (siehe Embed-Session):

curl -sS -X POST "$AAC_API/embed/session" \
  -H "Authorization: Bearer $AAC_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "index": "documentation", "expires_in": 900 }'

Setzen Sie dann das gelieferte token in die Seite:

<div id="aacsearch"></div>
<script
	src="https://search.example.com/embed/v1/aacsearch.js"
	data-aac-token="aac_sess_…"
	data-aac-target="#aacsearch"
	data-aac-placeholder="Dokumentation durchsuchen …"
></script>
AttributPflichtWirkung
data-aac-tokenjaEmbed-Session-Token aus POST /api/v1/embed/session. Fehlt es, mountet das Script nicht automatisch
data-aac-targetneinCSS-Selektor für das Zielelement, Standard #aacsearch
data-aac-endpointneinAPI-Basis-URL; sonst aus der Script-URL abgeleitet
data-aac-placeholderneinÜberschreibt den Platzhalter aus den Session-Einstellungen
data-aac-client-idneinStabile Besucher-ID (z. B. Ihre Nutzer-ID), damit Suchen und Klicks geräteübergreifend eine Historie bilden; sonst eine anonyme UUID im localStorage

Ein data-aac-key gibt es nicht: Ein Plattform-API-Schlüssel darf weder im HTML noch in einem data--Attribut noch in einer URL stehen. Das Token ist nur zum Suchen, an einen Index gebunden und läuft von selbst ab.

Das Script hängt sich an DOMContentLoaded, wenn das Dokument noch lädt, sonst startet es sofort — die Position des Tags ist damit egal, solange das Zielelement existiert, wenn das Script läuft. Fehlt das Ziel, bricht es mit einem console.warn ab, statt die Seite zu stören.

Zwei URLs, zwei Caching-Strategien

PfadCacheWofür
/embed/v1/aacsearch.jsimmutable, 1 JahrProduktion; die Version steckt im Pfad, ein Update braucht /v2/
/embed/aacsearch.js5 MinutenEntwicklung; folgt immer der aktuellen Version

Der versionslose Pfad ist bewusst kurz gecacht, damit Sie beim Entwickeln nicht gegen ein Jahr Browser-Cache kämpfen.

Programmatisch starten

<script src="https://search.example.com/embed/v1/aacsearch.js" async></script>
<script>
	window.addEventListener("load", () => {
		window.AACSearch.init({
			token: "aac_sess_…", // serverseitig ausgestellt, nie der API-Schlüssel
			target: "#suche",
			endpoint: "https://search.example.com",
			placeholder: "Wonach suchen Sie?",
			clientId: "user_123", // optional
		});
	});
</script>

init gibt ein Promise zurück, das nach dem Einrichten des Widgets aufgelöst wird. Bei Fehlern wirft es nicht, sondern rendert eine Meldung an Ort und Stelle:

SituationWas der Besucher sieht
Kein tokenSearch is not configured for this page. (plus ein console.error mit Verweis auf POST /api/v1/embed/session)
Token abgelaufen (401)Search session expired — reload the page.
Anderer Fehler bei /embed/configSearch is unavailable right now (503). (Statuscode variiert)

window.AACSearch.version gibt die geladene Version ("1.0.0") zurück — nützlich, um in einem Fehlerbericht zu sehen, was tatsächlich lief. Außerdem stehen trackConversion() und getRecommendations() bereit. Ein zweiter init-Aufruf im selben Ziel rendert erneut dorthin und ersetzt den bisherigen Inhalt; das dokumentierte Muster ist ein Widget pro Seite.

Der Session-Vertrag

Jeder Aufruf des Bundles geht an den Proxy /api/v1/embed/* Ihrer Installation und authentifiziert sich mit dem Session-Token im JSON-Body — nie in der URL, damit es nicht in Browser-Verlauf, Referrer und Access-Logs landet.

AufrufEndpunktWann
EinstellungenPOST /api/v1/embed/configEinmal beim Mounten: liefert index, scope, expires_at und settings
SuchePOST /api/v1/embed/searchBei jeder Anfrage, Seiten-, Facetten- oder Sortierungsänderung
EventsPOST /api/v1/embed/eventsview beim ersten Rendern eines Treffers, click auf einen Treffer, conversion über trackConversion()
EmpfehlungenPOST /api/v1/embed/recommendationsWenn showRelated aktiv ist, und über getRecommendations()

Die Suche geht nicht direkt vom Browser an den Suchdienst. Der Proxy prüft das Token bei jeder Anfrage, wendet den Mandantenfilter serverseitig an und nutzt dieselbe Pipeline wie die öffentliche API (Query-Log, Regeln, Defaults, Relaxation, Did-you-mean); Widget-Traffic erscheint also in den Analytics. Der Browser sieht weder Engine-Host noch -Schlüssel noch Collection-Namen. Jede proxierte Suche zählt gegen das searches-Kontingent; ein Proxy-Request trägt höchstens 5 Suchen, page ≤ 20, und per_page wird auf 50 gekappt.

Die Session-Laufzeit beträgt standardmäßig 900 Sekunden (höchstens 3600). Das Widget erneuert sein Token nicht selbst: Nach Ablauf liefern Anfragen 401, und das Widget zeigt The search session expired — reload the page. Bei dauerhaft geöffneten Seiten stellen Sie vor Ablauf ein neues Token aus und rufen init erneut auf — oder laden die Seite neu.

Events

Das Widget meldet Verhalten automatisch, nach bestem Bemühen und mit keepalive, sodass ein Tracking-Fehler die Host-Seite nie stört:

// Aus dem eigenen Code, z. B. nach dem Checkout:
window.AACSearch.trackConversion({ documentId: "sku-123", valueCents: 4900, query: "laufschuhe" });

Events tragen das Session-token, eine Besucher-session_id (die Client-ID des Widgets), document_id, position und query. Sie landen in denselben Verhaltenstabellen wie die REST-Events-API, mit Zuordnung pro Widget, wenn das Token von einem gespeicherten Widget stammt.

Empfehlungen

const { items, mode } = await window.AACSearch.getRecommendations({
	seedDocumentId: "sku-123",
	limit: 4,
});

getRecommendations liefert { items: [], mode: "unavailable" }, solange das Widget nicht gemountet ist, und { items: [], mode: "error" } bei einem Fehler. Die eingebaute „For you“-Leiste erscheint nur, wenn showRelated für den Index aktiv und Empfehlungen aktiviert sind.

Rendering

Aus settings baut das Widget die InstantSearch-Konfiguration: perPage als hitsPerPage, facets als Checkbox-Listen (bis zu 8 Werte pro Facette), sortOptions als Dropdown (ausgeblendet, wenn nur eine Option), showStats für die Trefferzeile, showRecent für Chips der letzten Anfragen (lokal pro Index gespeichert, erst ab drei Zeichen und nur bei Treffern), showVoice für die Spracheingabe des Browsers.

Oberflächentexte gibt es auf Englisch und Russisch, gewählt über navigator.language; alle anderen Sprachen fallen auf Englisch zurück. Eigene Texte lassen sich derzeit nicht injizieren — dafür braucht es eine eigene Oberfläche auf Basis von /embed/search.

Theming

{
	"accent": "#0f766e",
	"dark": true,
	"placeholder": "Wissen durchsuchen",
	"perPage": 10,
	"facets": ["category", "tags"],
	"showStats": true,
	"showRecent": false,
	"showVoice": true
}
SchlüsselStandardWirkung
accent#2563ebButtons, Fokusring, Links, aktive Facetten
darkfalseDunkle Palette über CSS-Variablen
placeholderSearch the docs…Text im Eingabefeld
perPage8Treffer pro Seite
queryBytitle,contentDurchsuchte Felder
facets[]Facettenfelder (Konsole: maximal 6)
showStatstrueTrefferzahl
showRecenttrueChips der letzten Anfragen
showVoicefalseSpracheingabe
showImagefalseTrefferbild, wenn das Dokument eines hat
showRelatedfalse„For you“-Leiste unter den Ergebnissen
sortOptionsRelevanz + created_at:descSortier-Dropdown, erster Wert muss default sein

Die Einstellungen liegen in SearchIndex.settings.embed und werden bei jeder Session-Ausstellung frisch gelesen: Eine Änderung im Panel „Erscheinungsbild" der Konsole ist beim nächsten Seitenaufruf sichtbar, ohne Deploy und ohne CDN-Invalidierung.

Für Feinarbeit am Styling greifen Sie die gerenderten Klassen ab und überschreiben sie im eigenen Stylesheet — accent und dark decken die häufigen Fälle ab, alles darüber ist CSS.

CSP und Datenschutz

Der gesamte Widget-Traffic geht an einen Origin, Ihre Installation: das Script selbst und die Aufrufe /api/v1/embed/*. Der Browser spricht nicht mit der Such-Engine, ein Engine-Origin ist daher nicht nötig.

Content-Security-Policy:
  script-src 'self' https://search.example.com;
  connect-src 'self' https://search.example.com;
  style-src 'self' 'unsafe-inline';

Das Bundle injiziert sein Stylesheet inline, daher braucht style-src 'unsafe-inline'. connect-src ist die Direktive, die man vergisst: Das Script lädt problemlos, aber die Aufrufe /embed/config, /embed/search und /embed/events scheitern ohne sie still im Netzwerk-Tab. Wird die API von einem anderen Host als das Script ausgeliefert, erlauben Sie beide Origins.

Datenschutz: Das Widget setzt keine Cookies. Die letzten Suchen und die Besucher-ID (aac_client_id, sofern Sie keine eigene übergeben) liegen im localStorage des Besuchers. Abgefragte Begriffe und Klick-Events landen im Query-Log bzw. in den Verhaltensdaten des Mandanten, wie bei jeder Suche über die API.

Grenzen

  • Kein URL-Routing. Die Suche schreibt den Query-String nicht in die Adresszeile; ein geteilter Link öffnet keine vorbefüllte Suche. Dafür braucht es eine eigene Oberfläche.
  • Keine eigenen Templates. Trefferlayout, Facetten- und Sortier-Widgets sind fest.
  • Kein automatisches Token-Refresh. Sessions leben standardmäßig 15 Minuten, höchstens eine Stunde; bei langlebigen Seiten neu ausstellen und init erneut aufrufen.
  • Ein Index pro Widget. Föderierte Suche über mehrere Indizes unterstützt das Widget nicht.
  • Sprache ist UI-Sprache, nicht Suchsprache. Die Stemming-Sprache kommt aus der Anfrage, nicht aus navigator.language.

On this page