Cabin — React & Redux Example App — Algolia

cabin_algolia_post

This is the 7th post in our 8 part tutorial series created by GetStream.io. The final result is your own feature-rich, scalable social network app built with React and Redux! Visit cabin.getstream.io for an overview of all 8 tutorials and a live demo. The full source code is available on GitHub.

Introduction

Have you ever wanted lightning fast search results in your application? How about lightning fast searches that provide relevant results?

You’re in luck! This is exactly what Algolia allows you to do. With Algolia, you can build unique search experiences for your application in a fraction of the time that it would normally take — we’re talking about saving hours, days or possibly weeks. Best of all, it’s hosted and delivers nearly instant results that can be fine-tuned to your exact needs.

There’s a reason why we chose to use it to build Cabin, as did other giants, such as Product Hunt, CrunchBase, DigitalOcean, Medium, and Hacker News (just to name a few).

Overview

Here is what you will be learning in this post of the series:

Getting Started

Server Side

Client Side

Typo Tolerance

Geo-Based Search

Weekly Usage Report

Dashboard

Stay updated to upcoming posts in this React & Redux series:

Getting Started

Step 1: Install & Clone Example App

Getting up and running with Cabin is a breeze.

Follow the step below to clone the repo (if you haven’t already):

git clone git@github.com:GetStream/stream-react-example.git

Note: If you have not already completed the introductory tutorial, now is a great time to do so as we outline the application structure and initial setup required.

Step 2: Create Algolia Account

Creating an account with Algolia is easy as pie. And pie is easy. Pi is harder.

Simply head over to their website and create a FREE account.

and create a FREE account. You’ll have an unlimited 14 day trial, but not to worry, you can always use their Hacker plan if you stay below 10,000 records and 100,000 operations per month.

Step 3: Gather API Credentials

Once you’ve completed your account creation, we’ll need to gather your API credentials from the dashboard.

On the left hand side of your dashboard, click on “API Keys”.

Screen Shot 2016-06-10 at 2.09.16 PM

Both the client facing application and server side API will use the same credentials.

Fill in your API credentials in /env.sh and source the file appropriately:

vim ./env.sh

export ALGOLIA_APP_ID=VALUE
export ALGOLIA_SEARCH_ONLY_KEY=VALUE
export ALGOLIA_API_KEY=VALUE

source ./env.sh

Step 4. Install the API Client

As previously mentioned, both our API and app will be using the same credentials. That said, we’ll need to install the API client in both places as well.

In our case, we’ll install it via NPM:

cd /app && npm install algoliasearch --save

cd ../api && npm install algoliasearch --save

Algolia also provides easy to use integrations via bower, and via CDN.

Step 5: Create an Index

Similar to our API credentials, there’s a button labeled “Indices” that you’ll need to click. Once on the indices dashboard, click “Add New” and create a new index with the name “cabin”.

Screen Shot 2016-06-10 at 2.53.42 PM

Jumping into the Server Side Code

Now that we’re signed up for Algolia and have the necessary dependencies installed, it’s time to take a look at our implementation for Cabin.

To begin, let’s have a look at the server side API where the heavy lifting happens behind the scenes.

Let’s head over to /api/routes/uploads.js and take a look at around line 322:

var algolia = algoliaSearch(config.algolia.appId, config.algolia.apiKey);

var index = algolia.initIndex('cabin');

index.addObject(result);

As you can see, the code is extremely straightforward.

First, we initialize the Algolia client using our appId and apiKey.

Second, we initialize our newly created index, cabin, and assign it to a variable named index.

Lastly, we call addObject and pass in our object for indexing.

Note: If you have a look at the code above line ~322, you’ll notice that there is a series of waterfall function calls being made using the popular Node.js library, Async. The several layers of waterfall provide us with an object at the end (the object used for indexing), which is structured as:

{
"id": 1,
"email": "foo@bar.com",
"fb_uid": "1213861088933558",
"first_name": "Foo",
"last_name": "Bar"
}

Behind the scenes, we’re able to look at the incoming response (for debugging purposes) and see exactly what was passed to Algolia:

Screen Shot 2016-06-10 at 3.03.48 PM

Note: To get to API Call Details, click on Indices on the left sidebar, then click on Logs. From there, you can choose any of the latest operations.

For brevity, we’re only going to cover the POST /uploads endpoint; however, Algolia is used throughout the API and can be found in /api/routes/users.js.

Client Side Implementation

Next up, let’s have a look at the front-end code within our /app.

Head over to /app/modules/actions.

This directory contains all our Redux actions, which you can read about on our previous blog post found here.

The primary logic for our client side search can be found inside of Search.js in our actions directory.

Because we’re using ES6 on the client, we can use the import statement to pull in the algoliasearch NPM library:

import algoliasearch from 'algoliasearch'
import config from 'config'

const algolia = algoliasearch(config.algolia.appId, config.algolia.searchOnlyKey)

Let’s move down to around line 40, and look at where we call our dispatch event:

return dispatch => {

// initialize the 'cabin' index:
let index = algolia.initIndex('cabin'),
attrs = []

switch(type) {
case 'all':
attrs.push(
'first_name',
'last_name',
'location',
'hashtags',
)
break;
case 'hashtags':
attrs.push('hashtags')
break
case 'user':
attrs.push(
'first_name',
'last_name',
)
break
case 'location':
attrs.push('location')
break
}

// perform algolia search:
index.search(term, {
attributesToHighlight: attrs,
hitsPerPage: 100
}, (err, content) => {
dispatch(_searchResponse(term, content))
})
}

Breaking this down a bit — here we are searching our “cabin” index for a term with two options:

  • attributesToHighlight
  • hitsPerPage

attributesToHighlight is based on one of four search modes we have created: all, hashtags, user, and location.

Depending on our case, we use a switch statement to send an object of the appropriate object attributes to search upon. Highlighting search terms in results is an important part of creating a great search UX. It’s important for users to know why their search returned the results that it did. Algolia does result highlighting by default, but for Cabin we need to specify the attributes we want highlighted because they differ based on the type of search.

hitsPerPage is straightforward — and in this case, we are returning 100 results.

As far as implementation goes, that’s all it takes to have a fast and accurate search in your application!

More Awesome Options & Functionality

Algolia is feature packed with useful tools for any application. Here are a few highlights:

Typo Tolerance

Yes, Algolia deals with typos for you with the following options:

minWordSizeFor1Typo
 minWordSizeFor2Typos
 typoTolerance
 allowTyposOnNumericTokens

Geo-Based Search

Bounding Box Searches? Polygon Searches? Search location around an IP address? It’s all available right here.

Weekly Usage Report

Algolia even sends a slick usage report every week via email:

Screen Shot 2016-06-13 at 9.05.56 AM

Powerful Dashboard For Debugging

On top of an amazing API and set of SDKs, Algolia outperforms competitors with their amazing dashboard.

Screen Shot 2016-06-10 at 2.47.52 PM

Hungry For More?

You’re in luck. Algolia maintains an amazing blog called “Milliseconds Matter” where they outline best practices, use-cases, etc. It’s definitely worth checking out. You can get to it by clicking here. Algolia also has a community site where they showcase open source projects and tools.”

Conclusion

Algolia is perfect for apps like Cabin. It’s fast, accurate, and easy to implement. In the next post we’ll cover how we’re using Mapbox to power the maps and geolocation for Cabin. Add your email on cabin.getstream.io or follow @getstream_io on Twitter to stay up to date about the latest Cabin tutorials.

This tutorial series is created by getstream.io. Try the 5 min interactive tutorial to learn how Stream works.


Originally published at The Stream Blog.