DEV Community

Funmilayo E. Olaiya
Funmilayo E. Olaiya

Posted on • Edited on

Mini contact cards - using Algolia as the search service and setting the web app up as a PWA

Hello everyone,

This tutorial will be about getting few details from a JSON object as mini contact cards using the front-end technology(react) and a search engine(algolia). The app will be hosted on netlify.

A quick note:

Algolia is a powerful search-service because the set up is quite easy, powerful, produces excellent search results and allows users to have a wonderful search experience.


Let's get started:

-Make sure Node.js installed on your computer

  • Set up react using this command - npx create-react-app . not npx create-react-app my-app because the later command will install a folder into the folder you already specified and we want the folder structure to look like this:

Alt Text
Read more:- https://create-react-app.dev/docs/getting-started/

In the App.js file, refactor the code to the following code:

import React, { Component} from 'react';
import './App.css';

class App extends Component {

    render(){
    return (
      <div className="App">
          <p>Random contact card</p>
    </div>
    );
    }
  }

  export default App;

Enter fullscreen mode Exit fullscreen mode

We only need to render the title of the app for now.

Add this to the App.css file:

p {
    font-size: 50px;
    color: rgb(164, 193, 188);
    text-align: center
  }

Enter fullscreen mode Exit fullscreen mode

In the index.css file, refactor the code to the following code:

body {
  margin: 0;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

Enter fullscreen mode Exit fullscreen mode

An account needs to be created on algolia and once that is created, you will be redirected to a dashboard.

Create an index titled -, for example: search-details.

Under add records to search, there are three options, add records manually, use the API or upload file.

We will be uploading the records manually since they are just ten users we are trying to search for.

Paste this JSON URL in your browser to get the full data: http://jsonplaceholder.typicode.com/users

After the full data have been copied, paste it to the algolia console and click save.

Click on searchable attributes and add the attributes to be used in searching.
Tip: you can add name and email since that is what will only be searched for.
Review and save settings.

Create a folder called components and create another folder called search, in it, create two files called - search.component.jsx and search.style.css in the search folder.

Install these packages:
npm install aloglia search react-instantsearch-dom -S - to integrate the Javascript API client and for helping to search the react-dom.

Add this following code to the search.component.jsx file:

import React from 'react';
import algoliasearch from 'algoliasearch/lite';
import { InstantSearch, SearchBox} from 'react-instantsearch-dom';
import {Content} from '../content/content.component';
import './search.style.css';

const searchClient = algoliasearch(
  '_APP ID_',
  '_Search-Only API Key_'
);
export const Search = () => (
  <InstantSearch searchClient={searchClient} indexName="search-details">
         <SearchBox 
            className='search' 
            />
     <Content 
     />    
  </InstantSearch>
);

Enter fullscreen mode Exit fullscreen mode

algolisearch app id and key are assigned to a constant whereby a function is declared to use the instantsearch component, retrieve the searchClient and index of the records.
The searchBox is a widget used to let the user perform a text-based query - will be used for searching through the records.

Add this code to the search.style.css:

input[type='search'] {
    justify-content: center;
    padding: 10px 30px;
    width: 40%;
    border: 1px solid black;
    margin-left: 30%;
  }

button.ais-SearchBox-submit {
      display: none;
  }

button.ais-SearchBox-reset{
  display: none;
}  

Enter fullscreen mode Exit fullscreen mode

Back to the components folder:

Create a folder called content, in it, create two files called: content.component.jsx and content.style.css.

Add the following code to the content.component.jsx file:

import React from 'react';
import { Hits } from 'react-instantsearch-dom';
import { Hit } from '../hit/hit.component';
import './content.style.css';

export const Content =() => (
<div className = 'content'>
    <Hits hitComponent={Hit} />
    </div>
);
Enter fullscreen mode Exit fullscreen mode

This code merely houses the imported hit component.

Add this code to the content.style.css file:

ul {
  list-style-type: none;
  width: 60%;
  margin: 0 auto;
  margin-top: 5%;
  }

  li {
  margin: 1em 0;
  }  


  @media screen and (max-width: 600px) {
    ul {
      width: 70%;
      margin-left: 5%;
    }
}
Enter fullscreen mode Exit fullscreen mode

Back to the components folder:
Create a folder called hit, in it, create two files called: hit.component.jsx and hit.style.css.

Add the following code to the hit.component.jsx file:

import React from 'react';
import './hit.style.css';

export const Hit = ({ hit }) => (
    <div className="hit">
        <div className="title">{hit.name}</div>
        <div className="details">Email: {hit.email}</div>
       <div className="details">Website: {hit.website}</div>
      </div>

);

Enter fullscreen mode Exit fullscreen mode

In this code - hits is used to display the name and email results that will be searched for.

Add the following code to the hit.style.css file:

@import url('https://fonts.googleapis.com/css?family=Quicksand&display=swap');

body{
    font-family: 'Quicksand', sans-serif;
    width: 100%;
    margin: 0;
}

.hit {
    background-color: rgb(216, 229, 227);
    border-radius: 5px;
}

  .title {
    color: grey;
    font-size: 20px;
    line-height: 3;
    text-align: center;
  }

  .details {
      color: grey;
      font-size: 10px;
      text-align: center;
  }

Enter fullscreen mode Exit fullscreen mode

The App.js file should be updated using this code:

import React, { Component} from 'react';
import './App.css';
import {Search} from './../src/components/search/search.component';

class App extends Component {

    render(){
    return (
      <div className="App">
          <p>Random contact card</p>
          <Search />
    </div>
    );
    }
  }


  export default App;
Enter fullscreen mode Exit fullscreen mode

The search component is imported and rendered.

Read more about the components- here


Now it's time to set it up as a PWA:

In the Public folder, in the manifest.json file, change the short name and name to random-contact-card.

Create a worker.js file in the public folder and add this code:

const CACHE_NAME = 'random-contact-card-cache';
const urlsToCache = ['/'];

// Install a service worker
self.addEventListener('install', event => {
  // Perform install steps
  event.waitUntil(
    caches.open(CACHE_NAME).then(cache => cache.addAll(urlsToCache))
  );
});

// Cache and return requests
self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request).then(response => {
      // Cache hit - return response
      if (response) {
        return response;
      }
      return fetch(event.request);
    })
  );
});

