Creating a Standalone Search Box

Many web sites include a search box in each page. Performing a search request from such a standalone search box typically redirects the browser to a separate page that can display the results.

This article explains how to use the JavaScript Search Framework to create and deploy full-fledged standalone search boxes offering advanced features such as Coveo Machine Learning (Coveo ML) Query Suggestions (QS).

This article provides generic guidelines and examples for adding a Coveo-powered standalone search box to a web site or application.

If you are working with a specific in-product integration of Coveo (e.g., Coveo for Salesforce), see the corresponding product documentation instead:

Configuration

In summary, what you need to do to add a standalone search box in a page is:

  1. Load the required JavaScript Search Framework resources, i.e.:

    • The CoveoFullSearch.css stylesheet

    • The CoveoJsSearch.Lazy.min.js script

  2. Configure a search endpoint

    This will allow your standalone search box to provide Coveo ML query suggestions. Ensure that you properly set your search hub.

  3. Initialize a Searchbox component.

    If redirecting to an external search page, you will typically use the initSearchbox function to initialize the search box, as in the example just below (see Initializing - Embedded in a Normal Page).

    If redirecting to an internal search page, you will typically also include the search box in the main search page. In that main search page, you will instead initialize the search box externally, with the init function, as in the Node.js Express application example below (see Initializing - Embedded in the Main Search Page).

Example

The following example illustrates a normal page with a standalone search box using the search endpoint of the Coveo Documentation Sample Search Interface, and redirecting search requests to that page.

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Standalone Search Box Example</title>
  <!-- 1. Load the required resources -->
  <link rel="stylesheet" href="https://static.cloud.coveo.com/searchui/v2.7219/css/CoveoFullSearch.css"/>
  <script class="coveo-script" src="https://static.cloud.coveo.com/searchui/v2.7219/js/CoveoJsSearch.Lazy.min.js"></script>
  <script>
  document.addEventListener("DOMContentLoaded", () => {
    const searchBoxRoot = document.getElementById("searchbox");
    // 2. Configure a search endpoint
    Coveo.SearchEndpoint.configureCloudV2Endpoint("", "xx564559b1-0045-48e1-953c-3addd1ee4457");
    // 3. Initialize a Searchbox component
    Coveo.initSearchbox(
      searchBoxRoot,
      "https://docs.coveo.com/en/assets/html/basic-search-interface-example.html"
    );
  });
  </script>
</head>
<header>
  <div id="searchbox">
    <div class="CoveoSearchbox"></div>
  </div>
</header>
<body>
  <p>Page content...</p>
</body>
</html>

If you load the above sample in a web browser, you should see something like this:

Empty standalone search box

When you start typing in the query box, you should get Coveo ML query suggestions:

Query suggestions standalone search box

If you hit the Enter key, or click the search button, the standalone search box should redirect your search request to the Sample Search Interface:

Standalone search box redirected

Node.js Express Application Example

The following is a more complex example, which includes a standalone search box in a normal page, as well as in the main search page. More precisely, the standalone search box is included in the header of every page of a Node.js Express application. As you can see below, the initialization of that search box varies from one page to an other.

<!-- ./views/partials/header.ejs -->
 
<!DOCTYPE html>
<html lang="en">
<head>
  <title><%= title %></title>
  <!-- 1. Load the required resources. When in the main search page, this includes templates. -->
  <link rel="stylesheet" href="https://static.cloud.coveo.com/searchui/v2.7219/css/CoveoFullSearch.css"/>
  <script src="https://static.cloud.coveo.com/searchui/v2.7219/js/CoveoJsSearch.Lazy.min.js"></script>
  <% if (title === "My Main Search Page") { %>
  <script class="coveo-script" src="https://static.cloud.coveo.com/searchui/v2.7219/js/templates/templates.js"></script>
  <% } %>
  <script>
  document.addEventListener("DOMContentLoaded", () => {
    const mainPageRoot = document.getElementById("search");
    const searchBoxRoot = document.getElementById("searchbox");
    // 2. Configure a search endpoint.
    Coveo.SearchEndpoint.configureSampleEndpointV2();
    // 3. Initialize a Searchbox component. When in the main search page, this is done externally.
    if (mainPageRoot) {
      Coveo.init(mainPageRoot, {
        externalComponents: [
          searchBoxRoot
        ]
      });
    } else {
      Coveo.initSearchbox(searchBoxRoot, "/search");
    };
  })
