Skip to content

Commit

Permalink
feat(Algolia Experiences): initial implementation (#6298)
Browse files Browse the repository at this point in the history
* feat(experience-management): add experience management

* test(experience-management): get info and rendering

* feat(api): use real api for configuration
  • Loading branch information
Haroenv authored Aug 30, 2024
1 parent 983f6a4 commit f2bebf0
Show file tree
Hide file tree
Showing 23 changed files with 1,598 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ jobs:
path: junit/jest/
- run:
name: Type Checking
command: yarn run type-check
command: yarn run type-check:v4

vue v3:
<<: *defaults
Expand Down
Binary file added examples/js/algolia-experiences/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
73 changes: 73 additions & 0 deletions examples/js/algolia-experiences/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Algolia Experiences demo</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/instantsearch.css@8/themes/satellite.min.css"
/>
<style>
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI',
Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue',
sans-serif;
}
main {
max-width: 80em;
margin: 0 auto;
}
.ais-Hits-list,
.ais-TrendingItems-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1em;
}
.ais-TrendingItems-item,
.ais-Hits-item {
padding: 0;
}
.ais-TrendingItems-item a,
.ais-Hits-item a {
width: 100%;
padding: 1.5em;
text-decoration: none;
color: inherit;
display: flex;
flex-direction: column;
}
.ais-TrendingItems-item img,
.ais-Hits-item img {
width: 100%;
height: 10em;
border-radius: 4px;
object-fit: contain;
}
.__flex {
display: flex;
gap: 1em;
justify-content: space-between;
}
.__bold {
font-weight: bold;
}
div:has(> .ais-Pagination) {
display: flex;
}
.ais-Pagination {
margin: 1em auto;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/algolia-experiences@1/dist/algolia-experiences.production.min.js"></script>
<meta
name="algolia-configuration"
content='{"appId":"F4T6CUV2AH","apiKey":"72d500963987bc97ff899d350a00f7a8"}'
/>
</head>
<body>
<main>
<h2>Buy historical books now!</h2>
<div data-experience-id="category:historical"></div>
</main>
</body>
</html>
73 changes: 73 additions & 0 deletions examples/js/algolia-experiences/local.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Algolia Experiences local demo</title>
<link
rel="stylesheet"
href="/packages/instantsearch.css/themes/satellite-min.css"
/>
<style>
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI',
Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue',
sans-serif;
}
main {
max-width: 80em;
margin: 0 auto;
}
.ais-Hits-list,
.ais-TrendingItems-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 1em;
}
.ais-TrendingItems-item,
.ais-Hits-item {
padding: 0;
}
.ais-TrendingItems-item a,
.ais-Hits-item a {
width: 100%;
padding: 1.5em;
text-decoration: none;
color: inherit;
display: flex;
flex-direction: column;
}
.ais-TrendingItems-item img,
.ais-Hits-item img {
width: 100%;
height: 10em;
border-radius: 4px;
object-fit: contain;
}
.__flex {
display: flex;
gap: 1em;
justify-content: space-between;
}
.__bold {
font-weight: bold;
}
div:has(> .ais-Pagination) {
display: flex;
}
.ais-Pagination {
margin: 1em auto;
}
</style>
<script src="/packages/algolia-experiences/dist/algolia-experiences.development.js"></script>
<meta
name="algolia-configuration"
content='{"appId":"F4T6CUV2AH","apiKey":"72d500963987bc97ff899d350a00f7a8"}'
/>
</head>
<body>
<main>
<h2>Buy historical books now!</h2>
<div data-experience-id="category:historical"></div>
</main>
</body>
</html>
19 changes: 19 additions & 0 deletions examples/js/algolia-experiences/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "example-algolia-experiences",
"version": "1.0.0",
"private": true,
"scripts": {
"start": "BABEL_ENV=parcel parcel index.html local.html",
"build": "BABEL_ENV=parcel parcel build index.html local.html --public-url .",
"website:examples": "BABEL_ENV=parcel parcel build index.html local.html --public-url . --dist-dir=../../../website/examples/js/algolia-experiences"
},
"browserslist": "firefox 68, chrome 78, IE 11",
"devDependencies": {
"@babel/core": "7.15.5",
"@parcel/core": "2.10.0",
"@parcel/packager-raw-url": "2.10.0",
"@parcel/transformer-webmanifest": "2.10.0",
"parcel": "2.10.0",
"typescript": "5.5.2"
}
}
13 changes: 11 additions & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// @ts-check

/** @type {any} */
const packagejson = require('./package.json');
/** @type {'3' | '4' | '5'} */
const algoliaSearchMajor =
packagejson.devDependencies.algoliasearch.split('.')[0];

