Toolsby Spectral Web Services

DocsAdvanced Search

Advanced Search configuration

Getting Advanced Search running on a Ghost site in six steps, then the reference — what gets indexed, the settings, the embed's attributes, and what to check when results look wrong.

Advanced Search replaces Ghost's built-in search with one that reads the whole body of every post, keeps itself current, and knows about your tags and authors. It runs on your own Algolia account, so the setup has a stretch at Algolia in the middle of it.

Allow about fifteen minutes for a site you've never set up before. Most of that is making the Algolia account.

Get it running

  1. Connect your Ghost site. If you haven't added your site to the dashboard yet, do that first — it needs a Ghost custom integration and takes a couple of minutes. Connect your Ghost site has the steps. Search needs a full Admin API key, because it registers its own webhooks. 1:43
  2. Make an Algolia account and upgrade to Grow. Sign up at algolia.com and verify your email. Algolia will then offer to walk you through importing data and building a UI — skip all of it; this tool does that work. You only need to reach the dashboard. Once there, click Upgrade and choose Grow. Don't stay on Build: it caps how long a single record can be, which real posts exceed, and it requires Algolia's branding on your search, which this embed doesn't display. Grow's free monthly allowance covers most sites — see what it costs. 3:45
  3. Copy three values from Algolia into the Search page. Algolia shows your keys right after the upgrade, and again any time under Settings → API Keys. You need the Application ID, the Write API Key and the Search API Key. The Write key is hidden until you click to reveal it, and Algolia warns you not to use it in frontend code — that's fine, it never leaves our server. Tick Search enabled, decide whether to index tags and authors, and press Save. 7:15
  4. Set up the webhooks, then index your content. Click Set up search integration — that registers the Ghost webhooks that keep the index current from now on, and it's much faster than making eleven of them by hand. Then click Index content, which is what puts your existing posts into the index in the first place, despite reading like a repair tool. It takes a moment on a small site and a good while on a few thousand posts. 8:44
  5. Paste the snippet into Ghost. Copy the snippet from the Install on your site panel and paste it into Ghost's Settings → Code injection → Site footer, then save. On a standard Ghost theme that's all: the snippet takes over your theme's existing search button. 10:32
  6. Try it. Open your site and press its search button. You should get the new search, with results as you'd expect. 11:56

Everything below is reference — the settings in detail, what does and doesn't get indexed, the attributes the embed accepts, and what to check when results look wrong.

Rather watch than read? The walkthrough does the whole job on a real Ghost site, Algolia account included, in thirteen minutes. One thing it shows has since changed: between the webhooks and indexing it clicks a set up search index button, which is now called Reset index settings to recommended and isn't a setup step any more — indexing creates the indices for you.

Your Algolia account, and what it costs

The index lives in your own Algolia application, not ours, which is why the account is yours to make. Grow's allowance is 10,000 search requests a month at no charge, and how far that goes depends on one setting:

  • Search when the reader presses Enter (the default) spends one request per search, so the allowance is 10,000 actual searches.
  • Search as they type (search-as-you-type, below) spends roughly five to ten requests for what a reader would call one search.

Plenty of sites fit either way. Check Algolia's current terms when you sign up rather than trusting this paragraph — they set the numbers, not us.

Three values go into the Search page, all from Algolia's Settings → API Keys:

FieldWhat to pasteNotes
Algolia App IDThe Application IDIdentifies your Algolia application. The Image Library uses the same one.
Algolia Write API keyThe Write API KeyNot the Admin API Key sitting beside it in Algolia — the Write key is the one needed here, and it can do less. Stored encrypted and never shown again. To rotate it, paste a new key over the field; leaving it blank keeps the saved one.
Algolia Search-only API keyThe Search API KeyPublic by design: it's what the search on your site queries with, restricted further before it ships (see Installing on your site).

Only running the Image Library? It reads these same credentials, and its docs list exactly which of the steps on this page it needs.

What gets indexed, and what never is

Every published post and page: the title, the headings, the full body text, the custom excerpt, the feature image's alt text and caption, and the names of its public tags. Long posts are split into one record per heading, so a match deep in a 4,000-word story still ranks. Results show each post once, with its best-matching section.

