mirror of https://github.com/vuejs/vitepress
parent
1d72e88341
commit
f42fe88f3e
@ -0,0 +1,379 @@
|
||||
---
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Buscar {#search}
|
||||
|
||||
## Busqueda local {#local-search}
|
||||
|
||||
VitePress admite la búsqueda de texto completo utilizando un índice en el navegador gracias a [minisearch](https://github.com/lucaong/minisearch/). Para habilitar esta función, simplemente configure la opción `themeConfig.search.provider` como `'local'` en el archivo `.vitepress/config.ts`:
|
||||
|
||||
```ts
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
export default defineConfig({
|
||||
themeConfig: {
|
||||
search: {
|
||||
provider: 'local'
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Resultado de ejemplo:
|
||||
|
||||

|
||||
|
||||
Alternativamente, puedes usar [Algolia DocSearch](#algolia-search) ou algunos complementos comunitarios como <https://www.npmjs.com/package/vitepress-plugin-search> o <https://www.npmjs.com/package/vitepress-plugin-pagefind>.
|
||||
|
||||
### i18n {#local-search-i18n}
|
||||
|
||||
Puede utilizar una configuración como esta para utilizar la búsqueda multilingüe:
|
||||
|
||||
```ts
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
export default defineConfig({
|
||||
themeConfig: {
|
||||
search: {
|
||||
provider: 'local',
|
||||
options: {
|
||||
locales: {
|
||||
zh: {
|
||||
translations: {
|
||||
button: {
|
||||
buttonText: '搜索文档',
|
||||
buttonAriaLabel: '搜索文档'
|
||||
},
|
||||
modal: {
|
||||
noResultsText: '无法找到相关结果',
|
||||
resetButtonTitle: '清除查询条件',
|
||||
footer: {
|
||||
selectText: '选择',
|
||||
navigateText: '切换'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### Opciones MiniSearch {#mini-search-options}
|
||||
|
||||
Puedes configurar MiniSearch de esta manera:
|
||||
|
||||
```ts
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
export default defineConfig({
|
||||
themeConfig: {
|
||||
search: {
|
||||
provider: 'local',
|
||||
options: {
|
||||
miniSearch: {
|
||||
/**
|
||||
* @type {Pick<import('minisearch').Options, 'extractField' | 'tokenize' | 'processTerm'>}
|
||||
*/
|
||||
options: {
|
||||
/* ... */
|
||||
},
|
||||
/**
|
||||
* @type {import('minisearch').SearchOptions}
|
||||
* @default
|
||||
* { fuzzy: 0.2, prefix: true, boost: { title: 4, text: 2, titles: 1 } }
|
||||
*/
|
||||
searchOptions: {
|
||||
/* ... */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Obtenga más información en [documentação do MiniSearch](https://lucaong.github.io/minisearch/classes/MiniSearch.MiniSearch.html).
|
||||
|
||||
### Presentador de contenido personalizado {#custom-content-renderer}
|
||||
|
||||
Puedes personalizar la función utilizada para presentar el contenido de rebajas antes de indexarlo:
|
||||
|
||||
```ts
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
export default defineConfig({
|
||||
themeConfig: {
|
||||
search: {
|
||||
provider: 'local',
|
||||
options: {
|
||||
/**
|
||||
* @param {string} src
|
||||
* @param {import('vitepress').MarkdownEnv} env
|
||||
* @param {import('markdown-it')} md
|
||||
*/
|
||||
_render(src, env, md) {
|
||||
// retorne a string HTML
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
Esta función se eliminará de los datos del sitio web en el lado del cliente, por lo que podrá utilizar las API de Node.js en ella.
|
||||
|
||||
#### Ejemplo: Excluir páginas de la busqueda {#example-excluding-pages-from-search}
|
||||
|
||||
Puedes excluir páginas de la busqueda adicionando `search: false` al principio de la página. Alternativamente:
|
||||
|
||||
```ts
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
export default defineConfig({
|
||||
themeConfig: {
|
||||
search: {
|
||||
provider: 'local',
|
||||
options: {
|
||||
_render(src, env, md) {
|
||||
const html = md.render(src, env)
|
||||
if (env.frontmatter?.search === false) return ''
|
||||
if (env.relativePath.startsWith('algum/caminho')) return ''
|
||||
return html
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
::: warning Nota
|
||||
En este caso, una función `_render` se proporciona, es necesario manipular el `search: false` desde el frente por su cuenta. Además, el objeto `env` não estará completamente populado antes que `md.render` no estará completamente poblado antes `env`, como `frontmatter`, debe hacerse después de eso.
|
||||
:::
|
||||
|
||||
#### Ejemplo: Transformar contenido - agregar anclajes {#example-transforming-content-adding-anchors}
|
||||
|
||||
```ts
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
export default defineConfig({
|
||||
themeConfig: {
|
||||
search: {
|
||||
provider: 'local',
|
||||
options: {
|
||||
_render(src, env, md) {
|
||||
const html = md.render(src, env)
|
||||
if (env.frontmatter?.title)
|
||||
return md.render(`# ${env.frontmatter.title}`) + html
|
||||
return html
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Pesquisa Algolia {#algolia-search}
|
||||
|
||||
VitePress admite la búsqueda en su sitio de documentación utilizando [Algolia DocSearch](https://docsearch.algolia.com/docs/what-is-docsearch). Consulte su guía de introducción. en tu archivo `.vitepress/config.ts`, Deberá proporcionar al menos lo siguiente para que funcione:
|
||||
|
||||
```ts
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
export default defineConfig({
|
||||
themeConfig: {
|
||||
search: {
|
||||
provider: 'algolia',
|
||||
options: {
|
||||
appId: '...',
|
||||
apiKey: '...',
|
||||
indexName: '...'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### i18n {#algolia-search-i18n} {#algolia-search-i18n}
|
||||
|
||||
Puede utilizar una configuración como esta para utilizar la búsqueda multilingüe:
|
||||
|
||||
```ts
|
||||
import { defineConfig } from 'vitepress'
|
||||
|
||||
export default defineConfig({
|
||||
themeConfig: {
|
||||
search: {
|
||||
provider: 'algolia',
|
||||
options: {
|
||||
appId: '...',
|
||||
apiKey: '...',
|
||||
indexName: '...',
|
||||
locales: {
|
||||
zh: {
|
||||
placeholder: '搜索文档',
|
||||
translations: {
|
||||
button: {
|
||||
buttonText: '搜索文档',
|
||||
buttonAriaLabel: '搜索文档'
|
||||
},
|
||||
modal: {
|
||||
searchBox: {
|
||||
resetButtonTitle: '清除查询条件',
|
||||
resetButtonAriaLabel: '清除查询条件',
|
||||
cancelButtonText: '取消',
|
||||
cancelButtonAriaLabel: '取消'
|
||||
},
|
||||
startScreen: {
|
||||
recentSearchesTitle: '搜索历史',
|
||||
noRecentSearchesText: '没有搜索历史',
|
||||
saveRecentSearchButtonTitle: '保存至搜索历史',
|
||||
removeRecentSearchButtonTitle: '从搜索历史中移除',
|
||||
favoriteSearchesTitle: '收藏',
|
||||
removeFavoriteSearchButtonTitle: '从收藏中移除'
|
||||
},
|
||||
errorScreen: {
|
||||
titleText: '无法获取结果',
|
||||
helpText: '你可能需要检查你的网络连接'
|
||||
},
|
||||
footer: {
|
||||
selectText: '选择',
|
||||
navigateText: '切换',
|
||||
closeText: '关闭',
|
||||
searchByText: '搜索提供者'
|
||||
},
|
||||
noResultsScreen: {
|
||||
noResultsText: '无法找到相关结果',
|
||||
suggestedQueryText: '你可以尝试查询',
|
||||
reportMissingResultsText: '你认为该查询应该有结果?',
|
||||
reportMissingResultsLinkText: '点击反馈'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
[Estas opciones](https://github.com/vuejs/vitepress/blob/main/types/docsearch.d.ts) se pueden superponer. Consulte la documentación oficial de Algolia para obtener más información sobre ellos.
|
||||
|
||||
### Configuración _Crawler_ {#crawler-config}
|
||||
|
||||
A continuación se muestra un ejemplo de la configuración que utiliza este sitio:
|
||||
|
||||
```ts
|
||||
new Crawler({
|
||||
appId: '...',
|
||||
apiKey: '...',
|
||||
rateLimit: 8,
|
||||
startUrls: ['https://vitepress.dev/'],
|
||||
renderJavaScript: false,
|
||||
sitemaps: [],
|
||||
exclusionPatterns: [],
|
||||
ignoreCanonicalTo: false,
|
||||
discoveryPatterns: ['https://vitepress.dev/**'],
|
||||
schedule: 'at 05:10 on Saturday',
|
||||
actions: [
|
||||
{
|
||||
indexName: 'vitepress',
|
||||
pathsToMatch: ['https://vitepress.dev/**'],
|
||||
recordExtractor: ({ $, helpers }) => {
|
||||
return helpers.docsearch({
|
||||
recordProps: {
|
||||
lvl1: '.content h1',
|
||||
content: '.content p, .content li',
|
||||
lvl0: {
|
||||
selectors: '',
|
||||
defaultValue: 'Documentation'
|
||||
},
|
||||
lvl2: '.content h2',
|
||||
lvl3: '.content h3',
|
||||
lvl4: '.content h4',
|
||||
lvl5: '.content h5'
|
||||
},
|
||||
indexHeadings: true
|
||||
})
|
||||
}
|
||||
}
|
||||
],
|
||||
initialIndexSettings: {
|
||||
vitepress: {
|
||||
attributesForFaceting: ['type', 'lang'],
|
||||
attributesToRetrieve: ['hierarchy', 'content', 'anchor', 'url'],
|
||||
attributesToHighlight: ['hierarchy', 'hierarchy_camel', 'content'],
|
||||
attributesToSnippet: ['content:10'],
|
||||
camelCaseAttributes: ['hierarchy', 'hierarchy_radio', 'content'],
|
||||
searchableAttributes: [
|
||||
'unordered(hierarchy_radio_camel.lvl0)',
|
||||
'unordered(hierarchy_radio.lvl0)',
|
||||
'unordered(hierarchy_radio_camel.lvl1)',
|
||||
'unordered(hierarchy_radio.lvl1)',
|
||||
'unordered(hierarchy_radio_camel.lvl2)',
|
||||
'unordered(hierarchy_radio.lvl2)',
|
||||
'unordered(hierarchy_radio_camel.lvl3)',
|
||||
'unordered(hierarchy_radio.lvl3)',
|
||||
'unordered(hierarchy_radio_camel.lvl4)',
|
||||
'unordered(hierarchy_radio.lvl4)',
|
||||
'unordered(hierarchy_radio_camel.lvl5)',
|
||||
'unordered(hierarchy_radio.lvl5)',
|
||||
'unordered(hierarchy_radio_camel.lvl6)',
|
||||
'unordered(hierarchy_radio.lvl6)',
|
||||
'unordered(hierarchy_camel.lvl0)',
|
||||
'unordered(hierarchy.lvl0)',
|
||||
'unordered(hierarchy_camel.lvl1)',
|
||||
'unordered(hierarchy.lvl1)',
|
||||
'unordered(hierarchy_camel.lvl2)',
|
||||
'unordered(hierarchy.lvl2)',
|
||||
'unordered(hierarchy_camel.lvl3)',
|
||||
'unordered(hierarchy.lvl3)',
|
||||
'unordered(hierarchy_camel.lvl4)',
|
||||
'unordered(hierarchy.lvl4)',
|
||||
'unordered(hierarchy_camel.lvl5)',
|
||||
'unordered(hierarchy.lvl5)',
|
||||
'unordered(hierarchy_camel.lvl6)',
|
||||
'unordered(hierarchy.lvl6)',
|
||||
'content'
|
||||
],
|
||||
distinct: true,
|
||||
attributeForDistinct: 'url',
|
||||
customRanking: [
|
||||
'desc(weight.pageRank)',
|
||||
'desc(weight.level)',
|
||||
'asc(weight.position)'
|
||||
],
|
||||
ranking: [
|
||||
'words',
|
||||
'filters',
|
||||
'typo',
|
||||
'attribute',
|
||||
'proximity',
|
||||
'exact',
|
||||
'custom'
|
||||
],
|
||||
highlightPreTag: '<span class="algolia-docsearch-suggestion--highlight">',
|
||||
highlightPostTag: '</span>',
|
||||
minWordSizefor1Typo: 3,
|
||||
minWordSizefor2Typos: 7,
|
||||
allowTyposOnNumericTokens: false,
|
||||
minProximity: 1,
|
||||
ignorePlurals: true,
|
||||
advancedSyntax: true,
|
||||
attributeCriteriaComputedByMinProximity: true,
|
||||
removeWordsIfNoResults: 'allOptional'
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
<style>
|
||||
img[src="/search.png"] {
|
||||
width: 100%;
|
||||
aspect-ratio: 1 / 1;
|
||||
}
|
||||
</style>
|
Loading…
Reference in new issue