I wrote about Ghost before, the platform on which this blog runs. I loved it, and still do, liking the minimalistic approach having just the features necessary for a blog needs and nothing more. There is only one thing I believe a blog needs and Ghost doesn't provide out of the box: search!
Having some experience with Azure Search, I decided to try and get the content of this blog into an Azure Search index.

First steps are easy, go into the Azure Portal and create an Azure Search instance. I chose the Free instance (only 1 per subscription allowed), which suffices the current needs for this blog. Store the name and the Search API Admin Key for later use.
You'll also need to create an Azure Function (v2, .NET Core), based on the HttpTrigger template, and also add a function.proj file to it. You can find the code for both the function.proj and run.csx file in a Gist.

The code needs some variables to be set on the top of the Function, most of them straightforward:

  • BlogUrl, like https://blog.yannickreekmans.be
  • SearchServiceName, saved when you created the Search instance
  • SearchAdminApiKey, saved when you created the Search instance

The values for ClientId and ClientSecret are a little less easy to find. The Ghost v0.1 API isn't really meant to be used from an external site or service, and doesn't allow to create additional ClientId and ClientSecret values so I decided to reuse those that are provided for the frontend to access the API.In Ghost Admin, under Labs, make sure the "Public API" checkbox is ticked. On the front page of your blog, check the source code and find something similar to the following code and use those values for ClientId and ClientSecret:

<<code block removed>>

Since the original publication of this post, the Ghost team made the Content API (v1.0) publically available and supported with Ghost v2.10.0. The order of executing things has been changed a bit.
The last value necessary in the Azure Function (ContentAPIKey) requires some setup in Ghost first.

We need to make sure the Azure Function runs whenever something happens to your Ghost blog. Luckily, in the recent versions of Ghost (I'm running 2.9.1 2.11.0 at the time of writing) webhook functionality is provided exactly for this purpose:

  • Open Ghost Admin panel, and open the Integrations tab
  • Underneath Custom Integrations, click Add custom integration and give it a name (I named mine Azure Search)
  • On the new page, there will be a field named Content API Key, you will need to copy this and add it to your Azure Function
  • Underneath Webhooks, add a new one. Provide a name (like Index Rebuild), select Site Changed (Rebuild) for event and put the URL for the Azure Function in the Target URL field.

Ghost will now call the Azure Function, everytime something changes on your blog and that function will keep the search index fresh. The Azure Function reads all the posts in the database with the API, transforms them into a format specific for Azure Search and inserts them in the index. Since Ghost doesn't provide a way to "know" when a post is deleted (and thus has to be removed from the index), I decided to drop the index and recreate it every time the Azure Function runs.

Now that the data is in there, it's a piece of cake to use the Search API and create a UI in the theme to visualize the search results. Happy searching!

Ghost Search Azure Functions