Mild-Mannered Canadian Fury

Doug Stephen is Politely Peeved

Presenting Swiftype Integration, And An Explanation Of How To Do It


Sat, 19 May 2012 Ā«permalinkĀ»

I have moved away from DuckDuckGo as my Site Search provider, in favor of beta-testing the YC-funded Swiftype service. They provide inline search results powered by their own crawler backend. It’s such a phenomenal concept; the only site that gets indexed is my own site instead of relying on a subset of the index of the entire web.

If you ever used the site search here when it was DDG powered, you know that the results were spotty at best. Even using a Google site search wouldn’t always return desired results. Swiftype eliminates this problem. They also provide great features like an API, in-line autocomplete/instant search, analytics, and the ability to customize result priority for keywords. Pretty awesome stuff.

It took me a few minutes to get everything set up on this site; they provide three installation types1 and I elected for the “results on a new page” installation.

Swiftype works by hooking their engines in to designated form elements on your page via JavaScript. The problem I was having was the fact that no search results were being rendered on the results landing page. Turns out there was a bit of a JS embedding conflict.

If the inline JS block for the search results as well as the search fields are both on the same page, there will be a conflict that prevents the results from loading properly. I placed the search field JS block in the after_footer partial so that it would be loaded on every page of the site, and this caused it to show up on the search results page. I probably could have done something like stuck the JS block in the article or something, but instead I decided to go with a Liquid conditional in the after_footer in the event that the script crapping out wouldn’t block in the middle of the page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
\\ Use your search results page URL here:
{% if page.url != "/search-results/index.html" %}

<script type="text/javascript">
  var Swiftype = window.Swiftype || {};
  (function() {
    Swiftype.key = 'your-engine-key';
    Swiftype.inputElement = '#st-search-input';
    Swiftype.resultContainingElement = '#st-results-container';
    Swiftype.attachElement = '#st-search-input';
    Swiftype.renderStyle = "new_page";
    Swiftype.resultPageURL = "{{ root-url }}/your-search-results-page/"

    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.async = true;
    script.src = "//swiftype.com/embed.js";
    var entry = document.getElementsByTagName('script')[0];
    entry.parentNode.insertBefore(script, entry);
  }());
</script>

{% endif %}

This keeps the scripts from getting double embedded, and wipes out the conflict. Just create your results page like you would any other Octopress page, paste the stuff from Swiftype, and be on your way. You’ll probably want to style things up a bit to match your current theme. But that’s all there is to it. You can also use this little liquid conditional to remove the search form on the Search Results page itself, since the search results page generates a large input block for searching on the results page anyway.

I hope that this service goes on to be successful, because I’m loving it.



  1. Write out to a div on the current page, bring up an overlay, or use a separate landing page.