在 Docusaurus 页面的 Instantsearch.js 部分使用 Algolia Docsearch 索引
Use Algolia Docsearch index for Instantsearch.js section in Docusaurus page
我有一个使用 Docusaurus.io 构建的文档站点,并且我使用 Docsearch 作为我在导航栏中的搜索 - 这工作正常。但是,我也想在网站的登录页面上实施 Algolia 即时搜索。该代码在使用 instantsearch 设置的旧索引上运行良好,但是当我将新 Docsearch 索引的 API 键和 ID 插入 instantsearch 配置函数时,我得到了一个 JSON 对象流我无法理解。
这是我正在尝试使用的模板(它适用于我在 Jekyll 网站上的旧索引):
const hitTemplate = function(hit) {
console.log(hit);
let url = hit.url;
const title = hit.lvl1;
const content = hit._highlightResult.matchedWords;
return `
<div class="post-item">
<a class="post-link" href="${url}">
<h4>${title}</h4>
</a>
<div class="search-article-description">${content}</div>
<a href="${url}" class="read-more">Read More »</a>
</div>
`;
结果为空白 <div>
。
当没有应用模板时,我的结果返回为嵌套 JSON 个对象。
我要实现的是一个额外的即时搜索,它只出现在文档站点的主页上。据我了解,我在 Docsearch 中不能有两个输入选择器,这就是我一直尝试使用即时搜索的原因。我需要一个符合 Docsearch API returns 数据方式的模板。
经过一周的反复试验和 Docsearch 开发人员通过 github 提供的一些非常有价值的帮助,我想出了一个适用于我的文档站点的解决方案,并在此分享它,希望其他沮丧的 Docusaurus、Docsearch 和 Instantsearch 用户找到了解决方案:
在instantsearch.js
中(在website/static/js中找到):
// instantSearch on homepage
document.addEventListener('DOMContentLoaded', () => {
// Set initial parameters for instantsearch on the homepage
const mainSearch = instantsearch({
appId: '...',
apiKey: '...',
indexName: 'your-docsearch-index-name',
searchParameters: {
hitsPerPage: 10
},
routing: true
});
mainSearch.addWidget(
instantsearch.widgets.configure({
filters: 'version:1.5.5' // set latest version here
})
);
// initialize SearchBox
mainSearch.addWidget(
instantsearch.widgets.searchBox({
container: '#search_input_main',
placeholder: 'Search the Docs',
autofocus: false,
poweredBy: true
})
);
// add hits cont
mainSearch.addWidget(
instantsearch.widgets.hits({
container: '#search-hits',
templates: {
empty: 'No results for the search term <em>"{{query}}"</em>.',
item: $('#results-template').html() // this is the template at index.js
},
hitsPerPage: 10
})
);
// add pagination
mainSearch.addWidget(
instantsearch.widgets.pagination({
container: '#pagination-container',
maxPages: 20,
// default is to scroll to 'body', here we disable this behavior
scrollTo: '#search-container'
})
);
mainSearch.start();
// Toggle search results
const search_input_main = document.querySelector('#search_input_main');
const searchContainer = document.querySelector('#search-container');
// Bind keyup event on the input
search_input_main.addEventListener('keyup', function() {
if (search_input_main.value.length > 0) {
searchContainer.classList.remove('hidden');
} else {
searchContainer.classList.add('hidden');
}
});
// hide results on reset
document.querySelector('.ais-search-box--reset').addEventListener('click', function() {
searchContainer.classList.add('hidden');
});
});
这是我的 pages/en/index.js:
const React = require('react');
...
// for homepage instantsearch
let resultsTemplate = `
<script type="text/template" id="results-template">
<div class="ais-result">
{{#hierarchy.lvl0}}
<div class="ais-lvl0">
<a title="{{_highlightResult.hierarchy.lvl1.value}}" href="{{{url}}}"><h4>{{{_highlightResult.hierarchy.lvl0.value}}}</h4></a>
</div>
{{/hierarchy.lvl0}}
<div class="ais-lvl1 breadcrumbs">
{{#hierarchy.lvl1}} {{{_highlightResult.hierarchy.lvl1.value}}} {{/hierarchy.lvl1}} {{#hierarchy.lvl2}} > {{{_highlightResult.hierarchy.lvl2.value}}} {{/hierarchy.lvl2}} {{#hierarchy.lvl3}} > {{{_highlightResult.hierarchy.lvl3.value}}} {{/hierarchy.lvl3}}
{{#hierarchy.lvl4}} > {{{_highlightResult.hierarchy.lvl4.value}}} {{/hierarchy.lvl4}}
</div>
<div class="ais-content">
{{{#content}}} {{{_highlightResult.content.value}}} {{{/content}}}
</div>
</div>
</script>
`
...
const SearchInput = () => (
<div>
<div className='productShowcaseSection small-paddingBottom paddingTop' style={{textAlign: 'center'}}>
<h3>Get the most out of Stackery's serverless toolkit</h3>
<Container>
<div className='search_input_div'>
<input id="search_input_main" type="text" className="form-control" placeholder="Search the docs" aria-label="Search" aria-describedby="search"></input>
</div>
</Container>
</div>
</div>
);
const SearchHits = () => {
return (
<Container className='hidden' id='search-container'>
<h3>Search results:</h3>
<div id='search-hits'></div>
<div id='pagination-container'></div>
<div
dangerouslySetInnerHTML={{ __html: resultsTemplate }}
/>
</Container>
)
}
class HomeSplash extends React.Component {
render () {
const language = this.props.language || '';
return (
<SplashContainer>
<div className='inner'>
<ProjectTitle />
<PromoSection>
...
</PromoSection>
<SearchInput />
</div>
</SplashContainer>
);
}
}
...
class Index extends React.Component {
render () {
const language = this.props.language || '';
return (
<div>
<HomeSplash language={language} />
<SearchHits />
<BrowseDocs />
<TryIt />
</div>
);
}
}
module.exports = Index;
注意事项:
- 请务必添加
filters: 'version:your-version'
,否则即时搜索将为您的每个版本提供 return 结果,从而导致大量重复。
instantsearch.js
底部的 JQuery 用于根据搜索输入中的按键事件显示和隐藏 <div>
搜索结果出现的位置
- 我使用
const mainSearch = instantsearch({...
而不是 const search
的原因是默认导航栏 Docsearch 已经使用了 search
变量。如果您在页面上有多个搜索,则需要执行此操作。
- 虽然本指南是特定于 Docusaurus 的,但这个有用的 JSfiddle 展示了如何在普通静态站点上使用 Docsearch 索引实现即时搜索:https://jsfiddle.net/s_pace/965a4w3o/1/
- 如果您需要帮助在您自己的 Docusaurus 网站上实现此功能,请发表评论,我很乐意提供帮助
我有一个使用 Docusaurus.io 构建的文档站点,并且我使用 Docsearch 作为我在导航栏中的搜索 - 这工作正常。但是,我也想在网站的登录页面上实施 Algolia 即时搜索。该代码在使用 instantsearch 设置的旧索引上运行良好,但是当我将新 Docsearch 索引的 API 键和 ID 插入 instantsearch 配置函数时,我得到了一个 JSON 对象流我无法理解。
这是我正在尝试使用的模板(它适用于我在 Jekyll 网站上的旧索引):
const hitTemplate = function(hit) {
console.log(hit);
let url = hit.url;
const title = hit.lvl1;
const content = hit._highlightResult.matchedWords;
return `
<div class="post-item">
<a class="post-link" href="${url}">
<h4>${title}</h4>
</a>
<div class="search-article-description">${content}</div>
<a href="${url}" class="read-more">Read More »</a>
</div>
`;
结果为空白 <div>
。
当没有应用模板时,我的结果返回为嵌套 JSON 个对象。
我要实现的是一个额外的即时搜索,它只出现在文档站点的主页上。据我了解,我在 Docsearch 中不能有两个输入选择器,这就是我一直尝试使用即时搜索的原因。我需要一个符合 Docsearch API returns 数据方式的模板。
经过一周的反复试验和 Docsearch 开发人员通过 github 提供的一些非常有价值的帮助,我想出了一个适用于我的文档站点的解决方案,并在此分享它,希望其他沮丧的 Docusaurus、Docsearch 和 Instantsearch 用户找到了解决方案:
在instantsearch.js
中(在website/static/js中找到):
// instantSearch on homepage
document.addEventListener('DOMContentLoaded', () => {
// Set initial parameters for instantsearch on the homepage
const mainSearch = instantsearch({
appId: '...',
apiKey: '...',
indexName: 'your-docsearch-index-name',
searchParameters: {
hitsPerPage: 10
},
routing: true
});
mainSearch.addWidget(
instantsearch.widgets.configure({
filters: 'version:1.5.5' // set latest version here
})
);
// initialize SearchBox
mainSearch.addWidget(
instantsearch.widgets.searchBox({
container: '#search_input_main',
placeholder: 'Search the Docs',
autofocus: false,
poweredBy: true
})
);
// add hits cont
mainSearch.addWidget(
instantsearch.widgets.hits({
container: '#search-hits',
templates: {
empty: 'No results for the search term <em>"{{query}}"</em>.',
item: $('#results-template').html() // this is the template at index.js
},
hitsPerPage: 10
})
);
// add pagination
mainSearch.addWidget(
instantsearch.widgets.pagination({
container: '#pagination-container',
maxPages: 20,
// default is to scroll to 'body', here we disable this behavior
scrollTo: '#search-container'
})
);
mainSearch.start();
// Toggle search results
const search_input_main = document.querySelector('#search_input_main');
const searchContainer = document.querySelector('#search-container');
// Bind keyup event on the input
search_input_main.addEventListener('keyup', function() {
if (search_input_main.value.length > 0) {
searchContainer.classList.remove('hidden');
} else {
searchContainer.classList.add('hidden');
}
});
// hide results on reset
document.querySelector('.ais-search-box--reset').addEventListener('click', function() {
searchContainer.classList.add('hidden');
});
});
这是我的 pages/en/index.js:
const React = require('react');
...
// for homepage instantsearch
let resultsTemplate = `
<script type="text/template" id="results-template">
<div class="ais-result">
{{#hierarchy.lvl0}}
<div class="ais-lvl0">
<a title="{{_highlightResult.hierarchy.lvl1.value}}" href="{{{url}}}"><h4>{{{_highlightResult.hierarchy.lvl0.value}}}</h4></a>
</div>
{{/hierarchy.lvl0}}
<div class="ais-lvl1 breadcrumbs">
{{#hierarchy.lvl1}} {{{_highlightResult.hierarchy.lvl1.value}}} {{/hierarchy.lvl1}} {{#hierarchy.lvl2}} > {{{_highlightResult.hierarchy.lvl2.value}}} {{/hierarchy.lvl2}} {{#hierarchy.lvl3}} > {{{_highlightResult.hierarchy.lvl3.value}}} {{/hierarchy.lvl3}}
{{#hierarchy.lvl4}} > {{{_highlightResult.hierarchy.lvl4.value}}} {{/hierarchy.lvl4}}
</div>
<div class="ais-content">
{{{#content}}} {{{_highlightResult.content.value}}} {{{/content}}}
</div>
</div>
</script>
`
...
const SearchInput = () => (
<div>
<div className='productShowcaseSection small-paddingBottom paddingTop' style={{textAlign: 'center'}}>
<h3>Get the most out of Stackery's serverless toolkit</h3>
<Container>
<div className='search_input_div'>
<input id="search_input_main" type="text" className="form-control" placeholder="Search the docs" aria-label="Search" aria-describedby="search"></input>
</div>
</Container>
</div>
</div>
);
const SearchHits = () => {
return (
<Container className='hidden' id='search-container'>
<h3>Search results:</h3>
<div id='search-hits'></div>
<div id='pagination-container'></div>
<div
dangerouslySetInnerHTML={{ __html: resultsTemplate }}
/>
</Container>
)
}
class HomeSplash extends React.Component {
render () {
const language = this.props.language || '';
return (
<SplashContainer>
<div className='inner'>
<ProjectTitle />
<PromoSection>
...
</PromoSection>
<SearchInput />
</div>
</SplashContainer>
);
}
}
...
class Index extends React.Component {
render () {
const language = this.props.language || '';
return (
<div>
<HomeSplash language={language} />
<SearchHits />
<BrowseDocs />
<TryIt />
</div>
);
}
}
module.exports = Index;
注意事项:
- 请务必添加
filters: 'version:your-version'
,否则即时搜索将为您的每个版本提供 return 结果,从而导致大量重复。 instantsearch.js
底部的 JQuery 用于根据搜索输入中的按键事件显示和隐藏<div>
搜索结果出现的位置- 我使用
const mainSearch = instantsearch({...
而不是const search
的原因是默认导航栏 Docsearch 已经使用了search
变量。如果您在页面上有多个搜索,则需要执行此操作。 - 虽然本指南是特定于 Docusaurus 的,但这个有用的 JSfiddle 展示了如何在普通静态站点上使用 Docsearch 索引实现即时搜索:https://jsfiddle.net/s_pace/965a4w3o/1/
- 如果您需要帮助在您自己的 Docusaurus 网站上实现此功能,请发表评论,我很乐意提供帮助