Skip to content

Commit ba378e8

Browse files
authored
feat(react-hooks): add insights (#382)
* feat(react-hooks): add insights note that it uses algolia/react-instantsearch#3476, so the version will need to be updated again before the docs are released This also doesn't use useInstantSearch yet, that can be done in the future * update version
1 parent f0a1dfe commit ba378e8

11 files changed

Lines changed: 9211 additions & 0 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# production
12+
/build
13+
14+
# misc
15+
.DS_Store
16+
.env.local
17+
.env.development.local
18+
.env.test.local
19+
.env.production.local
20+
21+
npm-debug.log*
22+
yarn-debug.log*
23+
yarn-error.log*
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# algolia-insights
2+
3+
_This project was generated with [create-instantsearch-app](https://github.com/algolia/create-instantsearch-app) by [Algolia](https://algolia.com)._
4+
5+
## Get started
6+
7+
To run this project locally, install the dependencies and run the local server:
8+
9+
```sh
10+
npm install
11+
npm start
12+
```
13+
14+
Alternatively, you may use [Yarn](https://http://yarnpkg.com/):
15+
16+
```sh
17+
yarn
18+
yarn start
19+
```
20+
21+
Open http://localhost:3000 to see your app.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"name": "algolia-insights",
3+
"version": "0.1.0",
4+
"private": true,
5+
"dependencies": {
6+
"algoliasearch": "^4.13.0",
7+
"instantsearch.css": "^7.4.5",
8+
"instantsearch.js": "^4.40.5",
9+
"react": "^18.1.0",
10+
"react-dom": "^18.1.0",
11+
"react-instantsearch-hooks-web": "^6.26.0",
12+
"react-scripts": "5.0.1"
13+
},
14+
"scripts": {
15+
"start": "react-scripts start",
16+
"build": "react-scripts build"
17+
},
18+
"eslintConfig": {
19+
"extends": [
20+
"react-app",
21+
"react-app/jest"
22+
]
23+
},
24+
"browserslist": {
25+
"production": [
26+
">0.2%",
27+
"not dead",
28+
"not op_mini all"
29+
],
30+
"development": [
31+
"last 1 chrome version",
32+
"last 1 firefox version",
33+
"last 1 safari version"
34+
]
35+
}
36+
}
1.88 KB
Loading
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="utf-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
7+
<meta name="theme-color" content="#000000">
8+
9+
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.png">
10+
11+
<!--
12+
Do not use @7 in production, use a complete version like x.x.x, see website for latest version:
13+
https://community.algolia.com/react-instantsearch/Getting_started.html#load-the-algolia-theme
14+
-->
15+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/algolia-min.css">
16+
17+
<title>algolia-insights</title>
18+
<script>
19+
var ALGOLIA_INSIGHTS_SRC = "https://cdn.jsdelivr.net/npm/search-insights@1.7.1";
20+
!function(e,a,t,n,s,i,c){e.AlgoliaAnalyticsObject=s,e[s]=e[s]||function(){
21+
(e[s].queue=e[s].queue||[]).push(arguments)},i=a.createElement(t),c=a.getElementsByTagName(t)[0],
22+
i.async=1,i.src=n,c.parentNode.insertBefore(i,c)
23+
}(window,document,"script",ALGOLIA_INSIGHTS_SRC,"aa");
24+
25+
aa('init', {
26+
appId: 'B1G2GM9NG0',
27+
apiKey: 'aadef574be1f9252bb48d4ea09b5cfe5',
28+
});
29+
</script>
30+
</head>
31+
32+
<body>
33+
<noscript>
34+
You need to enable JavaScript to run this app.
35+
</noscript>
36+
37+
<div id="root"></div>
38+
</body>
39+
40+
</html>
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
em {
2+
background: cyan;
3+
font-style: normal;
4+
}
5+
6+
.header {
7+
display: flex;
8+
align-items: center;
9+
min-height: 50px;
10+
padding: 0.5rem 1rem;
11+
background-image: linear-gradient(to right, #8e43e7, #00aeff);
12+
color: #fff;
13+
margin-bottom: 1rem;
14+
}
15+
16+
.header a {
17+
color: #fff;
18+
text-decoration: none;
19+
}
20+
21+
.header-title {
22+
font-size: 1.2rem;
23+
font-weight: normal;
24+
}
25+
26+
.header-title::after {
27+
content: ' ▸ ';
28+
padding: 0 0.5rem;
29+
}
30+
31+
.header-subtitle {
32+
font-size: 1.2rem;
33+
}
34+
35+
.container {
36+
max-width: 1200px;
37+
margin: 0 auto;
38+
padding: 1rem;
39+
}
40+
41+
.search-panel {
42+
display: flex;
43+
}
44+
45+
.search-panel__filters {
46+
flex: 1;
47+
}
48+
49+
.search-panel__results {
50+
flex: 3;
51+
}
52+
53+
.searchbox {
54+
margin-bottom: 2rem;
55+
}
56+
57+
.pagination {
58+
margin: 2rem auto;
59+
text-align: center;
60+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import {
2+
Highlight,
3+
Hits,
4+
InstantSearch,
5+
Pagination,
6+
RefinementList,
7+
SearchBox,
8+
} from 'react-instantsearch-hooks-web';
9+
import algoliasearch from 'algoliasearch/lite';
10+
11+
import './App.css';
12+
import { Insights } from './Insights';
13+
14+
const searchClient = algoliasearch(
15+
'B1G2GM9NG0',
16+
'aadef574be1f9252bb48d4ea09b5cfe5'
17+
);
18+
19+
function App() {
20+
return (
21+
<div className="container">
22+
<InstantSearch searchClient={searchClient} indexName="demo_ecommerce">
23+
<Insights />
24+
<div className="search-panel">
25+
<div className="search-panel__filters">
26+
<RefinementList attribute="brand" />
27+
</div>
28+
29+
<div className="search-panel__results">
30+
<SearchBox className="searchbox" placeholder="Search" />
31+
<Hits hitComponent={Hit} />
32+
33+
<div className="pagination">
34+
<Pagination />
35+
</div>
36+
</div>
37+
</div>
38+
</InstantSearch>
39+
</div>
40+
);
41+
}
42+
43+
function Hit({ hit, sendEvent }) {
44+
return (
45+
<div>
46+
<Highlight attribute="name" hit={hit} />
47+
<button
48+
type="button"
49+
onClick={() => {
50+
sendEvent('click', hit, 'Product Added');
51+
}}
52+
>
53+
Add to cart
54+
</button>
55+
<button
56+
type="button"
57+
onClick={() => {
58+
sendEvent('conversion', hit, 'Product Ordered');
59+
}}
60+
>
61+
Order
62+
</button>
63+
</div>
64+
);
65+
}
66+
67+
export default App;
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { createInsightsMiddleware } from 'instantsearch.js/es/middlewares';
2+
import { useEffect } from 'react';
3+
import { useConnector } from 'react-instantsearch-hooks-web';
4+
5+
const connectMiddleware = (renderFn, unmountFn) => (widgetParams) => ({
6+
init(initOptions) {
7+
renderFn(
8+
{
9+
...this.getWidgetRenderState(initOptions),
10+
instantSearchInstance: initOptions.instantSearchInstance,
11+
},
12+
true
13+
);
14+
},
15+
16+
render(renderOptions) {
17+
const renderState = this.getWidgetRenderState(renderOptions);
18+
19+
renderFn(
20+
{
21+
...renderState,
22+
instantSearchInstance: renderOptions.instantSearchInstance,
23+
},
24+
false
25+
);
26+
},
27+
28+
getWidgetRenderState(renderOptions) {
29+
return {
30+
use: (...args) => renderOptions.instantSearchInstance.use(...args),
31+
unuse: (...args) => renderOptions.instantSearchInstance.unuse(...args),
32+
widgetParams,
33+
};
34+
},
35+
36+
dispose() {
37+
unmountFn();
38+
},
39+
});
40+
41+
export function Insights() {
42+
const { use, unuse } = useConnector(connectMiddleware);
43+
44+
useEffect(() => {
45+
const middleware = createInsightsMiddleware({
46+
insightsClient: window.aa,
47+
});
48+
49+
use(middleware);
50+
51+
return () => unuse(middleware);
52+
}, [use, unuse]);
53+
54+
return null;
55+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
body,
2+
h1 {
3+
margin: 0;
4+
padding: 0;
5+
}
6+
7+
body {
8+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica,
9+
Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import React from 'react';
2+
import { render } from 'react-dom';
3+
import './index.css';
4+
import App from './App';
5+
6+
render(
7+
<React.StrictMode>
8+
<App />
9+
</React.StrictMode>,
10+
document.getElementById('root')
11+
);

0 commit comments

Comments
 (0)