🔎 Adding Google Custom Search to Ghost
The Ghost publishing platform has no build in search functionality. This post explains to add site search with Google Custom Search to a site published with Ghost.
The Ghost publishing platform has no build in search functionality. This post explains to add site search with Google Custom Search to a site published with Ghost.
Why Google Custom Search?
There are a number of possible ways to add search to a site published with Ghost:
- Run a Solr, Lunr, Elasticsearch or Amazon Web Services CloudSearch instance[1], and use the Ghost API to deliver the content of thecodemill.biz to the search engine for indexing.
- Use Algolia freemium hosted search. The downside is one also has to push the content to the search engine for it to be indexed.
- ExpertRec is a $5+/month hosted search. However, not sure if it crawls your site or if you have to push content to it.
- Cludo's hosted search is $200+/month, crawls your site and promises lots of customization and reporting.
- SwifType also offers hosted search and will crawl your site for $300+/month.
- Or you can leverage Google's index of your site by creating a Google Custom Search limited to your site.[2]
From these options:
-
Solr, Lunr, Elasticsearch, CloudSearch and Algolia all require significant development work to push content to the search engine when changes are made. I expect that —down the line, Ghost will add support for some of these solutions. How to add search to Ghost is already being discussed on Github. In the end, Ghost will probably have a app (aka. extension) for Solr/Elasticsearch similar to Wordpress, Jekyll and other publishing platforms. ❎
-
ExpertRec is primarily focused on the Magento E-commerce Platform plus it lacks any and all documentation. ❎
That leaves Google Custom Search for the time being. ✅
Create a Google Custom Search for your site
Follow the steps outlined in the Google Custom Search Help pages to create a custom search specific to your site.
I opted for an integration that required the least amount of changes to Ghost. I set The Code Mill search up as a separate full-width search page with the search box at the top of the page and results below it. Like so:
This setup requires the following elections in Google Custom Search:
- Select a Full Width layout in the Look and Feel section. This places the search results below the search box.
- Set the Link Target to
_self
in the Websearch Settings of the Search Features section. Now, result-links open in the current browser tab, for if you don't set the link target, links will open in a new tab.
Add the Google Custom Search to your site
Create a new story in Ghost and turn it into a page.
Copy the Javascript snippet for your site's custom search from Google Custom Search. You can get the snippet from the Setup section in the Basics tab by clicking the Get code button. The snippet will look similar to the snippet below but have a different cx
value[3]. This is the unique ID of your custom search.
<script>
(function() {
var cx = '451650838876851240126:1abjymvhb89';
var gcse = document.createElement('script');
gcse.type = 'text/javascript';
gcse.async = true;
gcse.src = 'https://cse.google.com/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(gcse, s);
})();
</script>
<gcse:search></gcse:search>
Paste the <script>…</script>
portion into the Post Footer of the Code Injection portion of the page.
Place the gcse:search
tag on the page inside a wrapper element. E.g.
<div class="search-wrapper">
<gcse:search></gcse:search>
</div>
Resolve styles conflicts between your site's styles and those brought in by Google Custom Search. Use the wrapper element to limit conflict resolution to just the search box and results. These are the changes I made to get a clean search experience on The Code Mill inside the default Casper theme:
<style>
.search-wrapper {
min-height: 21em;
line-height: 1em;
box-sizing: initial;
width: 100%;
}
.search-wrapper .gsc-control-cse input {
margin-top: 0 !important;
}
.search-wrapper .gsc-control-cse table {
background: none;
overflow-x: initial;
line-height: 1em;
margin: 0;
white-space: normal;
}
.gcsc-branding, .gsc-branding-text, .gsc-branding-img {
display: none !important;
}
.search-wrapper .gsc-control-cse table td {
border: none;
padding: 0;
}
.search-wrapper .gsc-search-box .gsc-input>input:focus,
.search-wrapper .gsc-input-box-focus {
box-shadow: none;
-moz-box-shadow: none;
-webkit-box-shadow: none;
}
.search-wrapper .gsc-results img {
margin: 0;
}
</style>
To make search available from any page on the site I added Search to the site's navigation in the header. Ghost makes this really easy. Simply add a new entry to the Design Settings:
I would have liked to place focus on the search box field upon loading the search page but was unsuccessful. Calling the focus
function on the <input>
field had no effect. I have a feeling that Google prevents one from doing this so that you have to see search is provided by Google Custom Search.
Takeaways
I'm very pleased with how well this worked within Ghost's data model. Google's Custom Search Javascript is only loaded on the search page where it is used. The same applies to the CSS changes to resolve style conflicts. Adding the search box and results was super easy thanks to Ghost's Markdown format. Plain old HTML is valid Markdown after all.
Google Custom Search doesn't always return all pages containing the search term(s) though. But beggars can't be choosers when it is free and overall the results are comprehensive enough to get to all the relevant content. If not directly then indirectly via one of the pages in the result set.
All in all, I'd say it is an 80/20 solution: accomplishing 80% with 20% of the effort.
Photo by Goran Ivos / Unsplash
As a Docker container on your own host or in the cloud. ↩︎
Unfortunately, Google has discontinued sale/renewal of the Google Site Search since Apr 1, 2017. The product will be completely shut down by April 1, 2018. That leaves Google Custom Search as Google's only web-based offering. ↩︎
The
cx
value in the snippet in the post is not a real custom search ID. ↩︎