Adding Algolia InstantSearch to my site
03 Jul 2021
Here’s my code
Minimum viable build
I created a file c:\example\algoliaindex.html
and double-clicked it to open it in my browser.
To get Algolia working at all, I had to put a DIV
into my HTML with an ID that had a distinctive name, such as search-searchbar
.
Then, in addition to importing some JavaScript libraries from 3rd parties, I had to put some JavaScript into my codebase that:
- Prepared InstantSearch by instantiating it as a variable called
search
. - Called upon the
addWidget()
function ofsearch
, passing it InstantSearch’ssearchBox
widget, wiring it up by ID to look forsearch-searchbar
in my DOM (this is also where I configured placeholder text). - Told InstantSearch to go ahead and inject widgets into my DOM with the
start()
function ofsearch
.
Here’s what algoliaindex.html
looks like:
<html>
<head>
<title>Algolia index experiment</title>
</head>
<body>
<p>Hello, world</p>
<div id="search-searchbar"></div>
<p>Well, that was neat</p>
<!-- Start end-of-page scripts -->
<!-- Import the basic InstantSearch library -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/instantsearch.min.js"></script>
<!-- Import moment for date parsing -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
<!-- Make InstantSearch put widgets in the DOM -->
<script>
// --- Prep InstantSearch ---
const search = instantsearch({
appId: "MY_APP_ID",
apiKey: "MY_SEARCH_ONLY_API_KEY",
indexName: "MY_INDEX_NAME",
});
// --- Define some custom helpers ---
// TO DO
// --- Define the "searchbar" as using the "searchBox" widget
search.addWidget(
instantsearch.widgets.searchBox({
container: "#search-searchbar",
placeholder: "Search this site...",
poweredBy: true, // This is required if you're on the free Community plan
autofocus: false,
})
);
// --- Throw InstantSearch into the DOM ---
search.start();
</script>
<!-- End end-of-page scripts -->
</body>
</html>
When I refreshed it in my browser, I saw the following lines of content:
- “Hello, world”
- A “search this site…” box
- “Search by Algolia”
- A massive magnifying glass
- “Well, that was neat”
If I typed “hello” into the search box, I could see my request come in at https://algolia.com/apps/MY_APP_ID/monitoring/logs
. When I clicked the latest result and inspected the Request body, its params included the phrase query=hello
, so everything’s working great.
Hooray, I have a minimum viable build for my Algolia front-end code! It looks terrible and doesn’t yet display any results on my page, but it appears at all, and it functions.
Search box CSS
Inspecting the page with my browser’s developer tools, I see that Algolia injected a lot into my search-searchbar
so that it looks like this in the DOM:
<div id="search-searchbar">
<div class="ais-search-box">
<input
autocapitalize="none"
autocomplete="off"
autocorrect="off"
placeholder="Search this site..."
role="textbox"
spellcheck="false"
type="text"
value=""
class="ais-search-box--input"
/>
<span class="">
<div class="ais-search-box--powered-by">
Search by
<a
class="ais-search-box--powered-by-link"
href="https://www.algolia.com/?utm_source=instantsearch.js&utm_medium=website&utm_content=&utm_campaign=poweredby"
target="_blank"
>Algolia</a>
</div>
</span>
<span class="ais-search-box--magnifier-wrapper">
<div class="ais-search-box--magnifier">
<svg
xmlns="http://www.w3.org/2000/svg"
id="sbx-icon-search-13"
viewBox="0 0 40 40"
width="100%"
height="100%"
>
<path
d="M26.804 29.01c-2.832 2.34-6.465 3.746-10.426 3.746C7.333 32.756 0 25.424 0 16.378 0 7.333 7.333 0 16.378 0c9.046 0 16.378 7.333 16.378 16.378 0 3.96-1.406 7.594-3.746 10.426l10.534 10.534c.607.607.61 1.59-.004 2.202-.61.61-1.597.61-2.202.004L26.804 29.01zm-10.426.627c7.323 0 13.26-5.936 13.26-13.26 0-7.32-5.937-13.257-13.26-13.257C9.056 3.12 3.12 9.056 3.12 16.378c0 7.323 5.936 13.26 13.258 13.26z"
fill-rule="evenodd"
></path>
</svg>
</div>
</span>
<span class="ais-search-box--reset-wrapper" style="display: none">
<button
type="reset"
title="Clear the search query."
class="ais-search-box--reset"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
width="100%"
height="100%"
>
<path
d="M8.114 10L.944 2.83 0 1.885 1.886 0l.943.943L10 8.113l7.17-7.17.944-.943L20 1.886l-.943.943-7.17 7.17 7.17 7.17.943.944L18.114 20l-.943-.943-7.17-7.17-7.17 7.17-.944.943L0 18.114l.943-.943L8.113 10z"
fill-rule="evenodd"
></path>
</svg>
</button>
</span>
</div>
</div>
It looks like I’ll want to consider defining CSS for div.ais-search-box
and its sub-elements:
input.ais-search-box--input
div.ais-search-box--powered-by
a.ais-search-box--powered-by-link
span.ais-search-box--magnifier-wrapper
div.ais-search-box--magnifier
span.ais-search-box--reset-wrapper
Rather than mess with all that, let’s see what comes out of the box in Algolia stylesheets – I’ll throw a couple of LINK
tags importing InstantSearch CSS libraries after my SCRIPT
tags importing the InstantSearch & Moment.js JavaScript libraries.
...
<!-- Import moment for date parsing -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
<!-- Import some InstantSearch styling -->
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/instantsearch.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/instantsearch-theme-algolia.min.css">
<!-- Make InstantSearch put widgets in the DOM -->
...
That looks much better – the magnifying glass is now inside the search box to the left of “Search this site…” and “Search by Algolia” floats to the bottom right of the search box.
But … do I really like this CSS library? Will it play nicely with Tailwind?
Let’s find out.
...
<head>
<title>Algolia index experiment</title>
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
</head>
<body>
<p>Hello, world</p>
<div class="w-10 bg-red-500">x</div>
<div id="search-searchbar" class="w-16 h-8"></div>
<p>Well, that was neat</p>
<!-- Start end-of-page scripts -->
<!-- Import the basic InstantSearch library -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/instantsearch.min.js"></script>
<!-- Import moment for date parsing -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
<!-- Import some InstantSearch styling -->
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/instantsearch.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/instantsearch-theme-algolia.min.css">
<!-- Make InstantSearch put widgets in the DOM -->
...
When I refreshed this in my browser, I saw the following lines of content:
- “Hello, world”
- “x” in a red box that’s
2.5rem
wide. - A “search this site…” box starting with a magnifying glass that clips its inner hint-text content to make sure that it doesn’t exceed
4rem
wide. However, it is definitely overflowing its2rem
height limit. - “Search by Algolia” that is trying to be right-aligned to the search box, but the search box is so narrow that it looks left-aligned on the page, and then it overflows the
4rem
limit. - “Well, that was neat” starting right below the
2rem
height limit of the element before it, but partially obscured by the searchbox and by “Search by Algolia”.
Adding overflow-hidden
to the div#search-searchbar
classes clips out the bottom of the searchbox and the “Search by algolia” text altogether, but that’s not quite right.
My conclusion? The searchbox widget’s default styling doesn’t interfere too badly with anything else I might want to do with my theme, as long as I give its container enough height that nothing looks wonky. I’ll just make sure it gets the space it wants. I’m not going to bother to write custom CSS.
V2 to V4 upgrade
It looks like the tutorial I started from was using out-of-date Algolia imports, so I’m going to take a moment to update the imports w/ the modern CDN scripts:
<!-- Import the basic InstantSearch libraries -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/algoliasearch-lite.umd.js" integrity="sha256-EXPXz4W6pQgfYY3yTpnDa3OH8/EPn16ciVsPQ/ypsjk=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/instantsearch.production.min.js" integrity="sha256-LAGhRRdtVoD6RLo2qDQsU2mp+XVSciKRC8XPOBWmofM=" crossorigin="anonymous"></script>
That requires changing my custom JavaScript a bit to match the new library’s coding standards, as well as breaking out my DIV
s that need DOM injection into separate search-searchbar
and search-poweredby
IDs.
...
<p>Hello, world</p>
<div id="search-searchbar"></div>
<div id="search-poweredby"></div>
<p>Well, that was neat</p>
<!-- Start end-of-page scripts -->
...
<!-- Make InstantSearch put widgets in the DOM -->
<script>
// --- Prep InstantSearch ---
const searchClient = algoliasearch(
"MY_APP_ID",
"MY_SEARCH_ONLY_API_KEY"
);
const search = instantsearch({
indexName: "MY_INDEX_NAME",
searchClient,
});
// --- Define some custom helpers ---
// TO DO
// --- Add all widgets ---
search.addWidgets([
// --- Define the "searchbar" as using the "searchBox" widget
instantsearch.widgets.searchBox({
container: "#search-searchbar",
placeholder: "Search this site...",
poweredBy: true, // This is required if you're on the free Community plan
autofocus: false,
}),
]);
// --- Throw InstantSearch into the DOM ---
search.start();
</script>
<!-- End end-of-page scripts -->
...
Here’s the DOM that gets injected from version 4 of InstantSearch (I’d been on version 2):
<div id="search-searchbar" class="w-16 h-24">
<div class="ais-SearchBox">
<form action="" role="search" class="ais-SearchBox-form" novalidate="">
<input
class="ais-SearchBox-input"
type="search"
placeholder="Search this site..."
autocomplete="off"
autocorrect="off"
autocapitalize="none"
spellcheck="false"
maxlength="512"
/><button
class="ais-SearchBox-submit"
type="submit"
title="Submit the search query."
>
<svg
class="ais-SearchBox-submitIcon"
xmlns="http://www.w3.org/2000/svg"
width="10"
height="10"
viewBox="0 0 40 40"
>
<path
d="M26.804 29.01c-2.832 2.34-6.465 3.746-10.426 3.746C7.333 32.756 0 25.424 0 16.378 0 7.333 7.333 0 16.378 0c9.046 0 16.378 7.333 16.378 16.378 0 3.96-1.406 7.594-3.746 10.426l10.534 10.534c.607.607.61 1.59-.004 2.202-.61.61-1.597.61-2.202.004L26.804 29.01zm-10.426.627c7.323 0 13.26-5.936 13.26-13.26 0-7.32-5.937-13.257-13.26-13.257C9.056 3.12 3.12 9.056 3.12 16.378c0 7.323 5.936 13.26 13.258 13.26z"
></path>
</svg></button
><button
class="ais-SearchBox-reset"
type="reset"
title="Clear the search query."
hidden=""
>
<svg
class="ais-SearchBox-resetIcon"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
width="10"
height="10"
>
<path
d="M8.114 10L.944 2.83 0 1.885 1.886 0l.943.943L10 8.113l7.17-7.17.944-.943L20 1.886l-.943.943-7.17 7.17 7.17 7.17.943.944L18.114 20l-.943-.943-7.17-7.17-7.17 7.17-.944.943L0 18.114l.943-.943L8.113 10z"
></path>
</svg></button
><span class="ais-SearchBox-loadingIndicator" hidden=""
><svg
class="ais-SearchBox-loadingIcon"
width="16"
height="16"
viewBox="0 0 38 38"
xmlns="http://www.w3.org/2000/svg"
stroke="#444"
>
<g fill="none" fillrule="evenodd">
<g transform="translate(1 1)" strokewidth="2">
<circle strokeopacity=".5" cx="18" cy="18" r="18"></circle>
<path d="M36 18c0-9.94-8.06-18-18-18">
<animateTransform
attributeName="transform"
type="rotate"
from="0 18 18"
to="360 18 18"
dur="1s"
repeatCount="indefinite"
></animateTransform>
</path>
</g>
</g></svg
></span>
</form>
</div>
</div>
<div id="search-poweredby" class="w-6 h-2">
<div class="ais-PoweredBy ais-PoweredBy--light">
<a
href="https://www.algolia.com/?utm_source=instantsearch.js&utm_medium=website&utm_content=&utm_campaign=poweredby"
target="_blank"
class="ais-PoweredBy-link"
aria-label="Search by Algolia"
rel="noopener noreferrer"
><svg
height="1.2em"
class="ais-PoweredBy-logo"
viewBox="0 0 168 24"
style="width: auto"
>
<path
fill="#5D6494"
d="M6.97 6.68V8.3a4.47 4.47 0 0 0-2.42-.67 2.2 2.2 0 0 0-1.38.4c-.34.26-.5.6-.5 1.02 0 .43.16.77.49 1.03.33.25.83.53 1.51.83a7.04 7.04 0 0 1 1.9 1.08c.34.24.58.54.73.89.15.34.23.74.23 1.18 0 .95-.33 1.7-1 2.24a4 4 0 0 1-2.6.81 5.71 5.71 0 0 1-2.94-.68v-1.71c.84.63 1.81.94 2.92.94.58 0 1.05-.14 1.39-.4.34-.28.5-.65.5-1.13 0-.29-.1-.55-.3-.8a2.2 2.2 0 0 0-.65-.53 23.03 23.03 0 0 0-1.64-.78 13.67 13.67 0 0 1-1.11-.64c-.12-.1-.28-.22-.46-.4a1.72 1.72 0 0 1-.39-.5 4.46 4.46 0 0 1-.22-.6c-.07-.23-.1-.48-.1-.75 0-.91.33-1.63 1-2.17a4 4 0 0 1 2.57-.8c.97 0 1.8.18 2.47.52zm7.47 5.7v-.3a2.26 2.26 0 0 0-.5-1.44c-.3-.35-.74-.53-1.32-.53-.53 0-.99.2-1.37.58-.38.39-.62.95-.72 1.68h3.91zm1 2.79v1.4c-.6.34-1.38.51-2.36.51a4.02 4.02 0 0 1-3-1.13 4.04 4.04 0 0 1-1.11-2.97c0-1.3.34-2.32 1.02-3.06a3.38 3.38 0 0 1 2.6-1.1c1.03 0 1.85.32 2.46.96.6.64.9 1.57.9 2.78 0 .33-.03.68-.09 1.04h-5.31c.1.7.4 1.24.89 1.61.49.38 1.1.56 1.85.56.86 0 1.58-.2 2.15-.6zm6.61-1.78h-1.21c-.6 0-1.05.12-1.35.36-.3.23-.46.53-.46.89 0 .37.12.66.36.88.23.2.57.32 1.02.32.5 0 .9-.15 1.2-.43.3-.28.44-.65.44-1.1v-.92zm-4.07-2.55V9.33a4.96 4.96 0 0 1 2.5-.55c2.1 0 3.17 1.03 3.17 3.08V17H22.1v-.96c-.42.68-1.15 1.02-2.19 1.02-.76 0-1.38-.22-1.84-.66-.46-.44-.7-1-.7-1.68 0-.78.3-1.38.88-1.81.59-.43 1.4-.65 2.46-.65h1.34v-.46c0-.55-.13-.97-.4-1.25-.26-.29-.7-.43-1.32-.43-.86 0-1.65.24-2.35.72zm9.34-1.93v1.42c.39-1 1.1-1.5 2.12-1.5.15 0 .31.02.5.05v1.53c-.23-.1-.48-.14-.76-.14-.54 0-.99.24-1.34.71a2.8 2.8 0 0 0-.52 1.71V17h-1.57V8.91h1.57zm5 4.09a3 3 0 0 0 .76 2.01c.47.53 1.14.8 2 .8.64 0 1.24-.18 1.8-.53v1.4c-.53.32-1.2.48-2 .48a3.98 3.98 0 0 1-4.17-4.18c0-1.16.38-2.15 1.14-2.98a4 4 0 0 1 3.1-1.23c.7 0 1.34.15 1.92.44v1.44a3.24 3.24 0 0 0-1.77-.5A2.65 2.65 0 0 0 32.33 13zm7.92-7.28v4.58c.46-1 1.3-1.5 2.5-1.5.8 0 1.42.24 1.9.73.48.5.72 1.17.72 2.05V17H43.8v-5.1c0-.56-.14-.99-.43-1.29-.28-.3-.65-.45-1.1-.45-.54 0-1 .2-1.42.6-.4.4-.61 1.02-.61 1.85V17h-1.56V5.72h1.56zM55.2 15.74c.6 0 1.1-.25 1.5-.76.4-.5.6-1.16.6-1.95 0-.92-.2-1.62-.6-2.12-.4-.5-.92-.74-1.55-.74-.56 0-1.05.22-1.5.67-.44.45-.66 1.13-.66 2.06 0 .96.22 1.67.64 2.14.43.47.95.7 1.57.7zM53 5.72v4.42a2.74 2.74 0 0 1 2.43-1.34c1.03 0 1.86.38 2.51 1.15.65.76.97 1.78.97 3.05 0 1.13-.3 2.1-.92 2.9-.62.81-1.47 1.21-2.54 1.21s-1.9-.45-2.46-1.34V17h-1.58V5.72H53zm9.9 11.1l-3.22-7.9h1.74l1 2.62 1.26 3.42c.1-.32.48-1.46 1.15-3.42l.91-2.63h1.66l-2.92 7.87c-.78 2.07-1.96 3.1-3.56 3.1-.28 0-.53-.02-.73-.07v-1.34c.17.04.35.06.54.06 1.03 0 1.76-.57 2.17-1.7z"
></path>
<path
fill="#5468FF"
d="M78.99.94h16.6a2.97 2.97 0 0 1 2.96 2.96v16.6a2.97 2.97 0 0 1-2.97 2.96h-16.6a2.97 2.97 0 0 1-2.96-2.96V3.9A2.96 2.96 0 0 1 79 .94"
></path>
<path
fill="#FFF"
d="M89.63 5.97v-.78a.98.98 0 0 0-.98-.97h-2.28a.98.98 0 0 0-.97.97V6c0 .09.08.15.17.13a7.13 7.13 0 0 1 3.9-.02c.08.02.16-.04.16-.13m-6.25 1L83 6.6a.98.98 0 0 0-1.38 0l-.46.46a.97.97 0 0 0 0 1.38l.38.39c.06.06.15.04.2-.02a7.49 7.49 0 0 1 1.63-1.62c.07-.04.08-.14.02-.2m4.16 2.45v3.34c0 .1.1.17.2.12l2.97-1.54c.06-.03.08-.12.05-.18a3.7 3.7 0 0 0-3.08-1.87c-.07 0-.14.06-.14.13m0 8.05a4.49 4.49 0 1 1 0-8.98 4.49 4.49 0 0 1 0 8.98m0-10.85a6.37 6.37 0 1 0 0 12.74 6.37 6.37 0 0 0 0-12.74"
></path>
<path
fill="#5468FF"
d="M120.92 18.8c-4.38.02-4.38-3.54-4.38-4.1V1.36l2.67-.42v13.25c0 .32 0 2.36 1.71 2.37v2.24zm-10.84-2.18c.82 0 1.43-.04 1.85-.12v-2.72a5.48 5.48 0 0 0-1.57-.2c-.3 0-.6.02-.9.07-.3.04-.57.12-.81.24-.24.11-.44.28-.58.49a.93.93 0 0 0-.22.65c0 .63.22 1 .61 1.23.4.24.94.36 1.62.36zm-.23-9.7c.88 0 1.62.11 2.23.33.6.22 1.09.53 1.44.92.36.4.61.92.76 1.48.16.56.23 1.17.23 1.85v6.87c-.4.1-1.03.2-1.86.32-.84.12-1.78.18-2.82.18-.69 0-1.32-.07-1.9-.2a4 4 0 0 1-1.46-.63c-.4-.3-.72-.67-.96-1.13a4.3 4.3 0 0 1-.34-1.8c0-.66.13-1.08.39-1.53.26-.45.6-.82 1.04-1.1.45-.3.95-.5 1.54-.62a8.8 8.8 0 0 1 3.79.05v-.44c0-.3-.04-.6-.11-.87a1.78 1.78 0 0 0-1.1-1.22c-.31-.12-.7-.2-1.15-.2a9.75 9.75 0 0 0-2.95.46l-.33-2.19c.34-.12.84-.23 1.48-.35.65-.12 1.34-.18 2.08-.18zm52.84 9.63c.82 0 1.43-.05 1.85-.13V13.7a5.42 5.42 0 0 0-1.57-.2c-.3 0-.6.02-.9.07-.3.04-.57.12-.81.24-.24.12-.44.28-.58.5a.93.93 0 0 0-.22.65c0 .63.22.99.61 1.23.4.24.94.36 1.62.36zm-.23-9.7c.88 0 1.63.11 2.23.33.6.22 1.1.53 1.45.92.35.39.6.92.76 1.48.15.56.23 1.18.23 1.85v6.88c-.41.08-1.03.19-1.87.31-.83.12-1.77.18-2.81.18-.7 0-1.33-.06-1.9-.2a4 4 0 0 1-1.47-.63c-.4-.3-.72-.67-.95-1.13a4.3 4.3 0 0 1-.34-1.8c0-.66.13-1.08.38-1.53.26-.45.61-.82 1.05-1.1.44-.3.95-.5 1.53-.62a8.8 8.8 0 0 1 3.8.05v-.43c0-.31-.04-.6-.12-.88-.07-.28-.2-.52-.38-.73a1.78 1.78 0 0 0-.73-.5c-.3-.1-.68-.2-1.14-.2a9.85 9.85 0 0 0-2.95.47l-.32-2.19a11.63 11.63 0 0 1 3.55-.53zm-8.03-1.27a1.62 1.62 0 0 0 0-3.24 1.62 1.62 0 1 0 0 3.24zm1.35 13.22h-2.7V7.27l2.7-.42V18.8zm-4.72 0c-4.38.02-4.38-3.54-4.38-4.1l-.01-13.34 2.67-.42v13.25c0 .32 0 2.36 1.72 2.37v2.24zm-8.7-5.9a4.7 4.7 0 0 0-.74-2.79 2.4 2.4 0 0 0-2.07-1 2.4 2.4 0 0 0-2.06 1 4.7 4.7 0 0 0-.74 2.8c0 1.16.25 1.94.74 2.62a2.4 2.4 0 0 0 2.07 1.02c.88 0 1.57-.34 2.07-1.02.49-.68.73-1.46.73-2.63zm2.74 0a6.46 6.46 0 0 1-1.52 4.23c-.49.53-1.07.94-1.76 1.22-.68.29-1.73.45-2.26.45-.53 0-1.58-.15-2.25-.45a5.1 5.1 0 0 1-2.88-3.13 7.3 7.3 0 0 1-.01-4.84 5.13 5.13 0 0 1 2.9-3.1 5.67 5.67 0 0 1 2.22-.42c.81 0 1.56.14 2.24.42.69.29 1.28.69 1.75 1.22.49.52.87 1.15 1.14 1.89a7 7 0 0 1 .43 2.5zm-20.14 0c0 1.11.25 2.36.74 2.88.5.52 1.13.78 1.91.78a4.07 4.07 0 0 0 2.12-.6V9.33c-.19-.04-.99-.2-1.76-.23a2.67 2.67 0 0 0-2.23 1 4.73 4.73 0 0 0-.78 2.8zm7.44 5.27c0 1.82-.46 3.16-1.4 4-.94.85-2.37 1.27-4.3 1.27-.7 0-2.17-.13-3.34-.4l.43-2.11c.98.2 2.27.26 2.95.26 1.08 0 1.84-.22 2.3-.66.46-.43.68-1.08.68-1.94v-.44a5.2 5.2 0 0 1-2.54.6 5.6 5.6 0 0 1-2.01-.36 4.2 4.2 0 0 1-2.58-2.71 9.88 9.88 0 0 1 .02-5.35 4.92 4.92 0 0 1 2.93-2.96 6.6 6.6 0 0 1 2.43-.46 19.64 19.64 0 0 1 4.43.66v10.6z"
></path></svg
></a>
</div>
</div>
As before:
- Unstyled code looks ugly (although not nearly as ugly as w/ v2).
- Algolia-delivered stylesheets for “searchbox” & “poweredby” widgets try to overflow height restrictions.
- “searchbox” Algolia-delivered stylesheets fit width into width restrictions.
- “poweredby” Algolia-delivered stylesheets try to overflow width restrcitions.
- Since “search by” is no longer incorporated into the searchbox, it no longer tries to right-align itself to anything.
URL query parameter handling
I want to be able to include a search box with very little client-side JavaScript in every page of my site, and then let the Submit action take people to /search?q=THEIR_SEARCH_WORDS
.
There’s a shortcut for this: I Just had to add routing: true
to my instantsearch()
initalization code:
const search = instantsearch({
indexName: "MY_INDEX_NAME",
searchClient,
routing: true,
});
I navigated my browser to file:///C:/example/algoliaindex.html?MY_INDEX_NAME%5Bquery%5D=world
and observed my request come in at https://algolia.com/apps/MY_APP_ID/monitoring/logs
with a Request body whose params included the phrase query=world
. Furthermore, world
shows up prepopulated in the search box rather than the placeholder text. Neat.
For the longest time, I thought that Algolia’s docs were trying to tell me that after the ?
it would need to be instant_search[query]=world
, and that wasn’t doing anything for me even after I added routing: true
, but it turns out that their particular sample index name was instant_search
– that wasn’t a magic keyword for the Instant Search library.
What I needed to do, to get URL parameters working with routing: true
on, was put my own index name into the URL.
I find it awkward to use the name of my Algolia index in URL parameters (I chose a weird name), so I want to keep working through the instructions about customizing URL parameter handling.
I tried this per the Routing URLs docs, but not only did ?instant_search[query]=world
stop working, ?q=world
didn’t work yet, either.
...
// --- Prep InstantSearch ---
const searchClient = algoliasearch(
"MY_APP_ID",
"MY_SEARCH_ONLY_API_KEY"
);
const indexName = 'MY_INDEX_NAME';
const search = instantsearch({
indexName,
searchClient,
routing: {
stateMapping: {
stateToRoute(uiState) {
const indexUiState = uiState[indexName];
return {
q: indexUiState.query,
}
},
routeToState(routeState) {
return {
[indexName]: {
q: routeState.q,
}
}
},
},
},
});
// --- Define some custom helpers ---
// TO DO
...
I searched the internet for statetoroute routetostate
and found a CodeSandbox called “InstantSearch.js - URLSync without page - CodeSandbox” that got things working, although the query parameter is query
, not q
, and the world query
doesn’t show up at all in the codebase, so that’s interesting.
Here’s what my custom scripting looks like now:
...
// --- Prep InstantSearch ---
const searchClient = algoliasearch(
"MY_APP_ID",
"MY_SEARCH_ONLY_API_KEY"
);
const indexName = "MY_INDEX_NAME";
const singleIndexStateMapping = instantsearch.stateMappings.singleIndex(indexName);
const withoutPageStateMapping = {
stateToRoute(uiState) {
const { page, ...state } = singleIndexStateMapping.stateToRoute(uiState);
return state;
},
routeToState(routeState) {
const { [indexName]: indexUiState } = singleIndexStateMapping.routeToState(routeState);
const { page, ...state } = indexUiState;
return { [indexName]: state, };
},
};
const search = instantsearch({
indexName,
searchClient,
routing: { stateMapping: withoutPageStateMapping },
});
// --- Define some custom helpers ---
// TO DO
// --- Add all widgets ---
search.addWidgets([
// --- Define the "searchbar" as using the "searchBox" widget
instantsearch.widgets.searchBox({
container: "#search-searchbar",
placeholder: "Search this site...",
poweredBy: true, // This is required if you're on the free Community plan
autofocus: false,
}),
instantsearch.widgets.poweredBy({
container: "#search-poweredby",
}),
]);
// --- Throw InstantSearch into the DOM ---
search.start();
...
I don’t read JavaScript well enough to have the slightest clue why it works, but I’m happy it does.
Adding a search bar to every page
Additional resources
- https://blog.floriancourgey.com/2018/11/migrate-from-wordpress-to-jekyll-2