// Update a service worker
self.addEventListener('activate', event => {
  const cacheWhitelist = ['random-contact-card-cache'];
  event.waitUntil(
    caches.keys().then(cacheNames =>
      Promise.all(
        cacheNames.map(cacheName => {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      )
    )
  );
});
Enter fullscreen mode Exit fullscreen mode

Update the index.html file in the public folder:

Add the javascript code to the body to check if the browser supports service workers.

<script>
      if ('serviceWorker' in navigator) {
        window.addEventListener('load', function () {
          navigator.serviceWorker.register('worker.js').then(function (registration) {
            console.log('Worker registration successful', registration.scope);
          }, function (err) {
            console.log('Worker registration failed', err);
          }).catch(function (err) {
            console.log(err);
          });
        });
      } else {
        console.log('Service Worker is not supported by browser.');
      }
    </script>
Enter fullscreen mode Exit fullscreen mode

Add this code to the head of the index.html:

<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> - the react logo is used for this app.

Now, update the index.js from serviceWorker.unregister() to serviceWorker.register()


It is all set up. yay.

It is time to run an audit on how far we have gone.

Go to your browser console(I assume your project is running on the localhost already). Click on audits, then generate a report.

If it is giving an error, relax, it happens when it is the first time.


Let us host it on netlify, which is the simplest ever.

Firstly, push your code to GitHub, then
Create an account on netlify -> sign in/up with git -> choose the project you wish to deploy -> the command should be npm run build and the directory should be build/.

When the project is live, try to generate report again. it is best to be done in incognito mode

See it in action - codesandbox
For the code - github

Thanks, for reading!

Top comments (0)