Démo en direct
Utilitaire pour les mises à jour de l'index Algolia côté serveur ainsi qu'un composant de recherche côté client pour les applications Svelte. N'ajoute qu'une seule dépendance :
algoliasearch
algoliasearch/lite
(13 Ko). Il y a 3 étapes pour configurer svelte-algolia
:
npm install --dev svelte-algolia
Créez un objet algoliaConfig
:
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` ] ,
} ,
}
La fonction getData
est censée renvoyer un tableau d'objets contenant les données que vous souhaitez indexer (un catalogue de produits, des articles de blog, des pages de documentation, des pokémons ou autre). Chaque objet du tableau de données doit avoir une clé nommée id
, _id
ou objectID
pour qu'Algolia puisse le reconnaître et écraser les données existantes le cas échéant.
L'objet settings s'applique à tous les index. Vous pouvez également transmettre un objet de paramètres à chaque index individuellement, qui remplace l'objet général.
Passez votre configuration à indexAlgolia
:
import { indexAlgolia } from 'svelte-algolia/server-side'
indexAlgolia ( algoliaConfig )
Vous pouvez appeler cette fonction partout où vous souhaitez mettre à jour vos index, par exemple dans svelte.config.js
ou dans src/hooks.ts
(comme le fait ce site de démonstration). En règle générale, vous l'incluez dans chaque version de production de votre application.
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` }}],
}
Pour utiliser ce package dans le cadre d'un processus de build (par exemple dans une application SvelteKit), appelez simplement indexAlgolia
dans votre configuration de build :
// 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 />
a besoin de l'ID et de la clé de recherche de votre application Algolia pour accéder à ses index de recherche, ainsi que d'un mappage des noms d'index au composant Svelte correspondant qui devrait restituer les résultats de recherche provenant de cet index. Chaque composant hit reçoit un objet hit
comme accessoire avec tous les attributs stockés dans l'index Algolia.
< 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 >
Par exemple, le composant PokemonHit.svelte
sur le site de démonstration ressemble à ceci :
< 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 >
Les sous-chaînes des attributs correspondant à la chaîne de recherche actuelle seront enveloppées dans <em>
qui nécessitent que la balise {@html ...}
soit rendue correctement, mais peuvent ensuite être stylisées pour mettre en évidence pourquoi un résultat particulier correspond à la chaîne de recherche actuelle. La valeur originale (c'est-à-dire sans les balises <em>
) de chaque attribut mis en surbrillance est disponible sous la forme hit.[attr]Orig
. Voir hit.nameOrig
ci-dessus.
Liste complète des accessoires/variables pouvant être liées pour ce composant :
appId: string
Identifiant de l'application Algolia
ariaLabel: string = `Search`
Indique à la technologie d'assistance comment annoncer l'élément d'entrée à l'utilisateur.
hasFocus: boolean = false
Booléen pouvant être lié indiquant si le volet de saisie de texte ou de résultats a actuellement le focus.
indices: Record < string , typeof SvelteComponent > | [ string , typeof SvelteComponent ] [ ]
Objet mappant le nom de chaque index dans lequel le composant Search
doit exploiter pour trouver les résultats de la recherche au composant Svelte qui doit restituer ces résultats.
input: HTMLInputElement | null = null
Handle vers le nœud DOM.
loadingMsg: string = `Searching...`
Chaîne à afficher dans le volet des résultats pendant la récupération des résultats de la recherche.
noResultMsg = ( query : string ) : string => `No results for ' ${ query } '`
Fonction qui renvoie la chaîne à afficher lorsque la recherche n'a renvoyé aucun résultat.
placeholder: string = `Search`
Espace réservé affiché dans la saisie de texte avant que l'utilisateur ne commence à taper.
query: string = ``
Valeur actuelle du nœud DOM.
resultCounter = ( hits : SearchHit [ ] ) : string =>
hits . length > 0 ? `<span>Results: ${ hits . length } <span>` : ``
Fonction qui renvoie une chaîne qui sera affichée à côté du nom de chaque index pour indiquer combien de résultats ont été trouvés dans cet index. Renvoie une chaîne vide pour ne rien afficher.
searchKey: string
Clé API de recherche uniquement
Search.svelte
écoute les événements on:close
sur chaque composant hit qu'il restitue et définira hasFocus
sur false
pour se fermer une fois reçu. Vous pouvez l'utiliser par exemple pour fermer l'interface de recherche lorsque l'utilisateur clique sur un lien dans l'un des résultats de recherche et accède à une autre page de votre site :
< 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 >
Il émet également un événement focus
chaque fois que l'utilisateur clique sur l'icône de recherche et que le focus entre dans la saisie de texte.
< Search on:focus ={() => console . log ( " Let's search! " )} />
Search.svelte
propose les variables CSS suivantes répertoriées ici avec leurs valeurs par défaut (le cas échéant) qui peuvent être transmises directement en tant qu'accessoires :
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)
Par exemple:
< Search
indices ={{ Pages : SearchHit , Posts : SearchHit }}
{ appId }
{ searchKey }
-- hitsBgColor = " var(--search-body-bg) "
-- inputColor = " var(--search-text-color) "
-- iconColor = " var(--search-link-color) "
/>
L'élément de niveau supérieur est un aside
avec la classe svelte-algolia
. Ainsi, vous pouvez également styliser l'intégralité de l'arborescence DOM située en dessous en définissant des styles globaux tels que
: 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 */
}
Quelques sites utilisant svelte-algolia
en production :
studenten-bilden-schueler.de
[code]afara.foundation
[code]ocean-artup.eu
[code] Vous utilisez vous-même svelte-algolia
? Soumettez un PR pour ajouter votre site ici !
Les PR sont les bienvenus, mais il est préférable d'ouvrir d'abord un problème pour discuter des changements.
L'ID de l'application et la clé de recherche .env
ont été intentionnellement validés afin que vous puissiez cloner ce référentiel et travailler dessus sans avoir à créer au préalable votre propre index. Pour tester vos modifications sur un serveur de développement exécuté localement, utilisez
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
Notez la commande sed
qui modifie le nom de l'index dans site/svelte.config.js
de 'Pokedex'
à 'Pokedex Clone'
afin de ne pas gâcher accidentellement l'index de recherche de ce site de démonstration lors du développement.