Google Custom Search

For ExpressionEngine 6, ExpressionEngine 3+, ExpressionEngine 2 • Current Version: 1.2.3

Purchase for $19

Display search results from your Google Custom Search Engine using standard EE template tags via the Google Custom Search API. A great search solution for your site if:

  • you have a low-to-medium traffic site
  • you want better relevance when searching, including the ability to add synonyms for search terms and more
  • you need to include the contents of PDF files in your search results
  • you need to search non-EE content (e.g., static HTML files) or content from other domains or sites, in addition to your EE content

The Google Custom Search API currently limits searches to 100 results per query, and 100 free queries per day. There is no daily query limit if you enable billing on your account (Google will bill $5 per additional 1000 queries, per day.)

Google Custom Search also integrates with Snaptcha to prevent spam searches from using up your queries and filling your search log with junk. (A simpler, but less-ruthless “honeypot” anti-spam measure is included for those who don’t use Snaptcha.)


  • ExpressionEngine® 3.0.0 or greater, or ExpressionEngine® 2.8.0 or greater
  • A Google Custom Search Engine ID or Linked Custom Search Engine file
  • A Google Custom Search API key
  • cURL and OpenSSL support on your server



Upload the included google_custom_search folder to your /system/user/addons/ directory (or /system/expressionengine/third_party/ directory if you’re running EE2), then install Google Custom Search from the Add-On Manager screen (or the Add-Ons → Modules screen if you’re running EE2).

You will need to obtain a Google Custom Search API key and either a Google Custom Search Engine ID or the link to a Custom Search Engine file.

The API key is what authorizes you to make requests to the Google Custom Search API (and keeps an eye on your daily request limit, and billing if enabled). The CSE ID (or alternately, the CSE “cref” file) is what gives the API the various parameters it needs to perform your search. (Many of these can be overridden via parameters applied to the results template tag).

Template Tags


This tag pair outputs the search form you’ll use to perform your custom search. It accepts six tag parameters:

  • results_page="template_group/template"(required) the template path where your search results code is located
  • id="form_id" – the “id” attribute for your form
  • class="form_class" – the “class” attribute for your form
  • honeypot="yes" – whether or not to add a hidden “honeypot” field to the form, useful if you’re experiencing search spam. Defaults to “no”.
  • snaptcha="yes" – if you have the Snaptcha extension installed, you can add Snaptcha protection to your search form with this parameter.
  • snaptcha_level="high" – if you are using the Snaptcha parameter, you can optionally set a custom Snaptcha security level which differs from your default security level. Valid values are “low”, “medium”, and “high”.


        <input type="text" name="keywords" size="20" placeholder="Enter keywords" />
        <input type="submit" name="submit" value="Search" />

