Skip to content

Commit

Permalink
feat(frontend): add siteId & branch param support
Browse files Browse the repository at this point in the history
  • Loading branch information
Jerska committed Oct 2, 2020
1 parent 432b67a commit 0f51a2a
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 19 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ When it receives a build hook, the Algolia Crawler processes your website asynch
You can find information about your current crawler in the [Netlify deploy logs](https://docs.netlify.com/monitor-sites/logs/#deploy-log).

> Note: by default, we only build the `master` branch. We can however create one crawler (targeting one Algolia index) per Git branch, so that you can have, for example, a production index on `master` and development index on `develop`. You need to configure the [`branches` plugin input](./plugin#available-parameters) to enable this feature.
> If you're using our front-end library, you'll also need to [pass the correct branch](./frontend#using-multiple-branches) to the library parameters.
<img src="/docs/screenshots/deploy-logs.png?raw=true" alt="Netlify deploy logs.">

Expand Down
45 changes: 35 additions & 10 deletions frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ It's designed to be compatible with the index structure extracted by the [plugin
algoliasearchNetlify({
appId: '<YOUR_ALGOLIA_APP_ID>',
apiKey: '<YOUR_ALGOLIA_API_KEY>',
indexName: 'netlify_<YOUR_NETLIFY_SITE_ID>_<YOUR_BRANCH>',
siteId: '<YOUR_NETLIFY_SITE_ID>',
branch: '<YOUR_TARGET_GIT_BRANCH>'
});
</script>
```
Expand All @@ -24,19 +25,43 @@ Here's the full list of options with their default value.
```js
algoliasearchNetlify({
// Mandatory
appId: '<YOUR_ALGOLIA_APP_ID>', // Application ID (Can be found in https://www.algolia.com/api-keys)
apiKey: '<YOUR_ALGOLIA_API_KEY>', // Search api key (Can be found in https://www.algolia.com/api-keys)
indexName: 'netlify_<YOUR_NETLIFY_SITE_ID>_<YOUR_BRANCH>', // Index name (Can be found in https://www.algolia.com/indexes)
appId: '<YOUR_ALGOLIA_APP_ID>', // Application ID (Can be found in https://www.algolia.com/api-keys)
apiKey: '<YOUR_ALGOLIA_API_KEY>', // Search api key (Can be found in https://www.algolia.com/api-keys)
siteId: '<YOUR_NETLIFY_SITE_ID>', // Netlify Site ID (Can be found in https://crawler.algolia.com/admin/netlify)
branch: '<YOUR_TARGET_GIT_BRANCH>', // Target git branch, either a fixed one (e.g. 'master') or a dynamic one using `process.env.HEAD`. See "Using Multiple branches" in this doc.

// Optional
analytics: true, // Enable search analytics
analytics: true, // Enable search analytics
autocomplete: {
hitsPerPage: 5, // Amount of results to display
inputSelector: 'input[type=search]', // CSS selector of your search input(s)
hitsPerPage: 5, // Amount of results to display
inputSelector: 'input[type=search]', // CSS selector of your search input(s)
},
color: '#3c4fe0', // Main color
debug: false, // Debug mode (keeps the autocomplete open)
poweredBy: true, // Controls displaying the logo (mandatory with our FREE plan)
color: '#3c4fe0', // Main color
debug: false, // Debug mode (keeps the autocomplete open)
poweredBy: true, // Controls displaying the logo (mandatory with our FREE plan)
});
```

## Using multiple branches

If you've setup the plugin to index multiple branches using the `branches` plugin input, each configured branch has a dedicated index.
You'll also need to pass the information of which index you want to search in using the `branch` parameter of the integration.

To get access to the currently building branch, you can configure your build tool to forward the `HEAD` environment variable.
For instance, with [`webpack`'s environment plugin](https://webpack.js.org/plugins/environment-plugin/) configured to forward `HEAD`, you could simply pass `branch: process.env.HEAD`.

If you've configured your plugin to index only specific branches, you'll need to duplicate the logic here so that it picks the correct branch only when appropriate.
For instance, with `branches = ['main', 'develop', 'feat/*']`, and using webpack's environment plugin to inject `HEAD`, here's how the snippet could look like:

```js
const currentBranch = process.env.HEAD; // Injected by your build tool
let targetBranch = 'main';
if (currentBranch === 'develop' || currentBranch.startsWith('feat/')) {
targetBranch = currentBranch;
}
algoliasearchNetlify({
// ...
branch: targetBranch,
});
```

Expand Down
15 changes: 14 additions & 1 deletion frontend/src/AlgoliasearchNetlify.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { AutocompleteWrapper } from './AutocompleteWrapper';
import { Options } from './options';

const defaultOptions: Omit<Options, 'appId' | 'apiKey' | 'indexName'> = {
const defaultOptions: Omit<
Options,
'appId' | 'apiKey' | 'indexName' | 'siteId' | 'branch'
> = {
analytics: true,
autocomplete: {
hitsPerPage: 5,
Expand All @@ -20,11 +23,21 @@ class AlgoliasearchNetlify {
constructor(_options: Options) {
AlgoliasearchNetlify.instances.push(this);

// Temporary
const splitIndexName = (
indexName: string
): { siteId: string; branch: string } => {
const regexp = /^netlify_([0-9a-f-]+)_(.*)_all$/;
const [, siteId, branch] = indexName.match(regexp)!;
return { siteId, branch };
};

// eslint-disable-next-line no-warning-comments
// TODO: add validation
const options = {
...defaultOptions,
..._options,
...(_options.indexName && splitIndexName(_options.indexName)), // Temporary
autocomplete: {
...defaultOptions.autocomplete,
..._options.autocomplete,
Expand Down
14 changes: 11 additions & 3 deletions frontend/src/AutocompleteWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ const SM_WIDTH = 600;
class AutocompleteWrapper {
// All fields are private because they're just here for debugging
private client: SearchClient;
private indexName: string;
private index: SearchIndex;

private $inputs: HTMLInputElement[] = [];
private autocompletes: AutocompleteJs[] = [];

constructor({ appId, apiKey, indexName }: Options) {
constructor({ appId, apiKey, siteId, branch }: Options) {
this.client = this.createClient(appId, apiKey);
this.indexName = indexName;
const indexName = this.computeIndexName(siteId, branch);
console.log('Index name', indexName);
this.index = this.client.initIndex(indexName);
}

Expand Down Expand Up @@ -108,6 +108,14 @@ class AutocompleteWrapper {
this.autocompletes = autocompletes;
}

private computeIndexName(siteId: string, branch: string): string {
// Keep in sync with crawler code in /netlify/crawl
const cleanBranch = branch
.replace(/[^\p{L}\p{N}_.-]+/gu, '-')
.replace(/-{2,}/g, '-');
return `netlify_${siteId}_${cleanBranch}_all`;
}

private createClient(appId: string, apiKey: string): SearchClient {
const client = algoliasearch(appId, apiKey);
client.addAlgoliaAgent(`Netlify integration ${version}`);
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ export interface Options {
// Mandatory
appId: string;
apiKey: string;
indexName: string;

// Temporary
indexName?: string;
siteId: string;
branch: string;

// Optional
analytics: boolean;
Expand Down
2 changes: 1 addition & 1 deletion plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Plugin inputs can be set in `netlify.toml`. They're all optional.
- `branches` - _Default: `['master']`_ - List of branches the crawler should build.
By default, we only build your main branch, but this can be used to build multiple branches.
Each of those will have a dedicated Algolia index, named `netlify_<site-id>_<branch-name>_all`.
To target the right branch, you will need to inject the `HEAD` environment variable in your front-end code.
You will need to [target the right branch](../frontend#using-multiple-branches) in your front-end code.
Accepts star patterns too, like so:
- `*`: matches all branches
- `feat/*`: matches all branches starting with `feat/`
Expand Down
1 change: 1 addition & 0 deletions public/1.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<html>
<head>
<title>First test page</title>
<meta name="description" content="First test page description" />
</head>
<body>
<h2>First test page</h2>
Expand Down
1 change: 1 addition & 0 deletions public/2.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<html>
<head>
<title>Second test page</title>
<meta name="description" content="Second test page description" />
</head>
<body>
<h2>Second test page</h2>
Expand Down
9 changes: 6 additions & 3 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

<head>
<title>Algoliasearch Netlify Test Website</title>
<meta name="description" content="Algolia x Netlify testing website." />

<link rel="icon" href="/favicon.ico" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/necolas/normalize.css@8.0.1/normalize.css" />

Expand Down Expand Up @@ -145,9 +147,10 @@ <h2>Test content</h2>
type="text/javascript"></script>
<script type="text/javascript">
const DEFAULT_SOURCE = `algoliasearchNetlify({
appId: 'FHMV5EW9NC',
apiKey: 'aea9a7c4604b1e1a4d57fd29b2dc0a3f',
indexName: 'test-manual-index',
appId: '4C7VLPQA76',
apiKey: 'a9cfed5acb56143690b612167d89a1b5',
siteId: '9209706f-d5b7-46e2-bb88-5d6bedd2823f',
branch: 'master',
debug: true,
});`
.split('\n')
Expand Down

0 comments on commit 0f51a2a

Please sign in to comment.