Buscar
Busqueda local
VitePress admite la búsqueda de texto completo utilizando un índice en el navegador gracias a minisearch. Para habilitar esta función, simplemente configure la opción themeConfig.search.provider
como 'local'
en el archivo .vitepress/config.ts
:
import { defineConfig } from 'vitepress' export default defineConfig({ themeConfig: { search: { provider: 'local' } } })
Resultado de ejemplo:
Alternativamente, puedes usar Algolia DocSearch o algunos complementos comunitarios como https://www.npmjs.com/package/vitepress-plugin-search o https://www.npmjs.com/package/vitepress-plugin-pagefind.
i18n
Puede utilizar una configuración como esta para utilizar la búsqueda multilingüe:
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
Puedes configurar MiniSearch de esta manera:
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 documentación de MiniSearch.
Presentador de contenido personalizado
Puedes personalizar la función utilizada para presentar el contenido de rebajas antes de indexarlo:
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 un 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
Puedes excluir páginas de la busqueda adicionando search: false
al principio de la página. Alternativamente:
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 } } } } })
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
no estará completamente poblado antes que md.render
se llama, luego verifica las propiedades opcionales env
, como frontmatter
, debe hacerse después de eso.
Ejemplo: Transformar contenido - agregar anclajes
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 } } } } })
Busqueda de Algolia
VitePress admite la búsqueda en su sitio de documentación utilizando Algolia DocSearch. Consulte su guía de introducción. en tu archivo .vitepress/config.ts
, Deberá proporcionar al menos lo siguiente para que funcione:
import { defineConfig } from 'vitepress' export default defineConfig({ themeConfig: { search: { provider: 'algolia', options: { appId: '...', apiKey: '...', indexName: '...' } } } })
i18n {#algolia-search-i18n}
Puedes utilizar una configuración como esta para utilizar la búsqueda multilingüe:
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 se pueden superponer. Consulte la documentación oficial de Algolia para obtener más información sobre ellos.
Configuración Crawler
A continuación se muestra un ejemplo de la configuración que utiliza este sitio:
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: 'section.has-active div h2', 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' } } })