const searchClient = algoliasearch(
"latency",
"b37781ea260eea196da5b3346d5ff4c9"
);
const search = instantsearch({
indexName: "instant_search",
searchClient
});
search.addWidget(
instantsearch.widgets.searchBox({
container: "#searchbox",
placeholder: "Search for products, brands or categories"
})
);
search.addWidget(
instantsearch.widgets.hits({
container: "#hits",
templates: {
item: data => `
<img src="${data.image}"/>
<div>
<div class="hit-title">
<h4>${instantsearch.highlight({
attribute: "name",
hit: data
})}</h4>
<div class="price">$${data.price}</div>
</div>
<p>${instantsearch.highlight({
attribute: "description",
hit: data
})}</p>
</div>
`,
empty: "<h1>No results... please consider another query</h1>"
}
})
);
search.addWidget(
instantsearch.widgets.refinementList({
container: "#brands",
attribute: "brand",
searchable: true,
searchablePlaceholder: "Search for brands"
})
);
search.addWidget(
instantsearch.widgets.hierarchicalMenu({
container: "#categories",
attributes: [
"hierarchicalCategories.lvl0",
"hierarchicalCategories.lvl1",
"hierarchicalCategories.lvl2"
]
})
);
search.addWidget(
instantsearch.widgets.rangeInput({
container: "#price",
attribute: "price"
})
);
search.addWidget(
instantsearch.widgets.clearRefinements({
container: "#clear-all"
})
);
// add widget
search.start();
<!DOCTYPE html>
<html>
<head>
<title>InstantSearch for Vanilla JS</title>
<script src="https://cdn.jsdelivr.net/npm/algoliasearch@3.32.0/dist/algoliasearchLite.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/instantsearch.js@3.1.1/dist/instantsearch.production.min.js"></script>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/instantsearch.css@7.1.0/themes/reset-min.css"
/>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<header>
<div id="searchbox"></div>
</header>
<main>
<div id="left-column">
<div id="clear-all"></div>
<h5 class="filter-title">Brands</h5>
<div class="filter-widgets" id="brands"></div>
<h5 class="filter-title">Categories</h5>
<div class="filter-widgets" id="categories"></div>
<h5 class="filter-title">Price</h5>
<div class="filter-widgets" id="price"></div>
</div>
<div id="right-column">
<div id="hits"></div>
</div>
</main>
<script src="app.js"></script>
</body>
</html>
/* Variables */
:root {
--input-width: 965px;
}
/* Layout */
body {
max-width: 1000px;
margin: 20px auto;
font-family: Helvetica, Arial, sans-serif;
}
header {
margin: 30px 0 30px 0;
}
main {
display: flex;
margin-top: 10px;
}
#left-column {
flex-basis: 30%;
}
#right-column {
flex-basis: 70%;
display: flex;
flex-direction: column;
}
/* Searchbox */
#searchbox div.ais-SearchBox {
width: 100%;
max-width: 100%;
}
#searchbox input.ais-SearchBox-input {
width: var(--input-width);
border: none;
border-bottom: #eee solid 4px;
box-shadow: none;
border-radius: 0;
font-size: 1.3em;
padding-left: 34px;
padding-bottom: 6px;
font-weight: 500;
color: #3a4570;
}
#searchbox input.ais-SearchBox-input::placeholder {
color: #ccc;
}
#searchbox .ais-SearchBox-submit {
position: relative;
bottom: 30px;
outline: none;
}
#searchbox .ais-SearchBox-submitIcon {
height: 18px;
width: 18px;
}
#searchbox .ais-SearchBox-reset {
position: relative;
bottom: 30px;
left: var(--input-width);
outline: none;
}
#searchbox .ais-SearchBox-resetIcon {
height: 14px;
width: 14px;
}
.ais-SearchBox-input:focus {
outline: none;
}
/* Hits */
.hit-title {
display: flex;
flex-wrap: nowrap;
justify-content: space-between;
}
.hit-title > .price {
display: flex;
margin-top: 5px;
height: 16px;
font-weight: normal;
border: 1px solid grey;
padding: 2px 6px;
border-radius: 250px;
font-size: 0.9em;
align-items: center;
}
main h4 {
font-size: 1em;
color: #222;
margin-top: 4px;
margin-bottom: 4px;
line-height: 1.5;
}
mark {
background-color: #dfe2ee;
}
.ais-Hits-item {
display: flex;
flex-direction: row;
align-items: center;
border-bottom: 2px solid #eee;
padding-bottom: 20px;
margin-bottom: 15px;
margin-top: 5px;
}
.ais-Hits-item img {
object-fit: contain;
width: 80px;
min-width: 80px;
max-height: 80px;
margin-right: 25px;
}
div.content {
display: flex;
flex-direction: column;
max-width: 750px;
}
p {
margin: 0;
color: #666;
text-align: justify;
font-size: 0.9em;
line-height: 1.3;
}
/* Widgets */
/* Widgets - general */
h5.filter-title {
font-size: 1.05em;
font-weight: bold;
border: none;
margin-top: 0;
margin-bottom: 5px;
text-transform: uppercase;
color: #3a4570;
}
#left-column .ais-root {
margin-bottom: 20px;
}
.filter-widgets:not(:last-child) {
border-bottom: #eee solid 3px;
margin-right: 30px;
margin-bottom: 20px;
}
.ais-RefinementList-item,
.ais-HierarchicalMenu-item,
.ais-Menu-item {
margin-bottom: 7px;
}
.ais-RefinementList-item--selected,
.ais-HierarchicalMenu-item--selected > div > a,
.ais-Menu-item--selected {
font-weight: bold;
}
.ais-RefinementList-label,
.ais-HierarchicalMenu-link,
.ais-Menu-link {
color: rgb(58, 69, 112);
cursor: pointer;
text-decoration: none;
}
span.ais-RefinementList-count,
.ais-HierarchicalMenu-count,
.ais-Menu-count {
margin-left: 5px;
padding: 0.1rem 0.4rem;
font-size: 0.8rem;
color: #3a4570;
background-color: #dfe2ee;
border-radius: 15px;
cursor: pointer;
}
/* Widget - RefinementList */
.ais-RefinementList-checkbox {
margin-left: 0;
}
.ais-RefinementList input[type="search"] {
border: none;
border-radius: 0;
border-bottom: 1px solid #c4c8d8;
font-size: 1em;
box-shadow: none;
padding-left: 16px;
width: 100%;
margin: 5px 0;
}
.ais-RefinementList input[type="search"]::placeholder {
color: #c4c8d8;
}
.ais-RefinementList-searchBox .ais-SearchBox-form > .ais-SearchBox-submit {
position: relative;
bottom: 25px;
outline: none;
}
.ais-RefinementList-searchBox .ais-SearchBox-form > .ais-SearchBox-reset {
display: none;
}
/* Widget - HierarchicalMenu */
.ais-HierarchicalMenu-item--selected > div {
margin-top: 5px;
}
.ais-HierarchicalMenu-item--selected > div > a::after {
margin-left: 5px;
}
/* Widget - RangeInput */
.ais-RangeInput-submit,
.ais-RangeInput-submit:hover {
background-color: #dfe2ee;
color: #3a4570;
padding: 0.2rem 0.6rem;
font-size: 1em;
margin-left: 5px;
border-radius: 15px;
border: none;
cursor: pointer;
}
.ais-RangeInput-submit:focus {
outline: none;
}
.ais-RangeInput-input--min,
.ais-RangeInput-input--max {
width: 70px;
min-width: 70px;
font-size: 1em;
}
.ais-RangeInput-separator {
margin: 0 5px;
}
/* Widget - Pagination */
#pagination {
align-self: center;
}
.ais-Pagination-link {
padding: 0.3rem 0.6rem;
margin-right: 3px;
display: block;
border: 1px solid #c4c8d8;
border-radius: 5px;
transition: background-color 0.2s ease-out;
text-decoration: none;
}
.ais-Pagination-link {
color: #3a4570;
}
.ais-Pagination-link:hover {
background: #e3e5ec;
}
.ais-Pagination-item--selected a,
.ais-Pagination-item--selected a:hover {
background-color: #3a4570;
border-color: #3a4570;
color: white;
}
/* Widget - ClearRefinements */
.ais-ClearRefinements-button {
border: none;
outline: none;
border-radius: 0;
border: solid 1px #dfe2ee;
color: #3a4570;
padding: 0.25em 1.4em;
border-radius: 40px;
font-size: 1em;
margin-bottom: 15px;
width: 100%;
}
.ais-ClearRefinements-button:hover {
background-color: #dfe2ee;
}
.ais-ClearRefinements-button--disabled {
display: none;
}
#clear-all {
border: none;
margin-bottom: 0px;
}
/* Widget - Stats */
.ais-Stats {
text-align: right;
margin-top: 2px;
font-size: 0.8em;
}