Closed bildungsroman closed 5 years ago
A DocSearch hit looks like this:
{
"hierarchy": {
"lvl2": null,
"lvl3": null,
"lvl0": "Glossary of React Terms",
"lvl1": "Single-page Application",
"lvl6": null,
"lvl4": null,
"lvl5": null
},
"url": "https://reactjs.org/docs/glossary.html#single-page-application",
"content": null,
"anchor": "single-page-application",
"objectID": "3940650362",
"_highlightResult": {
"hierarchy": {
"lvl0": {
"value": "Glossary of React Terms",
"matchLevel": "none",
"matchedWords": []
},
"lvl1": {
"value": "<span class=\"algolia-docsearch-suggestion--highlight\">S</span>ingle-page Application",
"matchLevel": "full",
"fullyHighlighted": false,
"matchedWords": ["s"]
}
},
"hierarchy_camel": [
{
"lvl0": {
"value": "Glossary of React Terms",
"matchLevel": "none",
"matchedWords": []
},
"lvl1": {
"value": "<span class=\"algolia-docsearch-suggestion--highlight\">S</span>ingle-page Application",
"matchLevel": "full",
"fullyHighlighted": false,
"matchedWords": ["s"]
}
}
]
}
}
To go a bit more in detail about what each of these keys mean:
_highlightResult
This is an internal object, used for highlighting the text matching your query. It's finally this object that you will use to render to the page.
This object has the same shape as the main object, but with as the difference that it contains for each key the value, matchLevel and matchedWords. Value is what you use to display the match.
.hierarchy
and .hierarchy_camel
(disclaimer: I'm not on the DocSearch team)
These two object contain the same information, but use hierarchy_camel
first, and hierarchy
as a fallback (it might be there for backwards compatibility).
This object contains the hierarchy of the documentation page's match. It is split up in each of the level so you can make hierarchical displays like the original DocSearch.js.
These keys are used to do other things than displaying the match
This is the url of the current match, with the target on a specific ID.
I'm not completely sure why this is null
in the example I took and has content in your example, but this is the actual text which is matching. You'll also use the highlighted version of this (_highlightResult.content.value
)
A repeat of the anchor (ID) on the page of this match.
An internal unique ID for this record. It can be used as a key
or for other uniqueness reasons.
If you have any more questions, I'm happy to find out the answer, and I'll let @s-pace fill in some extra info as needed as well.
@Haroenv Thank you for the explanation, but I'm still having trouble translating that into a coherent view. For example, I just got TypeError: hit._highlightResult.content is undefined, can't access property "value" of it
when trying to reference hit._highlightResult.content
. It would be incredibly helpful if docsearch provided a template for displaying results in places other than the navbar.
@Haroenv I found this template in the repo, I wonder if you would know how to implement it in my case (sorry for the basic questions, I'm still fairly new to JS): https://github.com/algolia/docsearch/blob/master/src/lib/templates.js
The templates of DocSearch use a different format than InstantSearch; but Sylvain who I pinged earlier will give some more info :)
๐ @bildungsroman
Thank you for reaching out.
What @Haroenv said is ๐ฏ ๐
Just a small amendment regarding the use of .hierarchy_camel
, we are using it in order to avoid decomposition of camel case words on this attribute. It helps to promote record(s) that contains the full and not decomposed word from the query over records solely containing a camel case compound of it. You can find how we build these settings here.
Your index has record with content=null
because of the way we build a record. We do push record at every time we had an element to the temporary index. If you want to avoid such behaviour, you can use min_indexed_level
or only_content_level
from your configuration file. It will be effective at the next crawling (or when we will deploy your PR)
You can find a bootstrap of an implementation of DocSearch with InstantSearch here. It will help you to use the templates.
Please note that you can place the dropdown somewhere else within you page:
You will need to integrate the following snippet:
<!-- at the end of the HEAD -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css" />
<!-- at the end of the BODY -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"></script>
<script type="text/javascript"> docsearch({
apiKey: '1f37f3b055249d4873e7665523830077',
indexName: 'stackery',
inputSelector: '### REPLACE ME ####',
debug: false // Set debug to true if you want to inspect the dropdown
});
</script>
inputSelector
value in JS snippet to a CSS selector that targets your search input field.Happy to give any further details or help
@s-pace Thank you, I will try your jsfiddle and hopefully get it to work for me.
As for the dropdown, I would like it to remain on the navbar so that every page of my docs site has search. What I'm trying to implement is an additional instantsearch that only appears on the homepage of the docs site. From what I understand, I can't have two input selectors in docsearch, which is why I've been trying to use instantsearch like so (but of course my old instantsearch template doesn't work):
const search = instantsearch({
appId: '{{ site.algolia.application_id }}',
indexName: '{{ site.algolia.index_name }}',
apiKey: '{{ site.algolia.search_only_api_key }}'
});
const hitTemplate = function (hit) {
let url = `{{ site.baseurl }}${hit.url}`;
const title = hit._highlightResult.title.value;
const content = hit._highlightResult.content.value;
return `
<div class="post-item col-12">
<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>
`;
}
// Adding searchbar and results widgets
search.addWidget(
instantsearch.widgets.searchBox({
container: '#homepage-search',
placeholder: 'Search',
poweredBy: true
})
);
search.addWidget(
instantsearch.widgets.hits({
container: '#search-hits',
templates: {
item: hitTemplate
}
})
);
@s-pace Is there no way to implement your jsfiddle example using Algolia's template, as in my example above? The problem is I'm using Docusaurus rather than a normal HTML site, which means I have an index.js page built in React, and no index.html where I could actually add the <script type="text/template" id="ais-results-template">...</script>
template (this is pretty annoying on Docusarus' part, but it seams they're working to allow more customization in their V2). I've tried injecting it in the backend but keep getting SyntaxError: Unexpected token <
:(
i.e. something like this:
const mainSearch = instantsearch({
appId: '...',
apiKey: '...',
indexName: 'stackery',
routing: true
});
const hitTemplate = function (hit) {
return `
<div class="ais-result">
{{#hierarchy.lvl0}}
<div class="ais-lvl0">
{{{_highlightResult.hierarchy.lvl0.value}}}
</div>
{{/hierarchy.lvl0}}
<div class="ais-lvl1">
{{#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>
`;
}
// 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',
item: hitTemplate
// item: $('#results-template').html()
},
hitsPerPage: 10
})
);
// add pagination
mainSearch.addWidget(
instantsearch.widgets.pagination({
container: '#pagination-container',
maxPages: 10,
// default is to scroll to 'body', here we disable this behavior
scrollTo: false
})
);
mainSearch.start();
(but that doesn't work as-is)
Can you link the repo with this so far?
It's private unfortunately. But it uses Docusaurus without too much customization: https://github.com/facebook/Docusaurus/tree/master/v1/examples/basics
This is very similar to our index.js
page: https://github.com/facebook/Docusaurus/blob/master/v1/examples/basics/pages/en/index.js
The main difference is I've added two React Components to our index.js
, SearchInput
and SearchHits
:
const SearchInput = () => (
<div>
<div className='paddingTop productShowcaseSection' 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>
</Container>
)
}
This is my entire instantSearch.js
in its non-working version:
// instantSearch on homepage
document.addEventListener('DOMContentLoaded', () => {
// Find the active nav item in the sidebar
const mainSearch = instantsearch({
appId: '...',
apiKey: '...',
indexName: 'stackery',
routing: true
});
const resultsTemplate = function(hit) {
let url = hit.url;
const title = hit._highlightResult.hierarchy.lvl0.value;
const content = hit._highlightResult.content.value;
console.log(hit);
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>
`;
}
// 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',
// item: $('#results-template').html()
item: resultsTemplate
},
hitsPerPage: 10
})
);
// add pagination
mainSearch.addWidget(
instantsearch.widgets.pagination({
container: '#pagination-container',
maxPages: 10,
// default is to scroll to 'body', here we disable this behavior
scrollTo: false
})
);
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');
});
});
(the reason I'm using the variable mainSearch
instead of search
is because I already use search
for Docsearch in the navbar.
๐ @bildungsroman ,
You can integrate in your homepage the provided snippet twice with a different inputSelector
in order to have it in another place.
Since you are using react, what about using our dedicated react instantSearch library? It might be easier and more compliant.
@s-pace I wish I could, but the way Docusaurus is set up is that it only uses stateless React components to set up the static site, so there's no actual React on the frontend, just HTML. I need to inject that template into the HTML in the process.
I made a stackoverflow question with all of this laid out (hopefully more clearly): https://stackoverflow.com/questions/52523180/add-html-with-template-script-to-docusaurus-react-page
I think my problem is a special and frustrating intersection of Docusaurus and Docsearch, though I imagine I won't be the only one facing it as Docsearch is recommended in the Docusaurus documentation. I could see having an instantsearch section on the homepage in addition to the navbar search be a popular feature, and other users will run into this issue if there's not a template to use.
As for having a different inputSelector
, that does work, but no results are displayed. Is there a way to modify where the results are displayed, rather than in a modal below the search input?
Ok, I have a partial solution and a real solution! I hope the partial solution is incorporated into a template in the future :)
First, I followed @s-pace 's suggestion and set only_content_level=true
in my configuration file.
Then, for the partial solution, I used this template in my instantSearch.js
file:
const resultsTemplate = function(hit) {
let url = hit.url;
const title = hit.hierarchy.lvl1;
const content = hit._highlightResult.content.value;
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>
`;
}
I say this is partial because it only showed the top result, over and over... but hey, progress and hopefully something to build on.
This ended up being the actual solution:
const React = require('react');
let resultsTemplate = `
<script type="text/template" id="results-template">
<div class="ais-result">
{{#hierarchy.lvl0}}
<div class="ais-lvl0">
{{{_highlightResult.hierarchy.lvl0.value}}}
</div>
{{/hierarchy.lvl0}}
<div class="ais-lvl1">
{{#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>
`
class Footer extends React.Component {
...
render () {
return (
<footer className='nav-footer' id='footer'>
...
<div
dangerouslySetInnerHTML={{ __html: resultsTemplate }}
/>
</footer>
);
}
}
module.exports = Footer;
Note the use of the quote marks used for codeblocks rather than the normal " or ' - that did the trick.
Thank you everyone for your help! I hope this is of use to a future struggling dev.
One final question, @s-pace :
In your jsfiddle as well as in my site, I'm getting repeated results in the instantsearch that don't appear in the navbar docsearch (see screenshot). I'll work on optimizing the template myself, but any hints would be appreciated.
Specifically, each result or the contents of <div class="ais-result">...</div>
are being displayed 18 times... no idea why. In your jsfiddle, they're displayed only 6 times each, so it makes me think it has something to do with hitsPerPage
, but changing that to 1 had no effect for me.
I know this would be repeating work, but since docusaurus uses react, is an option to use react instantsearch? https://community.algolia.com/react-instantsearch/
๐ @bildungsroman ,
The search-UI natively integrated within your Docusaurus website is filtering over the current version thanks to the parameter facetFilters
For example for this page, the HTML contains the following meta:
<meta name="docsearch:language" content="en">
<meta name="docsearch:version" content="1.5.5">
These information are indexed within your record.
From the integrated snippet, it looks this way:
<script type="text/javascript"> docsearch({
apiKey: '1f37f3b055249d4873e7665523830077',
indexName: 'stackery',
inputSelector: '### REPLACE ME ####',
algoliaOptions: { 'facetFilters': ["version:$VERSION", "language:$LANGUAGE"] },
debug: false // Set debug to true if you want to inspect the dropdown
});
</script>
You should replace $VERSION
with the version you want to search on. The list of possible version is picked up from your meta data.
So as of today you have: 0.0.1
, 0.0.2
, 0.0.3
, 0.0.4
, 0.0.5
, 0.1.0
, 1.3.0
, 1.4.3
, 1.4.5
, 1.4.6
, 1.4.7
, 1.5.0
, 1.5.1
, 1.5.2
, 1.5.3
, 1.5.4
, 1.5.5
, next
(you know why you have a record being displayed 18 times now)
Do not forget $LANGUAGE
and replace it with the language you want to search on. The list of possible version is also picked up from your meta data. So as of today you have only one: en
You should refine the search to the current version. For example for the version "0.0.1" and the language "en", just specify:
'facetFilters': ["version:0.0.1", "language:en"]
You will need to integrate these facetFilters
within your search. You can find some documentation helping you in this way in the instantSearch related materials.
Let us know when you are done with it.
@Haroenv Unfortunately Docusaurus uses React only on the back-end to build a static site, so that wouldn't work. What's served is static HTML, and stateful components don't work (I've tried this already and the Docusaurus docs support this).
@s-pace I'm not using the Docsearch UI for this, I'm using the Instantsearch UI, where the problem lies. I tried setting facetFilters
and it did nothing:
const mainSearch = instantsearch({
appId: '...',
apiKey: '...',
indexName: 'stackery',
algoliaOptions: { 'facetFilters': ["version:1.5.5", "language:en"] },
routing: true
});
The problem is I'm still seeing repeated results in my instantsearch that don't appear in my docsearch - see screenshot:
The "CLI Reference" item appears 18 times before the next item appears, whereas in the navbar Docsearch it only appears once, as it should.
Right now I'm realizing this is a problem of formatting and building the right template that makes instantsearch work with a docsearch index without displaying results from every version (and potentially every language).
@s-pace Just to test, I tried changing to this:
docsearch({
apiKey: "...",
indexName: "stackery",
inputSelector: "#search_input_react",
algoliaOptions: { // sets which version's results are displayed
facetFilters: [ "language:en", "version:next" ]
},
debug: true // Set debug to true if you want to inspect the dropdown
});
in every place Docsearch appears, and still no luck :(
I'm going to try to build a filtering function that eliminates multiple results, as I see no other way to do it.
What would be super helpful is if Docsearch returned a version property (i.e. hit._highlightResult.version
), then I could filter hit
based on version. Is there a way to add that to my config file?
I've hacked this together - not the best solution, but could be useful to anyone else using Docusaurus. The downside is you have to manually set the versions:
mainSearch.addWidget(
instantsearch.widgets.hits({
container: '#search-hits',
templates: {
empty: 'No results',
item: $('#results-template').html()
},
transformData: {
item: function(hit) {
const versions = ['0.0.1', '0.0.2', '0.0.3', '0.0.4', '0.0.5', '0.1.0', '1.3.0', '1.4.3', '1.4.5', '1.4.6', '1.4.7', '1.5.0', '1.5.1', '1.5.2', '1.5.3', '1.5.4', 'next']
for (let i=0;i<versions.length;i++) {
if (hit.url.indexOf(versions[i]) > -1) {
hit.version = versions[i];
hit.oldVersion = true;
break;
} else {
hit.version = "current";
}
}
return hit;
}
},
hitsPerPage: 10
})
);
Edit: I found another (major) downside: I still have to return hit;
, even for an old version (otherwise I get no results for some reason). I added the hit.oldVersion
flag to filter in the template:
let resultsTemplate = `
<script type="text/template" id="results-template">
<div class="ais-result">
{{^oldVersion}}
{{#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>
{{/oldVersion}}
</div>
</script>
`
While this works, the DOM still thinks there are more results, they're just not shown, but that means with pagination on I get empty pages followed by a page of several results. If I turn pagination off, I just get what would be on the first page of paginated results (with everything else hidden). Not sure what to do about this :(
you can filter on version
in InstantSearch.js like this:
search.addWidget(
instantsearch.widgets.configure({
filters: 'version:XXX'
})
);
@Haroenv That ended up doing the trick, thank you!!
For any Docusaurus users googling their way here, this ended up being my working function:
In instantsearch.js
(found in website/static/js):
// instantSearch on homepage
document.addEventListener('DOMContentLoaded', () => {
// Set initial parameters for instantsearch on the homepage
const mainSearch = instantsearch({
appId: '...',
apiKey: '...',
indexName: 'stackery',
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');
});
});
And this is my 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;
Thank you again @Haroenv and @s-pace!
Glad this all got resolved, and sorry it took a while :)
Do you want to request a feature or report a bug?
Feature request (or explanation of how to implement if this exists).
What is the current behavior?
I have a documentation site built using docusaurus.io, and am using Docsearch as my search in the navbar - this is working fine. However, I'd like to implement Algolia instantsearch on the landing page of the site as well. The code is working fine with an old index set up with instantsearch, but when I plug in the API key and ID of the new docsearch index into the
instantsearch
config function, I get a stream of JSON objects that I can't make sense of.This is the template I'm trying to use (which worked on my old index on a jekyll site):
That results in a blank
<div>
.This is what my results look like when no template is applied:
What is the expected behavior?
Being able to display results in a coherent way, as when using a standard Algolia index.