现场演示
用于服务器端 Algolia 索引更新的实用程序以及 Svelte 应用程序的客户端搜索组件。只添加一个依赖项:
algoliasearch
algoliasearch/lite
(13 KB)。设置svelte-algolia
有 3 个步骤:
npm install --dev svelte-algolia
创建一个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` ] ,
} ,
}
getData
函数预计会返回一个对象数组,其中包含您希望索引的数据(产品目录、博客文章、文档页面、神奇宝贝或其他内容)。数据数组中的每个对象都应该有一个名为id
、 _id
或objectID
键,以便 Algolia 识别它并在适当的情况下覆盖现有数据。
设置对象适用于所有索引。您还可以将设置对象单独传递给每个索引,以覆盖常规索引。
将您的配置传递给indexAlgolia
:
import { indexAlgolia } from 'svelte-algolia/server-side'
indexAlgolia ( algoliaConfig )
您可以在任何想要更新索引的地方调用此函数,例如在svelte.config.js
或src/hooks.ts
中(如本演示站点所做的那样)。通常,您会将其包含在应用程序的每个生产版本中。
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` }}],
}
要使用此包作为构建过程的一部分(例如在 SvelteKit 应用程序中),只需在构建配置中调用indexAlgolia
:
// 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 />
需要您的 Algolia 应用程序的 ID 和搜索键来访问其搜索索引,以及从索引名称到相应 Svelte 组件的映射,该组件应呈现来自该索引的搜索命中。每个命中组件接收一个hit
对象作为 prop,其所有属性都存储在 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 >
例如,演示网站上的PokemonHit.svelte
组件如下所示:
< 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 >
与当前搜索字符串匹配的属性中的子字符串将被包装在<em>
中,这需要正确呈现{@html ...}
标记,但随后可以设置样式以突出显示特定匹配与当前搜索字符串匹配的原因。每个突出显示的属性的原始值(即没有<em>
标签)可用作hit.[attr]Orig
。请参阅上面的hit.nameOrig
。
该组件的 props/可绑定变量的完整列表:
appId: string
阿尔戈利亚应用程序 ID
ariaLabel: string = `Search`
告诉辅助技术如何向用户宣布输入元素。
hasFocus: boolean = false
可绑定布尔值,指示文本输入或结果窗格当前是否具有焦点。
indices: Record < string , typeof SvelteComponent > | [ string , typeof SvelteComponent ] [ ]
将Search
组件为查找搜索结果而应利用的每个索引的名称映射到应呈现这些命中的 Svelte 组件的对象。
input: HTMLInputElement | null = null
DOM 节点的句柄。
loadingMsg: string = `Searching...`
获取搜索结果时在结果窗格中显示的字符串。
noResultMsg = ( query : string ) : string => `No results for ' ${ query } '`
当搜索未返回结果时返回要显示的字符串的函数。
placeholder: string = `Search`
用户开始输入之前,文本输入中显示的占位符。
query: string = ``
DOM 节点的当前值。
resultCounter = ( hits : SearchHit [ ] ) : string =>
hits . length > 0 ? `<span>Results: ${ hits . length } <span>` : ``
返回一个字符串的函数,该字符串将显示在每个索引名称旁边,以显示在该索引中找到了多少结果。返回空字符串不显示任何内容。
searchKey: string
仅限搜索 API 密钥
Search.svelte
监听它渲染的每个点击组件上的on:close
事件,并将hasFocus
设置为false
以在收到时关闭自身。您可以使用此功能,例如,当用户单击其中一个搜索结果中的链接并导航到您网站上的另一页面时关闭搜索界面:
< 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 >
每次用户单击搜索图标并且焦点进入文本输入时,它还会发出focus
事件。
< Search on:focus ={() => console . log ( " Let's search! " )} />
Search.svelte
提供了此处列出的以下 CSS 变量及其默认值(如果有),可以直接作为 props 传入:
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)
例如:
< Search
indices ={{ Pages : SearchHit , Posts : SearchHit }}
{ appId }
{ searchKey }
-- hitsBgColor = " var(--search-body-bg) "
-- inputColor = " var(--search-text-color) "
-- iconColor = " var(--search-link-color) "
/>
顶层元素是类svelte-algolia
的aside
。因此,您还可以通过定义全局样式来设置其下面的整个 DOM 树的样式
: 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 */
}
一些在生产中使用svelte-algolia
网站:
studenten-bilden-schueler.de
[代码]afara.foundation
[代码]ocean-artup.eu
[代码]自己使用svelte-algolia
吗?在这里提交 PR 以添加您的网站!
欢迎 PR,但最好先打开一个问题来讨论更改。
应用程序 ID 和搜索键.env
是有意提交的,因此您可以克隆此存储库并对其进行处理,而无需先创建自己的索引。要在本地运行的开发服务器中尝试您的更改,请使用
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
请注意sed
命令将site/svelte.config.js
中的索引名称从'Pokedex'
更改为'Pokedex Clone'
这样您在开发时就不会意外弄乱此演示站点的搜索索引。