name: nuxt-swiftsearch description: Implement Algolia search UIs in Nuxt 3 apps using @atoms-studio/nuxt-swiftsearch — an SSR-first, fully typed alternative to vue-instantsearch. version: 1.0.0 license: MIT author: "@atoms-studio" tags:
- nuxt
- algolia
- search
- ssr
- vue
Instructions
Use this skill when building search UIs in Nuxt 3 apps with Algolia via @atoms-studio/nuxt-swiftsearch.
When to Use
- Adding search functionality to a Nuxt 3 app with Algolia
- Building search pages with filters, pagination, infinite scroll
- Implementing SSR-compatible search experiences
- Migrating from vue-instantsearch to a Nuxt-native approach
Installation
npx nuxi@latest module add swiftsearch
// nuxt.config.ts
export default defineNuxtConfig({
modules: ["@atoms-studio/nuxt-swiftsearch"],
});
Core Pattern: Dual Registration
Every widget requires both a composable (in <script setup>) AND a component (in <template>). The composable registers the widget with the InstantSearch instance; the component renders it.
<template>
<AisInstantSearch :widgets :configuration>
<AisSearchBox />
<AisHits />
<AisRefinementList attribute="brand" />
</AisInstantSearch>
</template>
<script setup lang="ts">
import { algoliasearch } from "algoliasearch";
const client = algoliasearch("APP_ID", "API_KEY");
const widgets = computed(() => [
useAisSearchBox({}),
useAisHits({ escapeHTML: true }),
useAisRefinementList({ attribute: "brand" }),
]);
const configuration = ref({
indexName: "my_index",
searchClient: client,
});
</script>
Critical Rules
widgetsmust becomputed— not a plain array. The reactivity is required for SSR hydration.configurationmust beref— wrap the config object inref().- Attribute props must match — when using
AisRefinementList,AisMenu, etc., theattributeprop on the component must match theattributein the composable. - All composables and components are auto-imported — no manual imports needed for
useAis*composables orAis*components.
Available Components & Composables
Full props, slots, composable params, and examples for every widget: widgets-reference.md
| Component | Composable | Purpose |
| -------------------------- | ----------------------------- | ------------------------------------------------------ |
| <AisInstantSearch> | — | Root wrapper, receives :widgets and :configuration |
| <AisIndex> | useAisIndex() | Multi-index scoping |
| <AisSearchBox> | useAisSearchBox() | Search input |
| <AisHits> | useAisHits() | Paginated results |
| <AisInfiniteHits> | useAisInfiniteHits() | Infinite scroll results |
| <AisRefinementList> | useAisRefinementList() | Facet filtering |
| <AisMenu> | useAisMenu() | Single-select facet menu |
| <AisMenuSelect> | — | Dropdown facet menu |
| <AisHierarchicalMenu> | useAisHierarchicalMenu() | Nested category navigation |
| <AisNumericMenu> | useAisNumericMenu() | Numeric range filtering |
| <AisRangeInput> | useAisRangeInput() | Min/max range input |
| <AisRatingMenu> | useAisRatingMenu() | Star rating filter |
| <AisToggleRefinement> | useAisToggleRefinement() | Boolean toggle filter |
| <AisClearRefinements> | useAisClearRefinements() | Clear all active filters |
| <AisCurrentRefinements> | useAisCurrentRefinements() | Show active filters |
| <AisSortBy> | useAisSortBy() | Sort order selector |
| <AisStats> | useAisStats() | Results count & timing |
| <AisPagination> | useAisPagination() | Page navigation |
| <AisConfigure> | useAisConfigure() | Hidden search parameters |
| <AisHighlight> | — | Highlight matched text |
| <AisAutocomplete> | useAisAutocomplete() | Autocomplete suggestions |
| <AisPanel> | — | Collapsible panel wrapper |
| <AisQueryRuleCustomData> | useAisQueryRuleCustomData() | Query rules data |
| <AisStateResults> | — | Generic state renderer |
Widget Categories (Quick Lookup)
Search Input: AisSearchBox, AisAutocomplete
Results: AisHits, AisInfiniteHits, AisStateResults
Refinements: AisRefinementList, AisMenu, AisMenuSelect, AisHierarchicalMenu, AisNumericMenu, AisRangeInput, AisRatingMenu, AisToggleRefinement
Active Filters: AisClearRefinements, AisCurrentRefinements
Sorting & Pagination: AisSortBy, AisPagination
Display: AisStats, AisHighlight, AisPanel
Config: AisConfigure, AisQueryRuleCustomData
Structure: AisInstantSearch, AisIndex
URL Routing
To sync search state with the URL:
- Set up query string parsing:
// app/router.options.ts
import type { RouterConfig } from "@nuxt/schema";
import qs from "qs";
export default <RouterConfig>{
parseQuery: qs.parse,
stringifyQuery: qs.stringify,
};
- Add the router to configuration:
<script setup lang="ts">
const algoliaRouter = useAisRouter();
const configuration = ref({
indexName: "my_index",
routing: algoliaRouter.value,
searchClient: client,
});
</script>
Slot Customization
All components expose slots with typed render state:
<AisHits>
<template #item="{ item }">
<div>{{ item.name }}</div>
</template>
</AisHits>
<AisInfiniteHits>
<template #item="{ item }">
<div>{{ item.title }}</div>
</template>
<template #loadMore="{ refineNext, isLastPage }">
<button :disabled="isLastPage" @click="refineNext">Load more</button>
</template>
</AisInfiniteHits>
Caching (Infinite Hits)
For stateful caching across page navigations:
const cache = useAisStatefulCache();
const infiniteCache = useAisInfiniteHitsStatefulCache();
const widgets = computed(() => [useAisInfiniteHits({ cache: infiniteCache })]);
Accessing the Instance
<script setup lang="ts">
const { getInstance } = useAisInstantSearch();
// Access the raw InstantSearch instance for advanced use cases
</script>
Multi-Index Search
<AisInstantSearch :widgets :configuration>
<AisIndex index="products">
<AisHits />
</AisIndex>
<AisIndex index="articles">
<AisHits />
</AisIndex>
</AisInstantSearch>
CSS Classes
Components use BEM convention: ais-WidgetName-element--modifier. Use useSuit("WidgetName") to generate class names programmatically.
Common Mistakes
- Forgetting to add the composable to
widgetsarray (component renders but doesn't work) - Using a plain array instead of
computed()for widgets - Mismatched
attributebetween component prop and composable param - Importing composables manually (they're auto-imported)
Dependencies
- Nuxt >= 3.10
algoliasearchv5+qs(only if using routing)
Expert Next.js App Router
Developpement
Un skill qui transforme Claude en expert Next.js App Router.
Générateur de README
Developpement
Crée des README.md professionnels et complets pour vos projets.
Rédacteur de Documentation API
Developpement
Génère de la documentation API complète au format OpenAPI/Swagger.