nuxt-swiftsearch
A Nuxt-native module for building Algolia-powered search UIs with TypeScript support.
Install
mkdir -p .claude/skills/nuxt-swiftsearch && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/14314" && unzip -o skill.zip -d .claude/skills/nuxt-swiftsearch && rm skill.zipInstalls to .claude/skills/nuxt-swiftsearch
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Implement Algolia search UIs in Nuxt 3 apps using @atoms-studio/nuxt-swiftsearch — an SSR-first, fully typed alternative to vue-instantsearch.Key capabilities
- →Implement Algolia search UIs in Nuxt 3 applications
- →Build search pages with filters, pagination, and infinite scroll
- →Ensure Server-Side Rendering (SSR) compatibility for search experiences
- →Register search widgets using both composables and components
- →Sync search state with the URL for persistent search experiences
- →Customize widget appearance and behavior using slots
How it works
The skill integrates Algolia search into Nuxt 3 apps using `@atoms-studio/nuxt-swiftsearch`, requiring dual registration of widgets via composables and components. It ensures SSR compatibility and provides features like URL routing and slot customization.
Inputs & outputs
When to use nuxt-swiftsearch
- →Add search to Nuxt app
- →Implement infinite scroll search
- →Configure Algolia filters
About this skill
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)
When not to use it
- →When forgetting to add the composable to the `widgets` array
- →When using a plain array instead of `computed()` for widgets
- →When importing composables manually
Prerequisites
Limitations
- →`widgets` must be `computed`
- →`configuration` must be `ref`
- →Attribute props must match between component and composable
How it compares
This skill offers an SSR-first, fully typed approach to Algolia search integration in Nuxt 3, requiring a specific dual registration pattern for widgets and providing built-in URL routing, which is more tailored to Nuxt's architecture than
Compared to similar skills
nuxt-swiftsearch side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| nuxt-swiftsearch (this skill) | 0 | 4mo | Review | Advanced |
| ai-model-web | 1 | 2mo | Review | Intermediate |
| rdc-setup | 1 | 5mo | Review | Intermediate |
| vitepress | 5 | 6mo | No flags | Beginner |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
ai-model-web
TencentCloudBase
Use this skill when developing browser/Web applications (React/Vue/Angular, static websites, SPAs) that need AI capabilities. Features text generation (generateText) and streaming (streamText) via @cloudbase/js-sdk. Built-in models include Hunyuan (hunyuan-2.0-instruct-20251111 recommended) and DeepSeek (deepseek-v3.2 recommended). NOT for Node.js backend (use ai-model-nodejs), WeChat Mini Program (use ai-model-wechat), or image generation (Node SDK only).
rdc-setup
reactive
Install and set up @data-client/react or @data-client/vue in a project. Detects project type (NextJS, Expo, React Native, Vue, plain React) and protocol (REST, GraphQL, custom), then hands off to protocol-specific setup skills.
vitepress
antfu
VitePress static site generator powered by Vite and Vue. Use when building documentation sites, configuring themes, or writing Markdown with Vue components.
create-adaptable-composable
vuejs-ai
Create a library-grade Vue composable that accepts maybe-reactive inputs (MaybeRef / MaybeRefOrGetter) so callers can pass a plain value, ref, or getter. Normalize inputs with toValue()/toRef() inside reactive effects (watch/watchEffect) to keep behavior predictable and reactive. Use this skill when user asks for creating adaptable or reusable composables.
moai-domain-frontend
modu-ai
Frontend development specialist covering React 19, Next.js 16, Vue 3.5, and modern UI/UX patterns with component architecture. Use when building web UIs, implementing components, optimizing frontend performance, or integrating state management.
vueuse-functions
antfu
Apply VueUse composables where appropriate to build concise, maintainable Vue.js / Nuxt features.