</script>
</head>
<body>
  <header>
    <!-- Standalone search box -->
    <div id="searchbox">
      <div class="CoveoSearchbox"></div>
    </div>
  </header>
  <main>
<!-- ./views/partials/footer.ejs -->
 
  </main>
</body>
</html>
<!-- ./views/index.ejs -->
 
<%- include('partials/header') %>
 
  <h1>Landing Page!</h1>
  <p>Welcome to a normal page with a standalone search box</p>
 
<%- include('partials/footer') %>
<!-- ./views/search.ejs -->
 
<%- include('partials/header') %>
 
<!-- Main search interface, minus the search box -->
<div id="search" class="CoveoSearchInterface" data-enable-history="true">
  <div class="coveo-main-section">
    <div class="coveo-results-column">
      <div class="CoveoResultList"><div>
      <div class="CoveoPager"></div>
    </div>
  </div>
</div>
 
<%- include('partials/footer') %>
// ./index.js
 
var express = require("express");
var app = express();
 
app.set("view engine", "ejs");
 
app.get("/", function(req, res){
  res.render("index", { title: "My Normal Page With A Standalone Search Box" });
});
 
app.get("/search", function(req, res){
  res.render("search", { title: "My Main Search Page" });
});
 
app.listen(3000, function(){
  onsole.log("The Standalone Search Box demo application has started!");
});

To run the Node.js application:

  1. Ensure that you have Node.js installed.

  2. Create the application folder structure and files (e.g., ./index.js, ./views/index.ejs, ./views/partials/header.ejs, etc.)

  3. From the root folder of the application:

    1. Run npm init to create a ./package.json file.

    2. Run npm install ejs express to install the required dependencies.

    3. Run node index.js to run the application locally.

  4. Open localhost:3000 in your web browser.

You should then see behaviour such as:

Search Express App Gif

This subsection provides additional details regarding the initialization of your standalone search box, depending on your use case.

Embedded in a Normal Page

Initialize your standalone search box using the initSearchbox top-level function, as in the basic example above.

This function takes the following arguments:

  1. The root HTML element which contains the component (or components) to initialize (e.g., document.getElementById('searchbox')).

  2. The URL of the search page to redirect the search requests to (e.g., https://example.com/search).

Consider the following markup:

<div id="searchbox">
  <div class="CoveoSearchbox"></div>
</div>

You could initialize this standalone search box as follows:

const searchBoxRoot = document.getElementById("searchbox");
Coveo.initSearchbox(searchBoxRoot, "[ENTER URL]");

Embedded in the Main Search Page

You will likely want to repeat the HTML and initialization code of your standalone search box in the header of several pages, as in the Node.js Express application example above. In that case, you must adapt the initialization process as follows:

  1. Include additional logic to bypass the initSearchbox call when the current page is the search page.

    Calling the initSearchbox method in the search page itself does not make sense; instead, the init top-level function should initialize the search box in the search page.

  2. Inform the init call that some of the components it needs to initialize lie somewhere outside of its target root element by specifying the root HTML element that contains the search box in the externalComponents attribute of the second argument of the init call options parameter (see Initializing Components External to your CoveoSearchInterface). The value of the externalComponents attribute must be an array of HTML elements.

Suppose the id of the root element of your main search page is search. You could bypass the initSearchbox function call when the current page is the main search page, and tell the init function to initialize the search box as an external component like this:

document.addEventListener("DOMContentLoaded", () => {
  const mainPageRoot = document.getElementById("search");
  const searchBoxRoot = document.getElementById("searchbox");
  Coveo.SearchEndpoint.configureCloudV2Endpoint("", "**********-****-****-****-************");
  if (mainPageRoot) {
    // Initialize the main page, and further initialize the
    // standalone search box as an external component
    Coveo.init(mainPageRoot, {
      externalComponents: [
        searchBoxRoot
      ]
    });
  } else {
    // Initialize only the standalone search box, such
    // that it redirects the browser to the main search page
    Coveo.initSearchbox(searchBoxRoot, "https://example.com/search");
  };
})
Recommended Articles