CMS Development

awwaldesign
Participant

Broad keyword match HubSpot site search?

Hello all,

 

I've added the HubSpot site search on my blog page. The way it works is that when I enter a search term for example dog it shows results for the articles containing the word dog but when I search dogs it doesn't give any results so it uses the "exact keyword match" rather than "Broad keyword match" I was wondering if there's way to customize it to show dog results even if I search dogs? (singular/plural)

Any help is appreciated 🙂

 

Thank you!

4 Replies 4
MiaPV
Top Contributor

Broad keyword match HubSpot site search?

I'd love to bubble this up to the top because I'm not even sure most HubSpot users are aware that the HubSpot search doesn't function like Google's. This doesn't just seem like, it is a major flaw in the product. People misspell things all the time. Sometimes a word is plural and sometimes it isn't, but either form should come up in search. I was told that HubSpot search was created this way because other companies needed it. Seems to me those companies should be able to write something to exclude anything other than the exact term while keeping it nice and loose for the rest of us. In fact, this isn't even about us, it's about user experience. Our audiences expect to be able to search like they do on Google. Otherwise, it forces us to keyword stuff our posts, which is also bad for user experience. I really hope HubSpot decides to make updating search for singular/plurals and misspellings a priority.

Thanks

Mia

awwaldesign
Participant

Broad keyword match HubSpot site search?

Agreed.

0 Upvotes
Anonymous
Not applicable

Broad keyword match HubSpot site search?

Hi @awwaldesign,

 

Here are a few resources to help get you started: 

1. Set up search results

2. FAQs for search results

0 Upvotes
awwaldesign
Participant

Broad keyword match HubSpot site search?

Hi @Anonymous,

 

Thank you so much for replying. I was about to lose hope 🙂

I've already setup the search box and the search result page. It mostly works fine but my problem is with the way it works.

 

So for example If I search Dog it shows me result of articles with the word Dog in it. This part is good I've no problem with this but if I search Dogs (Plural) it doesn't give me any results, Instead I get "No result found" I want it to show articles containing the word Dog in results even if the search term is Dogs.

 

So from my understanding, It looks for the "exact term" rather than a "broad term" Is there any way to customize the search this way?


Does this make sense?


Here's HUBL code

<div class="hs-search-field"> 
  <h3>
          Search The Blog 
        </h3>
    <div class="hs-search-field__bar"> 
      <form id="search-form" action="/{{ site_settings.content_search_results_page_path }}">
        <input type="text" class="hs-search-field__input" name="term" autocomplete="off" placeholder="{{ module.placeholder }}">
        <input type="hidden" name="type" value="BLOG_POST">
        <input type="hidden" name="pathPrefix" value="blog">
        <button type="submit" form="search-form" value="Submit" class="hs-button primary"><i class="fa fa-search"></i></button>

        <ul class="hs-search-field__suggestions"></ul>
      </form>
    </div>
    
</div>




And Here's JS

