Usage
Recommended: declarative widget authoring
When <AisInstantSearch> has no :widgets prop, Nuxt Swiftsearch auto-generates the widget list from child components.
<template>
<AisInstantSearch :configuration="configuration">
<AisSearchBox placeholder="Search products" />
<AisConfigure :hits-per-page.camel="12" />
<AisRefinementList attribute="brand" searchable />
<AisHits />
<AisPagination />
</AisInstantSearch>
</template>
<script setup lang="ts">
import { algoliasearch } from "algoliasearch";
const searchClient = algoliasearch("latency", "6be0576ff61c053d5f9a3225e2a90f76");
const configuration = {
indexName: "instant_search",
searchClient,
};
</script>
Still supported: manual widget arrays
If you need dynamic widget factories or unsupported control flow, keep using :widgets with useAis* composables.
<template>
<AisInstantSearch :configuration="configuration" :widgets="widgets">
<AisSearchBox />
<AisHits />
</AisInstantSearch>
</template>
<script setup lang="ts">
import { algoliasearch } from "algoliasearch";
const searchClient = algoliasearch("latency", "6be0576ff61c053d5f9a3225e2a90f76");
const configuration = {
indexName: "instant_search",
searchClient,
};
const widgets = computed(() => [useAisSearchBox({}), useAisHits({})]);
</script>
Multi-index tip
Use <AisIndex index-name="..." :index-id="..."> for explicit state boundaries when multiple indices use the same widget types.
Typed transformItems with generics
Widgets that expose transformItems now support generic item typing, so slot props can match your transformed shape.
Use Vue's template generic syntax via @vue-generic (not <AisHits<ProductHit>>).
<script setup lang="ts">
import type { BaseHit, Hit } from "instantsearch.js/es/types";
type ProductHit = {
objectID: string;
name: string;
brandLabel: string;
};
const transformHits = (items: Array<Hit<BaseHit>>) => {
return items.map((item) => ({
...item,
brandLabel: String(item.brand ?? "Unknown"),
})) as Array<Hit<ProductHit>>;
};
</script>
<template>
<!-- @vue-generic {ProductHit} -->
<AisHits :transform-items="transformHits">
<template #item="{ item }"> {{ item.name }} — {{ item.brandLabel }} </template>
</AisHits>
</template>
Next step
See /examples for end-to-end patterns extracted from the playground (declarative layout, manual mode compatibility, multi-index isolation, route-driven filters, autocomplete, pagination routing, parity showcase, and analytics/insights event tracking).