Never indexed:

  • Drafts and scheduled posts. A post enters the index when it's published and leaves when it's unpublished or deleted.
  • Anything tagged #no-index. Add the tag before publishing and the post or page is skipped. On something already indexed, the tag stops future updates but doesn't remove the old records — see below.
  • Internal tags, the ones whose names start with #. They never appear on a result or in the tags index.

Members-only and paid posts are indexed. A result shows their title, excerpt, image, author and date, and the key your site searches with can't return a post's body at all. The click lands on your paywall, which makes search a quiet signup prompt.

Staff profiles. Tag a page #staff-profile and, with Index authors on, its body is folded into the author record of whoever is set as the page's author, so a search for something in the bio finds the person. The page itself doesn't appear as a page result. Unpublish or delete it and that text is cleared from the author again.

The three checkboxes

  • Search enabled. The master switch for the webhooks. While it's off, Ghost's publish, edit and delete events are ignored and the index stays as it was; the Image Library, if it's on, still gets its own half of those events. The search on your site keeps working either way, since it talks to Algolia, not to this dashboard.
  • Index tags. Keeps a tags index (the name and description of every public tag) and gives the search modal a Tags section.
  • Index authors. Keeps an authors index (name, bio, location, and the staff profile page described above) and gives the modal an Authors section. Worth it for a multi-author newsroom; not worth it if one person writes everything.

The two index checkboxes are also written into the install snippet as enable-tags and enable-authors, so copy the snippet again after changing them. Press Save after any change on this form.

Keeping the index current

Set up search integration registers eleven webhooks on your Ghost site, one per event that should change the index. It needs the Ghost Admin API key from Site settings, which has to come from a custom integration, because that's where Ghost keeps webhooks. Running it again is safe: an event that's already registered is left alone.

Ghost eventWhat happens
post.published, post.published.editedThe post is indexed, or re-indexed from scratch.
post.unpublished, post.deletedThe post's records are removed.
page.published, page.published.editedSame, for pages. A staff profile page updates its author's record instead.
page.unpublished, page.deletedThe page's records are removed.
tag.added, tag.editedThe tag's record is written, when Index tags is on.
tag.deletedThe tag's record is removed.

Every webhook is signed with the site's Search secret. If you'd rather create them by hand, or need to check one, Show me how to create webhooks manually lists each event with its target URL, and the reveal control above it shows the secret. That secret belongs to Search alone, so rotating it can't break another tool's webhooks.

These webhooks cover what you do in the Ghost editor. They do not fire for bulk changes or API writes — the commonest cause of a search index that disagrees with the site, and the first thing to check under When search results look wrong.

Indexing, resetting and clearing

Index content walks every published post and page, and every public tag and author when those indices are on, and writes them all, page by page, with progress shown on the button. It's how content gets into a new index in the first place, and how you repair one that has drifted. It's safe to repeat, and it never removes anything that's still published.

Clear indices empties the posts, tags and authors indices. Pair it with Index content to rebuild from scratch when something is in the index that shouldn't be — a deleted post that still appears, say. The Image Library's images index is deliberately out of reach here: it holds notes nothing else can restore.

Reset index settings to recommended is not a setup step, despite what the walkthrough video shows. A missing index is created with the recommended settings the first time anything is written to it, so this button exists only to repair an index whose settings look wrong — and it overwrites anything you've customized in the Algolia dashboard.

Installing on your site

Once an App ID and search-only key are saved, the Search page shows an Install on your site panel. Paste its snippet into Ghost's Settings → Code injection → Site footer. It has three parts:

  1. A <script> that loads the search embed, pinned to one version by an integrity hash. Old snippets keep working when a new version ships; paste a fresh one to move to it.
  2. The <sws-search> tag, already filled with your App ID, a restricted key, your site's name as the title, and the tag and author settings.
  3. A few lines that take over your theme's own search button, anything marked data-ghost-search, which is how Ghost's official themes mark it, so pressing it opens this search instead of Ghost's. If your theme marks its button differently, change that selector in the snippet.

