Package Exports
- @vectorhook/instantsearch
Readme
@vectorhook/instantsearch
An adapter that lets you use Algolia's InstantSearch frontend libraries with VectorHook as the backend search engine.
This adapter translates queries from InstantSearch libraries (vanilla JS, React, Vue, Angular) to VectorHook's search API format, allowing you to leverage InstantSearch's rich UI components while using VectorHook's powerful search capabilities.
Installation
# npm
npm install @vectorhook/instantsearch @vectorhook/client instantsearch.js
# or yarn
yarn add @vectorhook/instantsearch @vectorhook/client instantsearch.js
# For React InstantSearch
npm install react-instantsearch-dom
# For Vue InstantSearch
npm install vue-instantsearch
Quick Start
// Initialize VectorHook client
import VectorHook from '@vectorhook/client';
import VectorHookInstantSearch from '@vectorhook/instantsearch';
import instantsearch from 'instantsearch.js';
import { searchBox, hits } from 'instantsearch.js/es/widgets';
// Initialize VectorHook client
const vectorhookClient = new VectorHook({
apiKey: 'your_api_key',
baseUrl: 'https://api.vectorhook.com'
});
// Initialize the InstantSearch adapter
const searchClient = new VectorHookInstantSearch({
vectorhookClient: vectorhookClient,
collectionName: 'products',
mappings: {
queryBy: 'name,description',
facetBy: 'categories,brand,in_stock'
}
});
// Create the InstantSearch instance
const search = instantsearch({
indexName: 'products',
searchClient
});
// Add widgets
search.addWidgets([
searchBox({
container: '#searchbox',
}),
hits({
container: '#hits',
templates: {
item: (hit) => `
<div>
<h3>${hit.name}</h3>
<p>${hit.description}</p>
<p>$${hit.price}</p>
</div>
`
}
})
]);
// Start the search
search.start();
Framework Integrations
React InstantSearch
import React from 'react';
import VectorHook from '@vectorhook/client';
import VectorHookInstantSearch from '@vectorhook/instantsearch';
import { InstantSearch, SearchBox, Hits, RefinementList } from 'react-instantsearch-dom';
const vectorhookClient = new VectorHook({
apiKey: 'your_api_key',
baseUrl: 'https://api.vectorhook.com'
});
const searchClient = new VectorHookInstantSearch({
vectorhookClient: vectorhookClient,
collectionName: 'products',
mappings: {
queryBy: 'name,description',
facetBy: 'categories,brand'
}
});
function App() {
return (
<InstantSearch indexName="products" searchClient={searchClient}>
<div className="search-panel">
<div className="search-panel__filters">
<RefinementList attribute="categories" />
<RefinementList attribute="brand" />
</div>
<div className="search-panel__results">
<SearchBox />
<Hits hitComponent={Hit} />
</div>
</div>
</InstantSearch>
);
}
function Hit({ hit }) {
return (
<article>
<h1>{hit.name}</h1>
<p>{hit.description}</p>
<p>${hit.price}</p>
</article>
);
}
export default App;
Vue InstantSearch
<template>
<ais-instant-search
:search-client="searchClient"
index-name="products"
>
<div class="search-panel">
<div class="search-panel__filters">
<ais-refinement-list attribute="categories" />
<ais-refinement-list attribute="brand" />
</div>
<div class="search-panel__results">
<ais-search-box />
<ais-hits>
<template slot="item" slot-scope="{ item }">
<h1>{{ item.name }}</h1>
<p>{{ item.description }}</p>
<p>${{ item.price }}</p>
</template>
</ais-hits>
</div>
</div>
</ais-instant-search>
</template>
<script>
import VectorHook from '@vectorhook/client';
import VectorHookInstantSearch from '@vectorhook/instantsearch';
export default {
data() {
const vectorhookClient = new VectorHook({
apiKey: 'your_api_key',
baseUrl: 'https://api.vectorhook.com'
});
const searchClient = new VectorHookInstantSearch({
vectorhookClient: vectorhookClient,
collectionName: 'products',
mappings: {
queryBy: 'name,description',
facetBy: 'categories,brand'
}
});
return {
searchClient
};
}
};
</script>
Configuration Options
The VectorHookInstantSearch
constructor accepts the following options:
const searchClient = new VectorHookInstantSearch({
// Required options
vectorhookClient: vectorhookClient, // Initialized VectorHook client
collectionName: 'products', // VectorHook collection to search
// Field mapping options
mappings: {
// Fields to search (comma-separated)
queryBy: 'name,description',
// Fields for faceting (comma-separated)
facetBy: 'categories,brand,in_stock',
// Field used for tag filtering
tagsField: 'tags',
// Field for geo search
geoField: '_geo',
// Map Algolia field names to VectorHook field names
facetMap: {
'category': 'categories',
'author.name': 'author_name'
},
// Map index names to sort options
sortMap: {
'products_price_asc': 'price:asc',
'products_price_desc': 'price:desc'
},
// Default sort when none specified
defaultSort: 'price:asc'
},
// Additional query parameters to include in all searches
additionalQueryParams: {
group_limit: 3,
typo_tolerance_enabled: false
},
// Performance options
requestTimeout: 5000, // Timeout in ms
maxRetries: 2, // Max retries for failed requests
// Debug mode
debug: false // Set to true for verbose logging
});
Features
- Full Compatibility: Works with all InstantSearch libraries (JS, React, Vue, Angular)
- Faceting: Supports refinement lists, hierarchical menus, and range sliders
- Pagination: Works seamlessly with InstantSearch's pagination components
- Sorting: Supports multiple indices for different sort orders
- Highlighting: Converts VectorHook highlights to InstantSearch format
- Error Handling: Built-in retries for failed requests
- Customization: Extensive mapping options for field names and behaviors
Field Mapping
Default Field Mappings
VectorHook's field names might be different from what InstantSearch expects. The adapter provides mapping options to handle these differences:
const searchClient = new VectorHookInstantSearch({
// ...other options
mappings: {
// Map Algolia field names to VectorHook field names
facetMap: {
'category': 'categories', // InstantSearch uses 'category', VectorHook uses 'categories'
'author.name': 'author_name' // Handle nested fields
}
}
});
Sort Mapping
For sorting, InstantSearch typically uses different indices with specific names. The adapter maps these index names to VectorHook sort parameters:
const searchClient = new VectorHookInstantSearch({
// ...other options
mappings: {
sortMap: {
'products_price_asc': 'price:asc',
'products_price_desc': 'price:desc',
'products_created_at_desc': 'created_at:desc'
}
}
});
Advanced Usage
Multi-Index Search
For multi-index searching (e.g., for sorting):
// instantsearch.js
const search = instantsearch({
indexName: 'products',
searchClient
});
// Add a sort-by widget
search.addWidgets([
sortBy({
container: '#sort-by',
items: [
{ label: 'Default', value: 'products' },
{ label: 'Price (asc)', value: 'products_price_asc' },
{ label: 'Price (desc)', value: 'products_price_desc' }
]
})
]);
The adapter will map these index names to VectorHook sort parameters based on your sortMap
configuration.
Custom Highlighting
Configure highlighting parameters:
const searchClient = new VectorHookInstantSearch({
// ...other options
additionalQueryParams: {
highlight_fields: 'name,description',
highlight_start_tag: '<mark>',
highlight_end_tag: '</mark>'
}
});
Geo Search
For geo search capabilities:
// React InstantSearch
<InstantSearch indexName="products" searchClient={searchClient}>
<Configure aroundLatLng="40.7128,-74.0060" aroundRadius="1000" />
{/* Other widgets */}
</InstantSearch>
The adapter will convert these parameters to VectorHook's geo filter format.
API Reference
VectorHookInstantSearch
Constructor
new VectorHookInstantSearch(options)
Methods
Method | Description |
---|---|
search(requests) |
Main method called by InstantSearch to perform searches |
setCollection(collectionName) |
Change the collection being searched |
updateOptions(options) |
Update adapter options |
resetOptions() |
Reset options to initial values |
getState() |
Get current search state |
clearCache() |
Compatibility method (no-op for VectorHook) |
Compatibility Notes
Sorting
VectorHook uses sort_by
parameter with format field:direction
, while InstantSearch typically uses separate indices.
Faceting
The adapter automatically converts InstantSearch facet filters to VectorHook's filter format.
Highlighting
VectorHook's highlighting format is converted to match what InstantSearch expects.
Migration from Algolia
If you're migrating from Algolia to VectorHook, this adapter makes it easier by allowing you to keep your existing InstantSearch UI code. You only need to:
- Replace the Algolia client with the VectorHook client and this adapter
- Configure the appropriate field mappings
- Ensure your VectorHook schema matches your data structure
Troubleshooting
Common Issues
- Missing facets: Ensure you've added the facet fields to the
facetBy
option. - Incorrect sorting: Check your
sortMap
configuration. - Search not working: Verify your VectorHook API key and collection name.
Debug Mode
Enable debug mode to see detailed logs:
const searchClient = new VectorHookInstantSearch({
// ...other options
debug: true
});
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.