/** @type {import('@jest/types').Config.InitialOptions} */
const config = {
rootDir: process.cwd(),
Expand All @@ -17,7 +23,8 @@ const config = {
'<rootDir>/packages/react-instantsearch-router-nextjs/__tests__',
'<rootDir>/packages/react-instantsearch-nextjs/__tests__',
'/__utils__/',
],
algoliaSearchMajor !== '5' && '<rootDir>/packages/algolia-experiences',
].filter((x) => x !== false),
watchPathIgnorePatterns: [
'<rootDir>/packages/*/cjs',
'<rootDir>/packages/*/dist',
Expand All @@ -30,7 +37,9 @@ const config = {
'jest-watch-typeahead/filename',
'jest-watch-typeahead/testname',
],
transformIgnorePatterns: ['node_modules/(?!(search-insights)/)'],
transformIgnorePatterns: [
'node_modules/(?!(search-insights|algoliasearch)/)',
],
transform: {
'^.+\\.(j|t)sx?$': 'babel-jest',
'^.+\\.vue$': '@vue/vue2-jest',
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"lint:fix": "eslint --ext .js,.ts,.tsx,.vue --fix .",
"type-check": "tsc && lerna run type-check",
"type-check:v3": "tsc --project tsconfig.v3.json",
"type-check:v4": "tsc --project tsconfig.v4.json",
"test": "jest && lerna run test",
"test:ci": "./scripts/retry.sh 3 'jest --maxWorkers=4 --ci' && lerna run test --concurrency=1",
"test:ci:v4": "./scripts/retry.sh 3 'jest --maxWorkers=4 --ci' && lerna run test:v4 --concurrency=1",
Expand Down
30 changes: 30 additions & 0 deletions packages/algolia-experiences/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# `algolia-experiences`

This package allows you to use Algolia without code, by creating experiences in the Algolia dashboard and embedding them in your website.

## Usage

To get started, load the script tag and configuration in your HTML file, and add a `data-experience-id` attribute to the container where you want to render the UI.

```html
<!DOCTYPE html>
<head>
<script src="https://cdn.jsdelivr.net/npm/algolia-experiences@1"></script>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/instantsearch.css@8/themes/satellite.min.css"
/>
<meta
name="algolia-configuration"
content='{"appId":"latency","apiKey":"6be0576ff61c053d5f9a3225e2a90f76"}'
/>
</head>

<body>
<div data-experience-id="my-experience-id"></div>
</body>
```

The `data-experience-id` attribute should be set to the experience ID you want to use. You can find the experience ID in the dashboard.

For styling, you can use the [instantsearch.css](https://www.npmjs.com/package/instantsearch.css) package.
21 changes: 21 additions & 0 deletions packages/algolia-experiences/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "algolia-experiences",
"license": "MIT",
"version": "1.0.2",
"main": "src/index.ts",
"jsdelivr": "dist/algolia-experiences.production.min.js",
"unpkg": "dist/algolia-experiences.production.min.js",
"files": [
"dist"
],
"dependencies": {
"instantsearch.js": "4.74.0",
"algoliasearch": "5.1.1"
},
"devDependencies": {
"@instantsearch/testutils": "1.44.0"
},
"scripts": {
"build": "rollup -c rollup.config.js"
}
}
89 changes: 89 additions & 0 deletions packages/algolia-experiences/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import path from 'path';

import babel from 'rollup-plugin-babel';
import commonjs from 'rollup-plugin-commonjs';
import resolve from 'rollup-plugin-node-resolve';
import replace from 'rollup-plugin-replace';
import { uglify } from 'rollup-plugin-uglify';

import packageJson from '../../package.json';

const version =
process.env.NODE_ENV === 'production'
? packageJson.version
: `UNRELEASED (${new Date().toUTCString()})`;
const algolia = '© Algolia, Inc. and contributors; MIT License';
const link = 'https://github.com/algolia/instantsearch';
const license = `/*! algolia-experiences ${version} | ${algolia} | ${link} */`;

const plugins = [
{
/**
* This plugin is a workaround for the fact that the `algoliasearch/lite`
* package resolves to the UMD by default in this version of rollup.
* Revisit when rollup > 1.
*/
name: 'handle-algoliasearch-lite',
resolveId(source) {
if (source !== 'algoliasearch/lite') return null;
return path.join(
path.dirname(path.resolve(require.resolve('algoliasearch'))),
'lite',
'lite.esm.browser.js'
);
},
},
resolve({
browser: true,
preferBuiltins: false,
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json'],
}),
babel({
rootMode: 'upward',
runtimeHelpers: true,
exclude: /node_modules|algoliasearch-helper/,
extensions: ['.js', '.ts', '.tsx'],
}),
commonjs(),
];

const createConfiguration = ({ mode, filename }) => ({
input: 'src/index.ts',
output: {
file: `dist/${filename}`,
name: 'instantsearch',
format: 'umd',
banner: license,
sourcemap: true,
},
onwarn(warning, warn) {
if (warning.code === 'CIRCULAR_DEPENDENCY')
throw new Error(warning.message);

warn(warning);
},
plugins: [
...plugins,
replace({
__DEV__: mode === 'development',
'process.env.NODE_ENV': JSON.stringify('production'),
}),
mode === 'production' &&
uglify({
output: {
preamble: license,
},
}),
].filter(Boolean),
});

export default [
createConfiguration({
mode: 'development',
filename: 'algolia-experiences.development.js',
}),
createConfiguration({
mode: 'production',
filename: 'algolia-experiences.production.min.js',
}),
];
Loading

0 comments on commit f2bebf0

Please sign in to comment.