var hsSearch = function(_instance) {
  var TYPEAHEAD_LIMIT			= 10;
  var searchTerm      		= "blog_post",
      searchForm 					=	_instance,
      searchField 				= _instance.querySelector('.hs-search-field__input'),
      searchResults 			= _instance.querySelector('.hs-search-field__suggestions'),
     	searchOptions				= function() {
        var formParams = [];
        var form = _instance.querySelector('form');
        for ( var i = 0; i < form.querySelectorAll('input[type=hidden]').length; i++ ) {
           var e = form.querySelectorAll('input[type=hidden]')[i];
          	if (e.name !== 'limit') {
            	formParams.push(encodeURIComponent(e.name) + "=" + encodeURIComponent(e.value));
            }
        }
        var queryString = formParams.join("&");
				return queryString;
      };
  
  var debounce = function(func, wait, immediate) {
    var timeout;
    return function() {
      var context = this,
          args = arguments;
      var later = function() { 
        timeout = null;
        if ( !immediate ) {
          func.apply(context, args);
        }
      };
      var callNow = immediate && !timeout;
      clearTimeout(timeout);
      timeout = setTimeout(later, wait || 200);
      if ( callNow ) { 
        func.apply(context, args); 
      }
    };
  },
  emptySearchResults = function(){
    searchResults.innerHTML = '<li class=\"hs-search__no-results\">No Result Found</li>';
    searchField.focus();
    searchForm.classList.add('hs-search-field--open');
  },
  fillSearchResults = function(response){
    var items = [];
		items.push( "<li id='results-for'>Results for \"" + response.searchTerm + "\"</li>" );
    response.results.forEach(function(val, index) {
      items.push( "<li id='result" + index + "'><a href='" + val.url + "'>" + val.title + "</a></li>" );
    });

    emptySearchResults();
    searchResults.innerHTML = items.join("");
    items.push( "<li>No Result </li>" );
    searchForm.classList.add('hs-search-field--open');
  },
  getSearchResults = function() {
			var request = new XMLHttpRequest();
   		var requestUrl = "/_hcms/search?&term="+encodeURIComponent(searchTerm)+"&limit="+encodeURIComponent(TYPEAHEAD_LIMIT)+"&autocomplete=true&analytics=true&" + searchOptions();

      request.open('GET', requestUrl, true);
      request.onload = function() {
        if (request.status >= 200 && request.status < 400) {
          var data = JSON.parse(request.responseText);
          if (data.total > 0) {
            fillSearchResults(data);
            trapFocus();      
          }
          else {
            emptySearchResults();
          }
        } else {
          console.error('Server reached, error retrieving results.');
        }
      };
      request.onerror = function() {
        console.error('Could not reach the server.');
      };
      request.send();
    },
  trapFocus = function(){
    var tabbable = [];
    tabbable.push(searchField);
    var tabbables = searchResults.getElementsByTagName('A');
    for (var i = 0; i < tabbables.length; i++) {
      tabbable.push(tabbables[i]);
    }
    var firstTabbable = tabbable[0],
        lastTabbable  = tabbable[tabbable.length-1];
    var tabResult = function(e){
      if (e.target == lastTabbable && !e.shiftKey) {
        e.preventDefault();
        firstTabbable.focus();   		
      }
      else if (e.target == firstTabbable && e.shiftKey) {
        e.preventDefault();
        lastTabbable.focus();
      } 
    },
    nextResult = function(e) {
      e.preventDefault();
      if (e.target == lastTabbable) {
        firstTabbable.focus();
      }
      else {
        tabbable.forEach(function(el){
          if (el == e.target) {
            tabbable[tabbable.indexOf(el) + 1].focus();
          }
        });
      }
    },
    lastResult = function(e) {
      e.preventDefault();
      if (e.target == firstTabbable) {
        lastTabbable.focus();
      }
      else {
        tabbable.forEach(function(el){
          if (el == e.target) {
            tabbable[tabbable.indexOf(el) - 1].focus();
          }
        });
      }
    };
    searchForm.addEventListener('keydown', function(e){
      switch (e.which) {
        case 9:
          tabResult(e);
          break;
        case 27:
          emptySearchResults();
          break;
        case 38:
          lastResult(e);
          break;
        case 40:
          nextResult(e);
          break;
      }
    });      
  },
  isSearchTermPresent = debounce(function() {
    searchTerm = searchField.value;
    if(searchTerm.length > 2) {
      getSearchResults();
    }    
    else if (searchTerm.length == 0)  {
      emptySearchResults(); 
    }
  }, 250),
  init = (function(){
    searchField.addEventListener('input', function(e) {
      if ((e.which != 9) && (e.which != 40) && (e.which != 38) && (e.which != 27) && (searchTerm != searchField.value)) {
        isSearchTermPresent();
      }
    });
  })();
}

if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading"){
  var searchResults = document.querySelectorAll('.hs-search-field');
  Array.prototype.forEach.call(searchResults, function(el){
    var hsSearchModule = hsSearch(el);
  });
} else {
  document.addEventListener('DOMContentLoaded', function() {
    var searchResults = document.querySelectorAll('.hs-search-field');
    Array.prototype.forEach.call(searchResults, function(el){
      var hsSearchModule = hsSearch(el);
    });
  });
}


$(document).click(function(e){
    var targetbox = $('.hs-search-field');
    if(!targetbox.is(e.target) && targetbox.has(e.target).length === 0){
    $('.hs-search-field').removeClass("hs-search-field--open");
}
});
0 Upvotes