Live-Demo
Dienstprogramm für serverseitige Algolia-Indexaktualisierungen sowie eine clientseitige Suchkomponente für Svelte-Apps. Fügt nur eine einzige Abhängigkeit hinzu:
algoliasearch
algoliasearch/lite
(13 KB). Die Einrichtung von svelte-algolia
erfolgt in drei Schritten:
npm install --dev svelte-algolia
Erstellen Sie ein algoliaConfig
Objekt:
import 'dotenv/config' // optional
async function loadPokedex ( ) {
const json = await import ( 'pokedex.json' )
return json . default . map ( ( el ) => ( { ... el , id : el . someUniqAttribute } ) )
}
const algoliaConfig = {
appId : process . env . VITE_ALGOLIA_APP_ID ,
// don't prefix admin key with VITE_ else it would get exposed to client-side code
apiKey : process . env . ALGOLIA_ADMIN_KEY ,
indices : [
{ name : `Pokedex` , getData : loadPokedex } ,
{ name : `Hitchhiker's Guide` , getData : guideLoader } ,
] ,
settings : {
attributesToHighlight : [ `name` ] ,
} ,
}
Von der getData
-Funktion wird erwartet, dass sie ein Array von Objekten zurückgibt, die die Daten enthalten, die Sie indizieren möchten (einen Produktkatalog, Blogbeiträge, Dokumentationsseiten, Pokémon oder was auch immer). Jedes Objekt im Datenarray sollte einen Schlüssel namens id
, _id
oder objectID
haben, damit Algolia es erkennt und gegebenenfalls vorhandene Daten überschreibt.
Das Einstellungsobjekt gilt für alle Indizes. Sie können auch jedem Index einzeln ein Einstellungsobjekt übergeben, das das allgemeine überschreibt.
Übergeben Sie Ihre Konfiguration an indexAlgolia
:
import { indexAlgolia } from 'svelte-algolia/server-side'
indexAlgolia ( algoliaConfig )
Sie können diese Funktion überall dort aufrufen, wo Sie Ihre Indizes aktualisieren möchten, z. B. in svelte.config.js
oder in src/hooks.ts
(wie dies auf dieser Demo-Site der Fall ist). Normalerweise würden Sie dies in jeden Produktions-Build Ihrer App einbinden.
const defaultConfig = {
verbosity : 1 , // 0, 1 or 2 for no/some/lots of logging
partialUpdates : false , // if true, figures out diffs between existing
// items and new ones and only uploads changes, otherwise, completely
// overwrites each index on every call to indexAlgolia()
matchFields : [ ] , // (only used when partialUpdates is true) keys of fields to check
// for whether an item has changed; could e.g. be a timestamp, hash or an ID that's
// updated every time the item has changed; if not provided, items are checked for
// deep-equality to discover changes which can become slow for thousands of items
settings : { } , // an object of Algolia index settings that applies to all indices
// see https://algolia.com/doc/api-reference/settings-api-parameters for available options
// can be overridden for individual indices by passing a settings object as part of the indices array:
// indices = [{ name: `pokedex`, ..., settings: { foo: `bar` }}],
}
Um dieses Paket als Teil eines Build-Prozesses (z. B. in einer SvelteKit-App) zu verwenden, rufen Sie einfach indexAlgolia
in Ihrer Build-Konfiguration auf:
// svelte.config.js
// only update Algolia indices on production builds (saves API quota)
if ( process . env [ 'NODE_ENV' ] === `production` ) {
const { indexAlgolia } = await import ( `svelte-algolia/server-side` )
const algoliaConfig = {
// see above
}
indexAlgolia ( algoliaConfig )
}
<Search />
benötigt die ID und den Suchschlüssel Ihrer Algolia-App, um auf die Suchindizes zuzugreifen, sowie eine Zuordnung von Indexnamen zur entsprechenden Svelte-Komponente, die Suchtreffer aus diesem Index rendern soll. Jede Trefferkomponente erhält als Requisite ein hit
mit allen im Algolia-Index gespeicherten Attributen.
< script >
import Search from ' svelte-algolia '
import PokemonHit from ' $site/PokemonHit.svelte '
const appId = ' 0OJ5UL9OJX '
const searchKey = ' 63f563566cdd6de606e2bb0fdc291994 '
// in a real app you'd get your credentials like this:
const appId = import .meta.env.VITE_ALGOLIA_APP_ID
const searchKey = import .meta.env.VITE_ALGOLIA_SEARCH_KEY
</ script >
< header >
< nav >{ ... }</ nav >
< Search
{ appId }
{ searchKey }
indices ={{ Pokedex : PokemonHit }}
placeholder = " Search Pokedex " />
</ header >
Die PokemonHit.svelte
-Komponente auf der Demoseite sieht beispielsweise so aus:
< script >
export let hit
</ script >
< h2 >{ @html hit . name }</ h2 >
< div >
< ul >
< li >Type: { @html hit . type . join ( ` , ` )}</ li >
< li >Height: { @html hit . height }</ li >
< li >Weight: { @html hit . weight }</ li >
< li >Weaknesses: { @html hit . weaknesses . join ( ` , ` )}</ li >
</ ul >
< img src ={ hit . img } alt ={ hit . nameOrig } />
</ div >
< style >
/* highlights text matching the search string */
:global( em ) {
color : darkcyan ;
line-height : 1.2 em ;
border-radius : 3 pt ;
font-style : normal ;
}
div {
display : flex ;
justify-content : space-between ;
}
</ style >
Teilzeichenfolgen in Attributen, die mit der aktuellen Suchzeichenfolge übereinstimmen, werden in <em>
eingeschlossen. Für die korrekte Darstellung ist das Tag {@html ...}
erforderlich. Anschließend können sie jedoch so gestaltet werden, dass hervorgehoben wird, warum ein bestimmter Treffer mit der aktuellen Suchzeichenfolge übereinstimmt. Der Originalwert (also ohne <em>
-Tags) jedes hervorgehobenen Attributs ist als hit.[attr]Orig
verfügbar. Siehe hit.nameOrig
oben.
Vollständige Liste der Requisiten/bindbaren Variablen für diese Komponente:
appId: string
Algolia-App-ID
ariaLabel: string = `Search`
Teilt der unterstützenden Technologie mit, wie sie dem Benutzer das Eingabeelement ankündigen soll.
hasFocus: boolean = false
Bindebarer boolescher Wert, der angibt, ob der Texteingabe- oder Ergebnisbereich derzeit den Fokus hat.
indices: Record < string , typeof SvelteComponent > | [ string , typeof SvelteComponent ] [ ]
Objekt, das den Namen jedes Index, auf den die Search
zugreifen soll, um Suchergebnisse zu finden, der Svelte-Komponente zuordnet, die diese Treffer rendern soll.
input: HTMLInputElement | null = null
Handle für den DOM-Knoten.
loadingMsg: string = `Searching...`
Zeichenfolge, die im Ergebnisbereich angezeigt werden soll, während Suchergebnisse abgerufen werden.
noResultMsg = ( query : string ) : string => `No results for ' ${ query } '`
Funktion, die die Zeichenfolge zurückgibt, die angezeigt wird, wenn die Suche keine Ergebnisse liefert.
placeholder: string = `Search`
Platzhalter, der in der Texteingabe angezeigt wird, bevor der Benutzer mit der Eingabe beginnt.
query: string = ``
Aktueller Wert des DOM-Knotens.
resultCounter = ( hits : SearchHit [ ] ) : string =>
hits . length > 0 ? `<span>Results: ${ hits . length } <span>` : ``
Funktion, die eine Zeichenfolge zurückgibt, die neben dem Namen jedes Index angezeigt wird, um anzuzeigen, wie viele Ergebnisse in diesem Index gefunden wurden. Geben Sie eine leere Zeichenfolge zurück, um nichts anzuzeigen.
searchKey: string
API-Schlüssel nur für die Suche
Search.svelte
wartet auf on:close
-Ereignisse bei jeder Trefferkomponente, die es rendert, und setzt hasFocus
auf false
um sich selbst zu schließen, wenn es empfangen wird. Damit können Sie beispielsweise die Suchoberfläche schließen, wenn der Benutzer auf einen Link in einem der Suchergebnisse klickt und zu einer anderen Seite Ihrer Website navigiert:
< script >
import { createEventDispatcher } from ' svelte '
export let hit
const dispatch = createEventDispatcher ()
</ script >
< h3 >
< a href ={ hit . slug } on:click ={() => dispatch ( ` close ` )}>{ @html hit . title }</ a >
</ h3 >
< p >{ @html hit . body }</ p >
Es gibt außerdem jedes Mal ein focus
aus, wenn der Benutzer auf das Suchsymbol klickt und der Fokus die Texteingabe eingibt.
< Search on:focus ={() => console . log ( " Let's search! " )} />
Search.svelte
bietet die folgenden hier aufgeführten CSS-Variablen mit ihren Standardwerten (falls vorhanden), die direkt als Requisiten übergeben werden können:
button
color: var(--search-icon-color)
h2
color: var(--search-heading-color)
input
background: var(--search-input-bg)
color: var(--search-input-color)
font-size: var(--search-input-font-size, 1em)
input::placeholder
color: var(--search-input-color)
input.hasFocus + button
color: var(--search-input-color)
div.results
background-color: var(--search-hits-bg-color, white)
box-shadow: var(--search-hits-shadow, 0 0 2pt black)
Zum Beispiel:
< Search
indices ={{ Pages : SearchHit , Posts : SearchHit }}
{ appId }
{ searchKey }
-- hitsBgColor = " var(--search-body-bg) "
-- inputColor = " var(--search-text-color) "
-- iconColor = " var(--search-link-color) "
/>
Das Element der obersten Ebene ist ein aside
mit der Klasse svelte-algolia
. Sie können also auch den gesamten DOM-Baum darunter formatieren, indem Sie globale Stile wie definieren
: global (aside.svelte-algolia input button svg) {
/* this would target the search icon */
}
: global (aside.svelte-algolia div.results section h2) {
/* this would target the heading shown above the list of results for each index */
}
Einige Websites, svelte-algolia
in der Produktion verwenden:
studenten-bilden-schueler.de
[Code]afara.foundation
[Code]ocean-artup.eu
[Code] Benutzen Sie svelte-algolia
selbst? Senden Sie eine PR, um Ihre Website hier hinzuzufügen!
PRs sind willkommen, aber eröffnen Sie am besten zuerst ein Problem, um Änderungen zu besprechen.
Die App-ID und der Suchschlüssel .env
wurden absichtlich festgeschrieben, sodass Sie dieses Repo klonen und daran arbeiten können, ohne zuerst Ihren eigenen Index erstellen zu müssen. Um Ihre Änderungen auf einem lokal ausgeführten Entwicklungsserver auszuprobieren, verwenden Sie
git clone https://github.com/janosh/svelte-algolia
cd svelte-algolia
sed -i.bak ' s/name: `Pokedex`/name: `Pokedex Clone`/ ' svelte.config.js
npm install
npm run dev
Beachten Sie den Befehl sed
, der den Indexnamen in site/svelte.config.js
von 'Pokedex'
in 'Pokedex Clone'
ändert, damit Sie beim Entwickeln nicht versehentlich den Suchindex für diese Demo-Site durcheinander bringen.