The Coveo JavaScript Search Framework, also known as the JSUI, lets you build visually rich, full-featured search interfaces. Thanks to the Hosted Search Pages and the WYSIWYG Interface Editor, Coveo platform users (even the ones with no programming skills) can discover their content easily. All the resources used to set up a Hosted search page are now available through the Search Pages API.

How can we benefit from this API and ease our JSUI integrations?

Limits of the Usual Approach

At Coveo Professional Services, the JSUI integration in our client environments can be painful. Here are a few key points to illustrate:

  • Code is packaged before deployment, JavaScript and CSS are easily bundled, yet we still need to make sure it ends up between the HTML head element of our client pages.
  • Ideally, the HTML would be handled in a separate file on the client system. The reality is that it is common that our HTML must be appended to an existing client file, which is adding some merge operations.
  • The deployment process will vary from one client to another. It can be done within a few minutes for some clients, while for others it will take days.
  • Quite often, the client’s web technology forces us to ramp up on systems we don’t know (and no, it is not necessarily a good opportunity to learn something new).
  • Finally, like our R&D teams, we like the benefits of continuous deployment, but we rarely have the opportunity to enjoy them.

Even for clients who integrate the JSUI by themselves, it’s usually coupled to their own web application—putting UI integration and deployments at risk! Ideally, the Coveo integration would be a one-time job and require minimum code.

Now let’s see how client UI and JSUI development can be decoupled.

Hosted Search Pages API

Recently, Search Pages API has been improved. It now lets us download all the resources required to load a search page.

A gif illustrates the drag-and-drop nature of building a user interface within the Coveo platform.

 Sitecore Hosted Search Page Component

The Coveo for Sitecore product team were the first to jump on the occasion to leverage the Search Page API upgrade. They have added a Sitecore server side component that renders an HTML component. The JavaScript bundled in Coveo for Sitecore then handles the code logic to fetch the Coveo API.1

A screen capture shows an example hosted search page within a Sitecore interface

For more details on how to implement this solution, have a look at this great article from Hugo Santos: Coveo for Sitecore – Cloud Hosted Search Page, The Fastest Way of Creating a Sitecore Search Interface Ever.

VueJS Use Case

When our client OsiSoft decided to move their public website to Sitecore, we were given a short five weeks to deliver five search interfaces. They decided to go with Sitecore JSS and the VueJS library.

As VueJS is not supported yet with Coveo for Sitecore OOTB package2, the solution has been to guide the client to implement VueJS code logic to implement a similar logic to the OOTB Coveo for Sitecore component.

Hosted Search Page Web Component

Jean-François Allaire from our Professional Services team developed a more generic solution by using a Web Component. The source code can be found here: https://github.com/Coveo-Turbo/hosted-search-page.

As you can see below, very little code is needed to integrate our search page and we have all the control over the Hosted Search page.

1 – Add a reference to the JavaScript package between the HTML head element:

<script src="https://unpkg.com/@coveops/hosted-search-page@latest/dist/index.min.js"></script>

2 – Here are the Web Components that will render the search interface, its searchBox, and a standalone searchBox:

<hosted-search-page id="searchPage"></hosted-search-page>

<hosted-search-page id="searchBox"></hosted-search-page></div>

<hosted-search-page id="globalSearchBox"></hosted-search-page>

3 – Here is how to initialize the code. Note that we use the custom event CoveoScriptLoaded instead of page load. Page IDs are not directly exposed in the platform; you can use Swagger UI to retrieve them:

var COVEO_ORG_ID = '**************************';
var COVEO_SEARCH_PAGE_API_KEY = '**********-****-****-****-************';
var coveoToken = '**********************************';

var hostedGlobalSearchBox = document.getElementById('globalSearchBox');
if (hostedGlobalSearchBox) {
hostedGlobalSearchBox.configure({
orgId: COVEO_ORG_ID,
apiKey: COVEO_SEARCH_PAGE_API_KEY,
pageId: '**********-****-****-****-************'
});
}

var hostedSearchBox = document.getElementById('searchBox');
if (hostedSearchBox) {
hostedSearchBox.configure({
orgId: COVEO_ORG_ID,
apiKey: COVEO_SEARCH_PAGE_API_KEY,
pageId: '**********-****-****-****-************'
});
}

var hostedSearchPage = document.getElementById('searchPage');
if (hostedSearchPage) {
hostedSearchPage.configure({
orgId: COVEO_ORG_ID,
apiKey: COVEO_SEARCH_PAGE_API_KEY,
pageId: '**********-****-****-****-************',
htmlOnly: true
});
}

document.addEventListener('CoveoScriptsLoaded', function () {

var globalSearchbox = hostedGlobalSearchBox.searchPage.querySelector('.CoveoSearchInterface');

if (coveoToken && coveoToken.token) {
Coveo.SearchEndpoint.configureCloudV2Endpoint(COVEO_ORG_ID, coveoToken.token);
if (Coveo.WindriverHelper.isSearchPage()) {
var search = hostedSearchPage.searchPage.querySelector('.CoveoSearchInterface');
var searchbox = hostedSearchBox.searchPage.querySelector('.CoveoSearchInterface');
Coveo.init(search, {
externalComponents: [
globalSearchbox,
searchbox
]
});
} else {
Coveo.initSearchbox(globalSearchbox, '/result', {});
}
}
});

4 – And here is a real-life implementation of this example, done for Wind River.

Conclusion

Timewise, this approach is a big win. Add to this the use of coveo-turbo, you can start building search pages locally and push them to the platform in a matter of seconds, as explained in this Deploying a page to the Coveo platform article. JavaScript and CSS customizations are supported as they are injected inline between script and style tags.

It is recommended to use bundled coveo-turbo custom components as much as possible to keep the inline header script as light as possible.

Client concerns to consider before going forward with this approach:

  • Is the client okay with the fact that JavaScript code is on Coveo side? (Let them know that JSUI will still run client side but a delay to download the scripts is added.)
  • Even if the Coveo API is responsive enough for most use cases, stress tests should be run—especially for commerce clients that have a lot of visits.
  • Deployment process can be done from the source code. (locally or build server—nice way to get continuous deployment, right?) Snapshot resources also lets you package and deploy search pages. Copying and pasting the DOM from the editor will not be enough, as the header is skipped in the editor.
  • If client uses a SPA framework, same as for regular JSUI integration, you will have to defer the initialization based on the framework events.

1. To support Sitecore JSS (headless approach), an NPM library has been developed.

2. Last time I checked, Sitecore JSS had to be implemented with React to support Hosted Search Page functionalities. (Sitecore JSS also offers VueJS and Angular.)