imarc / craft-googlecustomsearch
A Craft plugin for site search via Google Custom Search, Google Vertex AI Search, or AddSearch.
Package info
github.com/imarc/craft-googlecustomsearch
Type:craft-plugin
pkg:composer/imarc/craft-googlecustomsearch
Requires
- php: ^8.2
- craftcms/cms: ^4.0.0 || ^5.0.0
- google/auth: ^1.30
Requires (Dev)
- craftcms/rector: dev-main
- phpunit/phpunit: ^10.0
Replaces
This package is auto-updated.
Last update: 2026-08-21 14:49:01 UTC
README
A Craft CMS plugin that adds external site search to your website, with three supported providers:
- Google Programmable Search Engine (Custom Search JSON API)
- Google Vertex AI Search (Discovery Engine)
- AddSearch
The provider is chosen per site, so multisite installs can mix providers. All providers return the same result shape, so your templates don't change when you switch.
This plugin was previously published as imarc/craft-googlecustomsearch. See Upgrading from v2 below. If you are looking for the Craft 2 version, see the craft2 branch.
Requirements
This plugin requires Craft CMS 4.x or 5.x and PHP 8.2+.
Installation
-
Open your terminal and go to your Craft project:
cd /path/to/project -
Then tell Composer to load the plugin:
composer require imarc/craft-sitesearch -
In the Control Panel, go to Settings → Plugins and click the “Install” button for Site Search.
Configuring
Go to Settings → Plugins → Site Search, pick a provider for each site (use the site menu to switch between sites on multisite installs), and fill in that provider's credentials. Every field accepts environment variables ($MY_VAR). Credentials can also be set in config/sitesearch.php (see Config file).
Google Custom Search setup
You will need a Search Engine ID and API Key.
- Search Engine ID — On the Programmable Search Engine control panel, create a search engine for the site you would like to integrate. Once created, copy the Search Engine ID from the Basics tab.
- API Key — In the Google Cloud console, create (or pick) a project, enable the Custom Search API (APIs & Services → Library), then create an API key under APIs & Services → Credentials. Restrict the key to the Custom Search API.
Google Vertex AI Search setup
Vertex AI Search (in the Google Cloud console as "AI Applications", formerly Agent Builder / Discovery Engine) provides Google-quality search over a crawled website index.
- In the Google Cloud console, create (or pick) a project and note its Project ID.
- Enable the Discovery Engine API (APIs & Services → Library → "Discovery Engine API").
- In AI Applications, create a data store:
- Select Website content.
- Enter your site's domain as the website URL and complete the data store setup. Verify the domain for advanced indexing if prompted.
- Wait for the initial crawl to begin; it can take some time for the website index to populate.
- Create a Search app and attach the data store:
- Select Site search with AI mode, then choose the website data store you created.
- Note the app's ID — this is the plugin's App / Engine ID — and its location (usually
global).
- Create credentials for the plugin:
- Go to IAM & Admin → Service Accounts, create a service account (e.g.
craft-site-search). - Grant it the Discovery Engine Viewer role (
roles/discoveryengine.viewer). - Create a JSON key for it (Keys → Add key → JSON) and store the file on your server outside the web root.
- In the plugin settings, set Service Account Key File to the file path (an env var like
$GOOGLE_APPLICATION_CREDENTIALSworks well). - On Google Cloud hosting (Cloud Run, GCE, App Engine): leave the key file blank and grant the runtime service account the Discovery Engine Viewer role — the plugin uses Application Default Credentials automatically.
- Go to IAM & Admin → Service Accounts, create a service account (e.g.
Note: it can take a while after creating the app for the website index to populate.
AddSearch setup
- Sign up at addsearch.com and create an index for your site (AddSearch crawls it for you).
- In the AddSearch dashboard, find your index's public Site Key (Setup → Keywords & API).
- Enter the Site Key in the plugin settings. If your index is private, also enter your secret API Key.
Config file
Copy src/config.php to config/sitesearch.php to configure per environment. Keys under siteSettings are site handles:
<?php return [ 'siteSettings' => [ // Google Custom Search 'default' => [ 'provider' => 'gcs', 'apiKey' => getenv('GOOGLE_SEARCH_API_KEY'), 'searchEngineId' => getenv('GOOGLE_SEARCH_ENGINE_ID'), ], // Google Vertex AI Search 'fr' => [ 'provider' => 'vertex', 'projectId' => getenv('GOOGLE_CLOUD_PROJECT'), 'location' => 'global', 'engineId' => getenv('VERTEX_SEARCH_ENGINE_ID'), 'serviceAccountFile' => getenv('GOOGLE_APPLICATION_CREDENTIALS'), ], // AddSearch 'de' => [ 'provider' => 'addsearch', 'siteKey' => getenv('ADDSEARCH_SITE_KEY'), 'addsearchApiKey' => getenv('ADDSEARCH_API_KEY'), // optional, private indices only ], ], ];
The legacy single-site format (top-level apiKey/searchEngineId, Google Custom Search only) is still supported.
Usage
In your twig template, retrieve search results by passing your search query, then iterate over them:
{% set response = craft.siteSearch.performSearch('query terms') %}
The response has the same shape for every provider:
| Property | Description |
|---|---|
page, perPage, start, end, totalResults |
Pagination info |
results |
Array of results: title, snippet, htmlSnippet, link, image, thumbnail |
raw |
The provider's decoded raw response, for provider-specific data |
Full signature: performSearch(terms, page = 1, perPage = 10, extra = []). extra is merged into the provider request (e.g. Vertex request fields, AddSearch or Custom Search query params).
By default an exception is thrown if the provider returns an error; call craft.siteSearch.setThrowOnFailure(false) first to log a warning and get the error response back instead.
Google Custom Search result limit: the Custom Search JSON API only serves the first 100 results of a query (and at most 10 per page), so with the gcs provider totalResults is capped at 100 to keep pagination from linking to pages Google won't serve. Google's uncapped match estimate is still available at response.raw.queries.request[0].totalResults if you want to display it (e.g. "About 52,000 results").
Here is a complete example with pagination:
{% extends "_layout" %}
{% set query = craft.request.getParam('q') %}
{% set page = craft.request.getParam('page') ?: '1' %}
{% set title = "Search" %}
{% if query %}
{% set response = craft.siteSearch.performSearch(query, page) %}
{% set title = query ~ " - Search" %}
{% set totalPages = ceil(response.totalResults / response.perPage) %}
{% endif %}
{% block content %}
<div class="main">
<h1>Search</h1>
<form class="search">
<div class="text">
<input type="search" name="q" placeholder="Search" value="{{ query }}">
</div>
<div class="submit">
<input type="submit" value="Search">
</div>
</form>
{% if query %}
{% if response.results | length %}
<div class="intro">
<p>
Showing {{ response.start }}–{{ response.end }} of {{ response.totalResults }} results for <strong>{{ query }}</strong>
</p>
</div>
<ul class="listing">
{% for result in response.results %}
<li>
<h3>
<a href="{{ result.link }}">
{{ result.title | raw }}
</a>
</h3>
{% if result.thumbnail | length %}
<img src="{{ result.thumbnail }}" width="80" style="float: left; margin: 0 1em 1em 0" />
{% endif %}
<a class="url" href="{{ result.link }}">{{ result.link }}</a>
<p class="summary">
{{ result.htmlSnippet | raw }}
</p>
</li>
{% endfor %}
</ul>
{% if totalPages > 1 %}
<div class="meta paginator">
{% if page > 1 %}
<a href="{{ url('search', {q:query, page:(page-1)}) }}" class="prev">Previous</a>
{% endif %}
{% if page < totalPages %}
<a href="{{ url('search', {q:query, page:(page+1)}) }}" class="next">Next</a>
{% endif %}
</div>
{% endif %}
{% else %}
<div class="info">
<p>
Your search for “{{ query }}” didn’t return any results.
</p>
</div>
{% endif %}
{% endif %}
</div>
{% endblock %}
Upgrading from v2
v3 renames the plugin from Google Custom Search (imarc/craft-googlecustomsearch) to Site Search (imarc/craft-sitesearch) and supports Craft CMS 4 and 5:
composer remove imarc/craft-googlecustomsearch && composer require imarc/craft-sitesearch- Install the Site Search plugin in the Control Panel (or
php craft plugin/install sitesearch). Your existing Google Custom Search settings are copied over automatically during install. craft.googlecustomsearchstill works but is deprecated — switch templates tocraft.siteSearchat your convenience. The result shape is unchanged (plus a newrawproperty).- If you had a
config/googlecustomsearch.php, rename it toconfig/sitesearch.php. - Uninstall/remove the old plugin if it's still listed.
Credits
Brought to you by Imarc