The restricted search key in the tag is derived from your search-only key in your browser, which needs an HTTPS page (if the panel says so, reload over HTTPS). It can query only the three search indices and return only the fields a result shows, so the full text of a post never leaves Algolia. That's what lets members-only posts be searchable without being readable. Change the search-only key at Algolia and the snippet changes with it, so paste it again.

To open the search from somewhere else, a link or a keyboard shortcut, call document.getElementById('sws').open().

Attributes on <sws-search>

The snippet sets title, theme, enable-tags and enable-authors for you. Add any of the others to the tag to change how the modal behaves. Attributes are read once, when the page loads.

AttributeDefaultWhat it does
titleyour site's nameThe heading at the top of the modal.
themeautolight, dark, or auto to follow the reader's device setting.
layouttabstabs puts Posts, Authors and Tags on a tab strip. stacked shows all three at once, authors and tags capped at four each.
show-imagetrue"false" hides post and author images.
show-authortrue"false" hides the byline on post results.
show-datetrue"false" hides the published date on post results.
image-size100Thumbnail size in pixels. Ghost's resized copies are requested at that size, so small stays small.
pub-date-filterfalse"true" adds a date-range filter, folded away until the reader opens it.
search-as-you-typefalse"true" searches as the reader types, from three characters on, instead of when they press Enter. Costs roughly five to ten Algolia requests per search rather than one.
enable-tags, enable-authorstrue"false" removes that section. The snippet sets these from the checkboxes.
relative-linksfalse"true" links each result by its path rather than the full address Ghost recorded, so a click stays on whatever host the reader is on. For a site that's also served under a second domain, such as an Institutional Access subdomain.

The modal takes its accent colour (buttons, the active tab, focus rings) from your theme's --ghost-accent-color, so it matches your site with no styling. To use a different colour, set --sws-accent-color on the sws-search element in your theme's CSS.

When search results look wrong

Posts I imported, bulk-published or bulk-deleted are wrong

This is the big one. Webhooks fire for changes made in the Ghost editor, and not for bulk ones. Posts created, updated or deleted through the Ghost API, or by a bulk action — including the ones in Ghost's own post list — don't fire them, so the index never hears about the change. Imported posts don't appear; bulk-deleted ones linger in results.

After an import, a bulk publish or unpublish, a bulk delete, or a tag sweep, run Clear indices and then Index content. Nothing about it is risky and it's the fix for almost every "the index disagrees with my site" report.

Search finds nothing at all

Usually the index is empty because Index content hasn't been run — setting up the webhooks doesn't backfill anything, it only handles what happens next. Run Index content and watch the progress on the button.

If it has been run, check in the Algolia dashboard under Search that your posts index exists and has records in it. Records there but nothing on your site is an install problem, not an index one — see below.

Algolia shows my indices but they're empty

Expected, if all you've done is create them. The indices appear before there's anything in them; Index content is what fills them.

A post I tagged #no-index is still in results

The tag stops future updates but doesn't retract what's already indexed. Either unpublish and republish the post, which fires the removal webhook, or run Clear indices then Index content to rebuild from what's published now.

My site's search button still opens Ghost's search

The snippet takes over any button marked data-ghost-search, which is what Ghost's official themes use. A theme that marks its search button some other way needs that selector changed in the snippet's last few lines. Failing that, wire your own control to document.getElementById('sws').open().

The install panel says to reload over HTTPS

The restricted key in the snippet is derived in your browser using an API that only exists on a secure page. Open the dashboard over https:// and the snippet renders. It deliberately won't fall back to shipping your unrestricted search key.

Algolia rejects records as too long

You're on the Build plan. Its record-size limit is below what an ordinary post needs. Upgrade to Grow and run Index content again.

I'm using more Algolia requests than expected

Check whether search-as-you-type is on: it spends five to ten requests for each search a reader would count as one. Turning it off, so search runs when they press Enter, cuts the count by most of that.

Results are stale after changing the search-only key

The snippet embeds a restricted key derived from the search-only key. Change it at Algolia and the old snippet stops working, so copy the snippet again and paste it back into Code injection.

Contributor access

If you give a contributor a Search grant (Site settings → Users), use lets them open the page and run Index content; manage lets them change everything else.