Core concepts
Vue InstantSearch is built around three core concepts:
Widgets Vue components that render search UI elements like search boxes, hits, and filters
Connectors Logic layer that manages widget state and search parameters
InstantSearch instance The root component that coordinates all widgets and manages the search state
The InstantSearch wrapper
Every Vue InstantSearch implementation requires the <ais-instant-search> component as the root wrapper. This component manages the search state and coordinates all child widgets.
Required props
Common props
Basic example
< template >
< ais-instant-search
: search-client = " searchClient "
index-name = "products"
: insights = " true "
: routing = " routing "
>
<!-- Your search widgets go here -->
</ ais-instant-search >
</ template >
< script >
import { liteClient as algoliasearch } from 'algoliasearch/lite' ;
export default {
data () {
return {
searchClient: algoliasearch ( 'YourAppID' , 'YourSearchKey' ),
routing: {
router: {
// Custom router implementation
},
},
};
} ,
} ;
</ script >
Essential components
Search box
The <ais-search-box> component provides a search input field.
< ais-search-box
placeholder = "Search for products..."
: autofocus = " true "
submit-title = "Submit search"
reset-title = "Clear search"
/>
Custom rendering with slots
< ais-search-box >
<template #submit-icon>
<svg><!-- Custom submit icon --></svg>
</template>
<template #reset-icon>
<svg><!-- Custom reset icon --></svg>
</template>
<template #loading-indicator>
<span class="custom-loader">Loading...</span>
</template>
</ ais-search-box >
Hits
The <ais-hits> component displays search results.
< ais-hits >
<template #item="{ item }">
<article>
<img :src="item.image" :alt="item.name" />
<h2>
<ais-highlight :hit="item" attribute="name" />
</h2>
<p>{{ item.price }}</p>
</article>
</template>
</ ais-hits >
The item slot receives the full hit object with all attributes from your Algolia index.
Refinement list
The <ais-refinement-list> component creates a list of facet filters.
< ais-refinement-list
attribute = "brand"
: searchable = " true "
searchable-placeholder = "Search brands..."
operator = "or"
: limit = " 10 "
: show-more = " true "
: show-more-limit = " 20 "
/>
The <ais-configure> component sets search parameters without rendering UI.
< ais-configure
: hits-per-page . camel = " 20 "
: attributes-to-snippet . camel = " [ 'description:50' ] "
: snippet-ellipsis-text . camel = " '...' "
: remove-words-if-no-result . camel = " 'allOptional' "
/>
Use the .camel modifier for props with camelCase names in Vue 2. Vue 3 handles this automatically.
Highlighting and snippeting
Highlight component
Highlight matching terms in search results:
< ais-highlight
: hit = " item "
attribute = "name"
highlighted-tag-name = "mark"
/>
Snippet component
Display text snippets with highlighted matches:
< ais-snippet
: hit = " item "
attribute = "description"
highlighted-tag-name = "em"
/>
Add pagination controls with <ais-pagination>:
< ais-pagination
: padding = " 3 "
: show-first = " true "
: show-last = " true "
/>
Custom pagination rendering:
< ais-pagination >
<template #default="{ pages, currentRefinement, refine, createURL }">
<ul>
<li v-for="page in pages" :key="page">
<a
:href="createURL(page)"
:class="{ active: page === currentRefinement }"
@click.prevent="refine(page)"
>
{{ page + 1 }}
</a>
</li>
</ul>
</template>
</ ais-pagination >
Multi-index search
Search across multiple indices using the <ais-index> component:
< ais-instant-search
: search-client = " searchClient "
index-name = "products"
>
<!-- Main index -->
<ais-search-box />
<ais-hits>
<template #item="{ item }">
<div>{{ item.name }}</div>
</template>
</ais-hits>
<!-- Secondary index for suggestions -->
<ais-index
index-name="query_suggestions"
index-id="suggestions"
>
<ais-hits>
<template #item="{ item }">
<div>{{ item.query }}</div>
</template>
</ais-hits>
</ais-index>
</ ais-instant-search >
All widgets support custom rendering through scoped slots:
< ais-stats >
<template #default="{ nbHits, processingTimeMS }">
<p>
Found <strong>{{ nbHits.toLocaleString() }}</strong> results
in {{ processingTimeMS }}ms
</p>
</template>
</ ais-stats >
Controlled components
Control widget state from parent components:
< template >
< ais-search-box v-model = " query " />
</ template >
< script >
export default {
data () {
return {
query: 'initial search' ,
};
} ,
} ;
</ script >
Conditional search
Control when searches execute using search-function:
< template >
< ais-instant-search
: search-client = " searchClient "
index-name = "products"
: search-function = " searchFunction "
>
< ais-search-box />
< ais-hits />
</ ais-instant-search >
</ template >
< script >
export default {
methods: {
searchFunction ( helper ) {
// Only search if query has at least 3 characters
if ( helper . state . query . length >= 3 ) {
helper . search ();
}
},
} ,
} ;
</ script >
Best practices
Use the lite client for better performance
Reuse the search client instance
Create the search client once and reuse it: // ✅ Good: Create once
const searchClient = algoliasearch ( 'appId' , 'apiKey' );
export default {
data () {
return { searchClient };
} ,
} ;
// ❌ Bad: Creates new instance on every render
export default {
data () {
return {
searchClient: algoliasearch ( 'appId' , 'apiKey' ),
};
} ,
} ;
Use transformItems for custom sorting or filtering
Configure search parameters with ais-configure
Next steps
Vue 2 vs Vue 3 Learn about version-specific differences
Server-side rendering Implement SSR with Vue InstantSearch