Website-Suche einbauen
Der öffentliche Such-Endpunkt /api/search: Parameter, Antwortformat, Limits und eine robuste Implementierung mit Debounce.
Jede Mosaio-Website hat einen Such-Endpunkt auf ihrer eigenen Domain. Er durchsucht alle veröffentlichten Seiten und öffentlichen Datensätze und wird vom Theme-JavaScript aufgerufen.
Endpunkt
GET /api/search?q=<begriff>&scope=<handles>&kind=<art>&limit=<n>&offset=<n>| Parameter | Standard | Beschreibung |
|---|---|---|
q | – | Pflicht, 2–128 Zeichen |
scope | alle öffentlichen | Kommaliste aus Datentyp-Handles und/oder page |
kind | record,page | record, page oder beides |
limit | 10 | max. 50 |
offset | 0 | max. 500 |
Antwort
{
"query": "dach",
"total": 12,
"took_ms": 14,
"facets": { "leistung": 8, "page": 4 },
"items": [
{
"kind": "record",
"handle": "leistung",
"title": "Dachsanierung",
"excerpt": "Wir sanieren Steil- und Flachdächer.",
"url": "/leistungen/dachsanierung",
"score": 0.61,
"headline": "… professionelle <mark>Dach</mark>sanierung …"
}
]
}headline enthält nur <mark> als HTML, alles andere ist serverseitig escaped – du darfst es mit innerHTML ausgeben.
Limits und Verhalten
30 Anfragen pro 60 Sekunden je IP, danach
429.Antworten werden bis zu fünf Minuten gecacht – neue Inhalte erscheinen mit Verzögerung.
Nur same-origin: Anfragen mit fremdem
Originerhalten403. Ein API-Token ist nicht nötig.Ohne JavaScript gibt es keine Suche – liefere einen Hinweis als Fallback.
Beispiel
let timer
let controller
input.addEventListener('input', () => {
clearTimeout(timer)
timer = setTimeout(async () => {
const q = input.value.trim()
controller?.abort()
if (q.length < 2) return clear()
controller = new AbortController()
try {
const res = await fetch(`/api/search?${new URLSearchParams({ q, limit: '10' })}`, { signal: controller.signal })
if (res.ok) render((await res.json()).items)
} catch (e) {
if (e.name !== 'AbortError') console.error(e)
}
}, 250)
})<div id="search-results" aria-live="polite" aria-label="Suchergebnisse"></div>Welche Felder durchsucht werden, steuern Redakteure je Feld mit „In der Volltextsuche berücksichtigen“. Titel wiegen am stärksten, danach Kurztexte wie excerpt oder teaser, dann Fließtext.
Unser Support antwortet in der Regel innerhalb eines Werktags.