一键导入
nuxt-swiftsearch
Implement Algolia search UIs in Nuxt 3 apps using @atoms-studio/nuxt-swiftsearch — an SSR-first, fully typed alternative to vue-instantsearch.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Implement Algolia search UIs in Nuxt 3 apps using @atoms-studio/nuxt-swiftsearch — an SSR-first, fully typed alternative to vue-instantsearch.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Create complete documentation sites for projects. Use when asked to: "create docs", "add documentation", "setup docs site", "generate docs", "document my project", "write docs", "initialize documentation", "add a docs folder", "create a docs website". Generates Docus-based sites with search, dark mode, MCP server, and llms.txt integration.
Review documentation for quality, clarity, SEO, and technical correctness. Optimized for Docus/Nuxt Content but works with any Markdown documentation. Use when asked to: "review docs", "check documentation", "audit docs", "validate documentation", "improve docs quality", "analyze documentation", "check my docs", "review my documentation pages", "validate MDC syntax", "check for SEO issues", "analyze doc structure". Provides actionable recommendations categorized by priority (Critical, Important, Nice-to-have).
| 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"] |
Use this skill when building search UIs in Nuxt 3 apps with Algolia via @atoms-studio/nuxt-swiftsearch.
npx nuxi@latest module add swiftsearch
// nuxt.config.ts
export default defineNuxtConfig({
modules: ["@atoms-studio/nuxt-swiftsearch"],
});
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>
widgets must be computed — not a plain array. The reactivity is required for SSR hydration.configuration must be ref — wrap the config object in ref().AisRefinementList, AisMenu, etc., the attribute prop on the component must match the attribute in the composable.useAis* composables or Ais* components.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 |
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
To sync search state with the URL:
// app/router.options.ts
import type { RouterConfig } from "@nuxt/schema";
import qs from "qs";
export default <RouterConfig>{
parseQuery: qs.parse,
stringifyQuery: qs.stringify,
};
<script setup lang="ts">
const algoliaRouter = useAisRouter();
const configuration = ref({
indexName: "my_index",
routing: algoliaRouter.value,
searchClient: client,
});
</script>
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>
For stateful caching across page navigations:
const cache = useAisStatefulCache();
const infiniteCache = useAisInfiniteHitsStatefulCache();
const widgets = computed(() => [useAisInfiniteHits({ cache: infiniteCache })]);
<script setup lang="ts">
const { getInstance } = useAisInstantSearch();
// Access the raw InstantSearch instance for advanced use cases
</script>
<AisInstantSearch :widgets :configuration>
<AisIndex index="products">
<AisHits />
</AisIndex>
<AisIndex index="articles">
<AisHits />
</AisIndex>
</AisInstantSearch>
Components use BEM convention: ais-WidgetName-element--modifier. Use useSuit("WidgetName") to generate class names programmatically.
widgets array (component renders but doesn't work)computed() for widgetsattribute between component prop and composable paramalgoliasearch v5+qs (only if using routing)