Insights

Set Up Coveo Headless's Engine Context for Next JS

An Alternative Approach That Works With Sitecore JSS

What Is The Headless Engine?

Think of the Headless Engine as the engine of any care. Without it working, you're going nowhere fast. It takes care of and organizes the use of the API token, Organization ID and so forth.

So, when it comes to setting up an Engine for our Sitecore JSS Next.JS application any time we create a component such as a navigation menu search bar, we need an engine and its corresponding context to support all of the Coveo components that are used as part of it.

For the purposes of this article, we're going to use the example of a navigation menu search box as our Sitecore component.

Let's Set Up The Component

The whole Next.JS component itself is relatively simple. As part of this project setup, we have installed @coveo/headless.


import { Field } from '@sitecore-jss/sitecore-jss-nextjs';
import { buildSearchEngine } from '@coveo/headless';
type EngineProps = {
    organizationId: Field<string>;
    searchHub: Field<string>;
    accessToken: Field<string>;
  };
export async function initializeHeadlessEngine(props: EngineProps) {
    return buildSearchEngine({
        configuration: {
        platformUrl: 'https://platform.cloud.coveo.com',
        organizationId: props.organizationId.value,
        accessToken: props.accessToken.value,
        },
    });
}

I will point out that in the above example a few things are known and as such, a few shortcuts were taken.

  • The API key being used has minimal privileges (i.e. search only),
  • A Search Hub is assigned to the API key to restrict which Query Pipeline is used and thus restrict its access further,
  • All content retrieved is already public information.

Set Up The Headless Engine Context

With the engine in place, we need a way to generate the context from which all other Coveo components will grab the engine context.


import { createContext } from 'react';

const HeadlessEngineContext = createContext< /> | undefined>(undefined);
export default HeadlessEngineContext;

Set Up The Menu Search Bar Component

With the Engine component in place, we can now set up the primary component that authors would place onto a page, or in our case, inside of a menu.


    import React, { useEffect } from 'react';
    import { Field, LinkField, withDatasourceCheck } from '@sitecore-jss/sitecore-jss-nextjs';
    import { initializeHeadlessEngine } from './Components/Engine';
    import { SearchEngine } from '@coveo/headless';
    import { ComponentWithContextProps } from 'lib/component-props';
    import { loadSearchHubActions } from '@coveo/headless';
    import StandaloneSearchBox from './Components/StandaloneSearchBox';
    import HeadlessEngineContext from './Components/HeadlessEngineContext';

    type MenuSearchBarProps = ComponentWithContextProps & {
      fields: {
        organizationId: Field<string>;
        searchHub: Field<string>;
        accessToken: Field<string>;
        searchPage: LinkField;
      };
    };
    
    const MenuSearchBar = ({ fields }: MenuSearchBarProps): JSX.Element => {
      // Grab the default engine state.
      const [engine, setEngine] = React.useState<SearchEngine | null>(null);
      useEffect(() => {
        // Initialize our engine with our fields from Sitecore
        initializeHeadlessEngine(fields).then((engine) => {
          setEngine(engine);
          // Set the search hub.
          const { setSearchHub } = loadSearchHubActions(engine);
          engine.dispatch(setSearchHub(fields.searchHub.value));
        });
      }, [fields]);
      if (engine) {
        return (
          // Use the HeadlessEngineContext to store our engine data.
          <HeadlessEngineContext.Provider value={engine}>
            ...
            // All components go within here
            ...
          </HeadlessEngineContext.Provider>
        );
      } else {
        return <div>Waiting for engine</div>;
      }
    };
    
    export default withDatasourceCheck()<MenuSearchBarProps>(MenuSearchBar);

With that in place, we can go forth and add in any components we need to build the menu search bar. Whether that be the search box itself or additional features like Query Suggestions.

👋 Hey Sitecore Enthusiasts!

Sign up to our bi-weekly newsletter for a bite-sized curation of valuable insight from the Sitecore community.

What’s in it for you?

  • Stay up-to-date with the latest Sitecore news
  • New to Sitecore? Learn tips and tricks to help you navigate this powerful tool
  • Sitecore pro? Expand your skill set and discover troubleshooting tips
  • Browse open careers and opportunities
  • Get a chance to be featured in upcoming editions
  • Learn our secret handshake
  • And more!
Sitecore Snack a newsletter by Fishtank Consulting
 

Meet David Austin

Development Team Lead | Sitecore Technology MVP x 3

📷🕹️👪

David is a decorated Development Team Lead with Sitecore Technology MVP and Coveo MVP awards, as well as Sitecore CDP & Personalize Certified. He's worked in IT for 25 years; everything ranging from Developer to Business Analyst to Group Lead helping manage everything from Intranet and Internet sites to facility management and application support. David is a dedicated family man who loves to spend time with his girls. He's also an avid photographer and loves to explore new places.

Connect with David