# Algolia search

> For the complete documentation index, see [llms.txt](https://www.jetbrains.com/help/writerside/llms.txt).

[Algolia](https://www.algolia.com/) is a search-as-a-service API that Writerside supports out of the box.

> **Note:**
> The free plan is limited to 10,000 search requests per month and 1 million total records. You can compare plans at [https://www.algolia.com/pricing/](https://www.algolia.com/pricing/).

Procedure: Create Algolia application and search index

1. Sign up for an [Algolia](https://www.algolia.com/) account.

2. On the Algolia [applications](https://www.algolia.com/account/applications) page, click Create Application.

Configure application parameters, select a region for your datacenter, and create the application.

3. On the Algolia application page, go to `Data sources | Indices` and click Create Index.

Provide an informative name and create the index.

4. On the index page, go to `Configuration | Facets`, and click Add an attribute under Attributes for faceting.

Add two attributes for faceting: `product` and `version`. Make sure both are searchable.

> **Note:**
> Do not add them to the list of Searchable attributes, only mark them as searchable in the Attributes for faceting list.

5. Click Review and Save Settings and confirm.

Procedure: Add Algolia parameters to Writerside build configuration

1. In your documentation project, open  `[buildprofiles.xml](buildprofiles-xml.html)` .

2. Under `[&lt;variables&gt;](buildprofiles-xml.html#variables)`, specify the following:

`[&lt;algolia-id&gt;](buildprofiles-xml.html#algolia-id)`
: Algolia application ID

`[&lt;algolia-index&gt;](buildprofiles-xml.html#algolia-index)`
: Algolia index name

`[&lt;algolia-api-key&gt;](buildprofiles-xml.html#algolia-api-key)`
: Algolia Search-Only API Key

`[&lt;algolia-show-logo&gt;](buildprofiles-xml.html#algolia-show-logo)`
: Show the Algolia logo in search results if you are using their free plan to comply with [Algolia's usage terms](https://support.algolia.com/hc/en-us/articles/4406981826065-Do-I-need-to-display-the-Algolia-logo-when-on-a-free-plan).

For example:

```XML
<variables>
    <algolia-id>TGW4GIW73X</algolia-id>
    <algolia-index>index_name</algolia-index>
    <algolia-api-key>29effd68f91893202311a653263f1fb8</algolia-api-key>
    <algolia-show-logo>true</algolia-show-logo>
</variables>
```

> **Note:**
> You can find the application ID and API keys in your Algolia account settings under [API Keys](https://dashboard.algolia.com/account/api-keys).

3. Commit and push these changes, then build and publish the help instance with these configuration parameters.

Now your published help instance will have a search field that will send queries to the specified Algolia index using the provided API key.

## Upload your search index records to Algolia

To reply to search requests from your help, Algolia needs records in the specified search index. The Writerside builder collects them while building the help website as a separate archive named `algolia-indexes-HI.zip` or whatever your instance ID was instead of `HI`.

This archive contains JSON files, each with a JSON object representing a separate search index record. Usually, there is one record per topic, but some bigger topics can be split into multiple records. Although Algolia lets you upload these JSON files with records to the search index manually, there are usually a lot of them, and you probably want to automate it anyway. The best approach is to add a step to your build and publication process that will upload the JSON files from the archive.

TeamCity:

Procedure:

1. If you do not yet have a TeamCity configuration for building your help artifacts, set it up as described in [Build on TeamCity Cloud](build-on-teamcity.html).

2. Create a separate build configuration for publishing search indexes to your Algolia application.

Configure it to use the following Docker image:

```
registry.jetbrains.team/p/writerside/builder/algolia-publisher:latest
```

This image will run the `help-publication-agent` script.

3. Create a Command line type step with the following command:

```BASH
env "algolia-key=${'$'}ALGOLIA_KEY" java -jar /opt/builder/help-publication-agent.jar \
update-index \
--application-name ${'$'}ALGOLIA_APP_NAME \
--index-name ${'$'}ALGOLIA_INDEX_NAME \
--product ${'$'}CONFIG_JSON_PRODUCT \
--version ${'$'}CONFIG_JSON_VERSION \
--index-directory algolia-index/ \
2>&1 | tee algolia-update-index-log.txt
```

4. In General Settings, in the Artifact path field, add `algolia-update-index-log.txt` to write logs.

5. In Dependencies, add artifacts produced by your help build configuration: `webhelp.zip` and `algolia-indexes-*.zip!** => algolia-index`. This action unpacks the ZIP archive with indexes to `algolia-index`.

6. In Parameters, add the following environment variables:

env.ALGOLIA_APP_NAME
: Algolia application ID

env.ALGOLIA_INDEX_NAME
: Name of Algolia index

env.ALGOLIA_KEY
: Algolia Admin API Key.
:
:
:
: This is a private key. Set the type of this parameter to `Password`, so that users without proper permissions will not see its value.

env.CONFIG_JSON_PRODUCT
: Help instance ID from the  [tree file](help-modules.html#tree-file)  or the value of the `web-path` attribute specified in  `[writerside.cfg](writerside-cfg.html)`  if it is different from the ID

env.CONFIG_JSON_VERSION
: Help instance version (usually the same as the branch name) specified in  `[writerside.cfg](writerside-cfg.html)`

> **Note:**
> You can find the application ID and API keys in your Algolia account settings under [API Keys](https://dashboard.algolia.com/account/api-keys).

7. Save the build configuration settings and click Deploy. After it finishes successfully, go to the index in your Algolia account and make sure that the index records have really been uploaded.

GitHub Actions:

Procedure:

1. In your repository on GitHub, go to `Settings | Secrets and variables | Actions`, and add a New repository secret with the name `ALGOLIA_KEY` and the value of the Admin API Key from your Algolia account.

> **Note:**
> You can find the application ID and API keys in your Algolia account settings under [API Keys](https://dashboard.algolia.com/account/api-keys).

2. Set up a GitHub Actions workflow that builds your help artifacts as described in [Build and publish on GitHub](deploy-docs-to-github-pages.html). More specifically, make sure that you add a `publish-indexes` job to the workflow as described in [Upload search indexes](deploy-docs-to-github-pages.html#search).

After you run this workflow successfully and the `publish-indexes` job finishes, go to the index in your Algolia account and make sure that the index records have really been uploaded.

GitLab CI:

Procedure:

1. In your repository on GitLab, go to `Settings | CI/CD | Variables`, and add a new CI/CD Variable called `ALGOLIA_KEY` with the Algolia Admin API Key from your Algolia account.

> **Note:**
> You can find the application ID and API keys in your Algolia account settings under [API Keys](https://dashboard.algolia.com/account/api-keys).
>
>
>
> Specify your private API key as a secret. The workflow will reference it via `${{ secrets.ALGOLIA_KEY }}`.
>
>
>
> Specify your private API key as a secret. The workflow will reference it via `$ALGOLIA_KEY`.

2. Set up a GitLab CI build pipeline that builds your help artifacts as described in [Build and publish on GitLab](deploy-docs-to-gitlab-pages.html). More specifically, make sure that you add a `publish-indexes` job to the workflow as described in [Upload search indexes](deploy-docs-to-gitlab-pages.html#search).

After you run this build pipeline successfully and the `publish-indexes` stage finishes, go to the index in your Algolia account and make sure that the index records have really been uploaded.

After you upload the index records to Algolia, you can check that search works in your published help. You will need to upload new search index records every time you publish a new help build.

## Algolia crawler

Algolia provides a hosted [crawler](https://www.algolia.com/products/features/crawler) that extracts content from your website, transforms it, and uploads as search index records to your Algolia account. You can use it instead of [uploading the index records collected by the builder](#upload-search-index) if this is more convenient for you, but do not use both methods at the same time.

> **Note:**
> Writerside does not support [DocSearch](https://docsearch.algolia.com/docs/what-is-docsearch/). This involves implementing a special frontend component, while a help instance built with Writerside already has a search component that operates on index records that are different from those used by DocSearch. The instructions here explain how to configure a custom crawler to collect index records in the supported format.

Procedure: Create crawler

1. On the [Algolia application page](https://dashboard.algolia.com), go to `Data sources | Crawler` and click Add new crawler.

> **Note:**
> You can only crawl content from domains you own. Add and verify a domain before creating a new crawler. For more information, see [Create a new crawler](https://www.algolia.com/doc/tools/crawler/getting-started/create-crawler/).

2. [Configure the crawler using the web editor](https://www.algolia.com/doc/tools/crawler/getting-started/crawler-configuration/).

Implement a function that will extract an array of JSON objects and return it as the value of the [recordExtractor](https://www.algolia.com/doc/tools/crawler/apis/configuration/actions/#parameter-param-recordextractor) parameter.

Here is a simple function that creates an array of index records:

```JS
recordExtractor: ({ $, url }) => {

    const records = [];

    const mainTitle = $("h1").text().trim();
    const headers = "h1, h2, h3, h4, h5, h6";

    $(headers).each((i, h) => {
        var urlString = url.href;
        const anchor = $(h).attr("id");

        if (anchor) {
          urlString += "#" + anchor;
        }

        const content = $(h).nextUntil(headers).text().trim();

        records.push({
            url: urlString,
            mainTitle: mainTitle,
            pageTitle: $(h).text().trim(),
            content: content,
            product: "hi"
        });
    });

    return records;
}
```

The function iterates over headers on a page and creates a separate index record for each one with the following fields:

`url`
: The URL where the index record should point.

`mainTitle`
: The main title on the page.

`pageTitle`
: The header of this specific record, like a chapter title.

`content`
: The main content of the search index record.

`product`
: The ID of the published [instance](instances.html). For example, the ID of the default `Help Instance` is `hi`. The index should have the `product` attribute for [faceting](https://www.algolia.com/doc/guides/managing-results/refine-results/faceting/). For information about adding facets to an index, see [Create Algolia application and search index](#create_algolia_index).

> **Note:**
> If your instance also has a [version](support-multiple-versions.html) configured, you will need to add a `version` field to the index records with the correct version number. And this attribute should be available for faceting and searchable, like `product`.

3. Run the crawler to collect index records.

> **Tip:**
> You can set up a [schedule](https://www.algolia.com/doc/tools/crawler/apis/configuration/schedule/) for regular automatic crawls or use the [Crawler API](https://www.algolia.com/doc/rest-api/crawler/) to run it after every publication.

4. If the published instance had [Algolia parameters](#add-search-to-config) pointing to the correct Algolia application, index, and API key when it was built, you should now be able to search against the index from your published help instance.