This tag pair outputs your CSE search results. It accepts several parameters:

  • api_key - (required if no access_token) your Google Custom Search API key
  • access_token - (required if no api_key) your Google Custom Search API OAuth 2.0 access token
  • cse - (required if no cref) your Google Custom Search Engine unique ID
  • cref - (required if no cse) URL to an XML-formatted Custom Search Engine file
  • keywords - (required) the URL segment which holds your encoded keywords. It will be the segment which follows the current template segment.
  • limit - the number of results to return per-page. Valid values are any number between 1 and 10 (default).
  • sort_attribute - name of the structured data attribute by which you’d like to sort the search results. If the site you’re searching doesn’t have any structured data, then you can likely only use “date” as a value here. Pass multiple values separated by a pipe (“|”) character.
  • sort_order - the order by which you’d like to sort the results when using the sort_attribute parameter. Valid values are “asc” and “desc”. Pass multiple values separated by a pipe (“|”) character.
  • sort_bias - whether you want to bias your results based on the sort_attribute parameter. Valid values are “strong” and “weak”. Pass multiple values separated by a pipe (“|”) character.
  • include_terms - an exact phrase to include alongside your keyword search.
  • exclude_terms - terms which will exclude results from your search.
  • and_terms - terms to include via the AND operator in your search.
  • or_terms - terms to include via the OR operator in your search.
  • site - URL with which to further restrict your search to.
  • exclude_site - URL to exclude from your search results.
  • link_site - URL which must be present as a link in all returned results
  • related_site - URL which all search results should be related to (as determined by Google).
  • filetype - search only for files of a specific type (file extension).
  • days - only return results from the past N number of days.
  • weeks - only return results from the past N number of weeks.
  • months - only return results from the past N number of months.
  • years - only return results from the past N number of years.
  • safe - search safety level (for mature content). Valid values are “high”, “medium”, or “off” (default).
  • filter - duplicate content filter. Valid values are “off” or “on” (default).
  • language - restrict the search to documents written in a particular language. See accepted values. Default is all languages.
  • single_chinese - set to “yes” to disable your Chinese-language search from displaying both Simplified and Traditional Chinese results.
  • country - restrict the search to results determined to originate in a particular country. See accepted values.
  • google_host - restrict search results to those found via a localized Google engine (e.g.,
  • replace_title - a common string of text in your page titles that you’d like removed from titles in your results (e.g. your site name).
  • paginate - where to place the pagination code in your template. Valid values are “top”, “bottom”, or “both”.

The following variables are available within the {exp:google_custom_search:results} tag, both as variables and conditionals:

  • {keywords} - your search phrase
  • {count}, {total_results}, and {absolute_results} - these all function identically to the native Channel Entries variables of the same names *
  • {paginate} - this tag pair functions identically to the native Channel Entries tag pair *
  • {title} - the page title of the search result
  • {title_formatted} - the page title of the search result, with Google’s search phrase emphasis intact
  • {excerpt} - the relevant content snippet of the search result
  • {excerpt_formatted} - the relevant content snippet of the search result, with Google’s search phrase emphasis intact
  • {url} - the URL to the search result
  • {image} - URL to Google’s chosen image for this result, if available
  • {thumbnail_image} - URL to the Google-cached, thumbnail version of Google’s chosen image for this result, if available
  • {format} - the file format of the search result (based on the result’s file extension)
  • {google_results_url} - the URL to perform this search directly on Google
  • {total_google_search_results} - the total number of search results available for your query when performed directly on Google
  • {request_url} - the full URL of the current API request to Google (useful for debugging)

* Note that as when searching via Google’s website, results counts are always approximate, and sometimes even vary when paging between result sets, so you may find result and page counts vary.


    {if no_results}<p>Sorry, your search returned no results.</p>{/if}
    {if count == 1}
        <p>Your search for <strong>{keywords}</strong> received {absolute_results} results.</p>
                {if image}<a href="{url}"><img src="{image}" alt="{title}" /</a>{/if}
                <a href="{url}" class="result_{format}">{title}</a> - {excerpt} <small>({url})</small>
        {if count == total_results}</ol>{/if}
            <p>Page {current_page} of {total_pages} pages {pagination_links}</p>

This single tag outputs the current search keywords, with simple formatting applied. It accepts one required parameter:

  • keywords="{segment_3}"(required) the segment which contains the md5 hash of your search terms.


{exp:google_custom_search:keywords keywords="{segment_3"}


Since the module interacts with Google’s remote API, and since that API does employ a limit (or charge) on queries per day, it’s advisable to employ some manner of local caching to avoid excessive server requests. At the most basic, we suggest employing ExpressionEngine’s native tag caching - or you may want to look at a more advanced solution such as CE Cache.


Visit the official support forums on devot:ee.


  • 1.2.3 (August 14th, 2019)
    • Fixed issue with the {exp:google_custom_search:keywords} tag
  • 1.2.2 (July 18th, 2019)
    • Fixed issue when using Snaptcha integration under EE5
    • Fixed issue with searching for words contain special characters
  • 1.2.1 (November 16th, 2015)
    • Fixed bug in EE2 version introduced with code refactoring in version 1.2.0
  • 1.2.0 (November 1st, 2015)
    • Changed variable naming and pagination in the “results” tag to be consistent with Channel Entries variables (see docs for examples)
    • Added EE3-compatible version
    • EE2 version now requires EE 2.8.0 or greater, and is feature-frozen
  • 1.1.5 (January 27th, 2015)
    • Added sort_attribute, sort_order, and sort_bias parameters
    • Removed bundled documentation
  • 1.1.4 (March 3rd, 2014)
    • Fixed control panel error when running under EE 2.8
    • Removed XID hash-checking from search form
  • 1.1.3 (April 17th, 2013)
    • Added integration with Snaptcha
    • Added new snaptcha and snaptcha_level parameters to the form tag
    • Added compatibility with EE 2.6’s Localize class
  • 1.1.2 (February 6th, 2013)
    • Added the {absolute_result_count} variable
    • Added XID hash-checking to search form
    • Fixed bug where you would not be redirected to Google for your search after hitting your daily API limit
  • 1.1.1
    • Fixed pagination bug when ordering/sorting by different fields in the search log
  • 1.1.0 (September 17th, 2012)
    • Added {image} and {thumbnail_image} variables for results which include image metadata
    • Added a slew of new parameters to catch up with the updated version of the Custom Search API
    • Now using partial fields in the API call to speed up requests
    • Fix for issues with IPv6 on some servers
    • Pagination fix in control panel under MSM
    • Added ability to sort the search log by keyword, search count, or date
    • Added ability delete terms from the search log
  • 1.10.11 (August 29th, 2012)
    • Fix for compatibility with EE 2.5+ on PHP < 5.2
  • 1.10.10 (June 10th, 2012)
    • Fix for results pagination numbering
  • 1.0.9 (February 7th, 2012)
    • Fix for PHP errors when returned results have no titles or summaries
  • 1.0.8 (November 14th, 2011)
    • Added new (optional) honeypot parameter to the search form to trap search spam
  • 1.0.7
    • Added new variables: {current_page}, {total_pages}, {current_results_start}, and {current_results_end}
  • 1.0.6 (July 22nd, 2011)
    • Added more useful error messages when the API call fails
  • 1.0.5
    • Fixed issues with servers running PHP < 5.2 where the supplemental JSON library was not loading
    • Added some template debugger messages
  • 1.0.4 (July 1st, 2011)
    • Fixed potential issue with loading control panel view files
  • 1.0.3
    • Changed default results language from English to any language
  • 1.0.2
    • Now using md5 hashes for keyword segments instead of base64 encoding due to potential issues with equals (=) characters in the URL
  • 1.0.1
    • Added {format} variable, removed {is_pdf} variable
  • 1.0 (June 22nd, 2011)
    • Initial release

Browse more software