Search across my blog posts and github projects

How I made a custom Google search across my github projects and blog posts.

The number of my github projects is growing (more than 100), so is the number of my blog posts. It has reached the point where finding a blog post or a project about something specific became a pain. Usually I search the local Markdown files instead of searching the actual blog website. I use the built-in github search to find a particular github project. This was all very slow and inefficient.

Finally I have decided to create a combined search app across blog posts and github projects. I made it very quickly using Google's custom search feature. You can try the result yourself. Open glebbahmutov.com and click "search". The search widget opens up, enter a few words, such as "code performance" and click "Search".

custom search widget

The search displays an overlay with found results above my website

custom search results

I can click "github" or "blog" tabs on the top of the results to only show found results from my github account or blog post. Here is how I made this custom search happen.

Create Google custom search engine

Start by going to the new custom search page and enter the basic information. For example, I named my website "Gleb Bahmutov". Immediately you get a custom long search url that will lead anyone to your custom built page. In my case it is this url.

First, I created a couple of labels that will divide my search results: "github", "blog", "personal", etc.

labels

These labels will show up as tab headers on the top of the results overlay and will limit results to come from a specific domain or several domains, because when creating each label I selected "Search only the sites with this label" option.

To choose the domains for a label, just apply the label to a site in the first setup page.

setup

Notice the search wildcards - I am searching the blog's index page and all its sub pages and any page starting with github/bahmutov.

Insert the search widget into the page

Once you have configured the search options (skip tweaking the styles), click "Get Code" button on the "setup" page and copy / paste the given code on to your page. You can see my personal website page's index.html. I decided to place the search widget in the main content area, below the header. The code to be pasted is JavaScript, and it will create search widget at the location where it is created.

The search widget is hidden by default, and appears when the user clicks the "search" link

<script>
(function() {
  var cx = '017313398942136460773:ey1oxxkrkve';
  var gcse = document.createElement('script');
  ...
  s.parentNode.insertBefore(gcse, s);
})();
document.getElementById('search').addEventListener('click', function () {
  document.getElementById('___gcse_0').style.display = 'block';
});
</script>
<gcse:search></gcse:search>

This creates the following widget when run

<div id="___gcse_0" style="display: block;">
    <div class="gsc-control-cse gsc-control-cse-en">
        ... a lot of markup
    </div>
</div>

The search automatically opens the overlay and displays the search results.

Customize the widget's style

The default widget does not match my website's visual style, and the built-in customization options are insufficient to make it do so. Thus I overrode the widget's elements' styles using CSS stylesheet. Most of the settings used !important qualifier.

:::css
.gsc-control-cse {
  background-color: inherit !important;
  border: none !important;
}

I removed the background and changed fonts and colors to match what I use on the website. The result blends in nicely. Note that the default prompt "Google Custom Search" is not a text, instead it is a watermark image, so I let it stay. Instead, I added :before element to label the search box

:::css
.gsc-control-cse:before {
  content: "Search my projects and blog posts";
  margin-left: 10px;
  color: #eaeaea;
}

Use custom search url as a browser search engine

You can submit the search query to my personal engine directly via url using q=<search string> parameter. For example, ...xkrkve&q=angularjs produces the following results

url seach

Instead of bookmarking this long url, you can paste it into the chrome://settings "Manage Search Engines" as a new engine. I added new engine with keyword "gleb" and the custom search url plus added search placeholder ...xkrkve&q=%s.

engine

Now when I want to find my blog post or a project, I start typing "gleb", then press Space to direct my search query to the custom url.

start searching

Shorter search url

As the final step, I configured my website's page to redirect to the search url, if there is q= search argument in the url. This is a simple JavaScript piece

index.html
1
2
3
4
5
6
7
8
9
10
11
12
(function redirectSearch() {
// redirect search queries to custom search endpoint
function hasSearch() {
return document.location.search.indexOf('q=') !== -1;
}
if (hasSearch()) {
console.log('has search', document.location.search);
var customSearchUrl = '...:ey1oxxkrkve&';
// pass the search part
document.location = customSearchUrl + document.location.search.substr(1);
}
}());

Now, I can kick off the custom search by going to the short url glebbahmutov.com/?q=<search terms>, for example q=improving+performance.

Integrate search into Alfred

If you are working on OSX, you probably use Spotlight App. I prefer Alfred free edition. It seems a little more advanced and is highly customizable. I configured a custom search in the Alfred preferences with the search url configured to point at the short search url above.

alfred gleb search

After saving the above custom search, I can open Alfred using Option-Space shortcut, type "gleb" and then send the search query to the default browser.

alfred search

This approach is even faster than using the custom search engine in Chrome.