Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(plugin): add siteId and branch params support #60

Merged
merged 3 commits into from
Oct 2, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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`.
Jerska marked this conversation as resolved.
Show resolved Hide resolved

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);
Jerska marked this conversation as resolved.
Show resolved Hide resolved
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