DEV Community

Farai Gandiya
Farai Gandiya

Posted on • Originally published at agckb.xyz on

How To Add Search To Your Static Site

This post was originally posted on The Algorithmic Cookbook under How To Add Search To Your Static Site. This post is also on YouTube

In this post, I’ll go over how to add search to a static site by adding a form which points to a search engine.

What’s The Search Form Should Have

For the search form to work, it needs:

  • The form with role attribute search, a method attribute (usully GET) and an action attribute with a URL to your search provider,
  • the (labelled) text input field with the name attribute set to what the search engine uses as the search field whose value include site:yourdomain.example , and
  • a submit button along with
  • some optimizations like multiple search engines and hiding the site:yourdomain.example in the search field.

I’ll assume that search engines don’t use anti-CSRF tokens which you’ll need to find a way to submit with the rest of the form.

I’ve already added a search form in my site’s header if you wanna try it out and it looks like this.

input field and button which says Search in a Google

Examining the Search Engine

To start off, go to a search engine and see how it works. Here I’ll be using Google Search. Inspecting the home page, the search box is an input field with name q. Moving up to the form element, we can see an action of /search (which resolves to https://www.google.com/search) and a method of GET. Trimming the unnecessary stuff, Google’s search form looks like this (… is truncated code).

<form ... action="search" ... method="GET" name="f" ...role="search">
  ...
  <input ... name="q" ... aria-label="search">
  ...
  <input ... value="Google Search" ... name="btnK" type="submit">
  ...
</form>

Enter fullscreen mode Exit fullscreen mode

If I then search for site:agckb.xyz, Google gives me the search results on my website, the Algorithmic Cookbook.

Google search results for site:agckb.xyz

Those are shown by this URL.

https://www.google.com/search?sxsrf=ALeKk01GA8FFoL3T8g20i8cZI0hBiXwdCw%3A1598164783561&source=hp&ei=Lw9CX5m8H4mQlwSxsZDoAw&q=site%3Aagckb.xyz&oq=site%3A&gs_lcp=CgZwc3ktYWIQAxgAMgQIIxAnMgQIIxAnMgIIADICCAAyAggAMgIIADICCAAyAggAMgIIADICCAA6BQgAEJECOgQIABBDOggIABCxAxCDAToICC4QsQMQgwE6CgguEMcBEKMCEEM6BwguELEDEEM6AgguULrgBViH7wVg0PYFaAFwAHgAgAH_A4gB4BWSAQU0LTUuMZgBAKABAaoBB2d3cy13aXo&sclient=psy-ab

Enter fullscreen mode Exit fullscreen mode

It looks horrendus with all the other parameters (which were hidden), but all you need is the q parameter with the (URI encoded) search field. So this works just as well.

https://www.google.com/search?q=site%3Aagckb.xyz

Enter fullscreen mode Exit fullscreen mode

Using what we’ve discovered, we can make our own form.

<form method="GET" class="search-form" action="https://www.google.com/search" role="search" name="search-form">
    <label for="search-form_query" class="sr-only search-form_label">Search Term</label>
    <input class="search-form_query" type="text" name="q" id="search-form_query" value="site:agckb.xyz ">
    <button class="search-form_button" type="submit">Search on Google</button>
</form>

Enter fullscreen mode Exit fullscreen mode

Here we’ve taken what we’ve seen from the Google search and moved it into a form.

The form’s action points to what we saw on Google’s search form https://www.google.com/search/ with method GET. There’s also a role=search to expose the form as a search landmark for assistive technologies.

There’s a label for the search input. The sr-only is to visually hide the label so that assistive technologies can still understand what the input is for. There are other accessible labeling techniques in case you really don’t want a label element.

The input itself has name q, type text, the id for the label and a pre-filled value of site:agckb.xyz␣ ( represents whitespace U+020). The pre-filled label is necessary to search your site, otherwise it will search the web instead of your specific site.

What I’ve done above is the most supported, barebones way of searching through a search engine. No JavaScript needed. I’m also confident that it’ll work across various search engines with their respective form actions and search query parameters.

Multiple Search Engines

If search engines use the same search button form parameter, you could add a button with the formaction to another search engine. For instance, Google and DuckDuckGo use q as a search parameter. I could support DuckDuckGo by adding this button:

<button action="submit" formaction="https://duckduckgo.com/">Search DuckDuckGo</button>

Enter fullscreen mode Exit fullscreen mode

In DuckDuckGo’s case, you can also search via POST and you can add formmethod=POST to do just that.

Hiding the site:yoursite.example from the form input

The reason I used Google is because it makes this easier. We can add a second input with a name q with a hidden attribute and assign site:yoursite.example as the value.

<input type="text" name="q" label="site:agckb.xyz" hidden>

Enter fullscreen mode Exit fullscreen mode

This is search engine specific, but browsers will supply the two q parameters and the search engine may merge them together.

If you can’t do this, you can then use JavaScript to remove it on load and replace it when the user wants to submit the form submitting the form.

const searchForm = document.forms['search-form'];

window.addEventListener('load', () => {
  searchForm.q.value = '';
});

searchForm.addEventListener('submit', function(e){
  e.preventDefault();
  searchForm.q.value += 'site:yoursite.example';
  e.currentTarget.submit();
});

Enter fullscreen mode Exit fullscreen mode

If you don’t want to hard code the site:yoursite.example, you can do 'site:' + window.location.hostname instead.

Comparison of Search Engines

I’ve put this table together to compare how various search engines are set up. I could probably get away with just listing 4 or 5 of these, but discovering these search engines was fun.

Search Engine Form URL Methods Search Term Name Merges Multiple Inputs? Cross Compatable With
Google https://www.google.com/search GET q Yes DuckDuckGo, Ecosia, Bing, Yooz, Quant, Parsijoo
Bing https://www.bing.com/search GET q No Google, DuckDuckGo, Ecosia, Yooz, Quant, Parsijoo
Yahoo https://search.yahoo.com/search GET, POST p No
DuckDuckGo https://duckduckgo.com/ GET, POST q No Google, Ecosia, Bing, Yooz, Quant, Parsijoo
Yandex https://yandex.com/search/ GET text No
Baidu https://www.baidu.com/s GET wd No
Ecosia https://ecosia.org/search GET q No Google, DuckDuckGo, Bing, Yooz, Quant, Parsijoo
Startpage https://www.startpage.com/sp/search GET, POST query No SwissCows
Swisscows https://swisscows.com/web GET query Maybe (it mashes them, but didn’t have results) `query
Yooz https://yooz.ir/search GET q No Google, DuckDuckGo, Ecosia, Bing, Quant, Parsijoo
Quant https://quant.com/ GET q No Google, DuckDuckGo, Ecosia, Bing, Yooz, Parsijoo
Parsijoo https://parsijoo.ir/web GET q No Google, DuckDuckGo, Ecosia, Bing, Yooz, Quant

Conclusion

And that’s how you can add search to your static site through a form pointing to a search engine. This isn’t the only way to add search to a static site and I hope to explore other ways in the future.

As a teaser, I’ve made a purely front-end search solution on my old website with lunr.js, but it’s a horrible front end strategy as it:

  • adds ~450KB of JavaScript on the webpage,
  • doesn’t prebuild the search index and
  • does all the work on the main thread.

Given what I know now, it’s time I improved this approach. Heck, I might even be able to move this logic onto a backend as is and leverage serverless functions to do the actual searching. Possibilities are endless1.


  1. Possibilities are probably not endless, unless you calculate every permutation of code that can do exactly this, then they are I guess? Then again, you’re limited to a few general approaches. But aren’t the specifics distinct algorithms as subsets of the general approaches? Should have just left this as a cliche ending. ↩︎

Thanks for reading! If you’ve enjoyed this post, you can support me by

Discussion (0)