Automated summary
Guides the implementation of Algolia search UIs in Nuxt 3 apps using the @atoms-studio/nuxt-swiftsearch module, following a dual composable/component registration pattern that stays SSR-safe.
Strengths
- States the core dual-registration rule clearly (composable in script setup plus component in the template), which prevents the most common mistakes
- Calls out the reactivity requirements needed for SSR hydration: widgets as computed, configuration as ref
- Provides a mapping table of Ais* components to useAis* composables covering search box, facets, pagination and infinite scroll
- Notes that components and composables are auto-imported and that attribute props must be kept in sync between template and composable
Limitations
- Full props, slots and composable parameters are deferred to a widgets-reference.md file that is not part of this SKILL.md
- No guidance on Algolia key safety (search-only key, environment variables) even though the example hardcodes credentials
- The component table is cut off, so the actual widget coverage cannot be verified
Use it when adding or migrating an Algolia search page in a Nuxt 3 project, especially with facet filters or infinite scroll.
Skip it when the project is not Nuxt 3 or not built on Algolia, or when you only need to call the Algolia API server-side without any search interface.
Security analysis
SafeThis is a documentation-only skill describing how to wire the @atoms-studio/nuxt-swiftsearch module into a Nuxt 3 app. It declares no tools, contains no shell pipelines, no obfuscated payloads, no file deletion, and no exfiltration of secrets. The only notable point is the placeholder Algolia key in client-side sample code, which is standard for Algolia search-only keys but should carry an explicit warning.
- •Example code embeds `algoliasearch("APP_ID", "API_KEY")` in the client-side `<script setup>`; the skill does not warn that only a public search-only API key may be used there, so an admin/write key could be leaked if followed carelessly.
- •Recommends running `npx nuxi@latest module add swiftsearch`, which fetches and installs a third-party package at execution time (legitimate, but unpinned `@latest`).
Examples
Add an Algolia search page to my Nuxt 3 app using @atoms-studio/nuxt-swiftsearch: install the module, then build a page with a search box, a brand refinement list and paginated hits.In my Nuxt 3 app, replace the paginated Algolia results with an infinite scroll list using AisInfiniteHits and useAisInfiniteHits from nuxt-swiftsearch, keeping SSR working.Migrate my existing vue-instantsearch Nuxt 3 search page to @atoms-studio/nuxt-swiftsearch, converting each widget to its Ais* component plus useAis* composable and keeping the same filters.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)
From the file to a first result
The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.
View the source and supporting filesThis download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.
1. Download the file
Download SKILL.mdFrom the root of a test project, save the file as .skill-downloads/algolia-search-uis-with-nuxt-swiftsearch-ms47vpev/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.
Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.
mkdir -p '.skill-downloads/algolia-search-uis-with-nuxt-swiftsearch-ms47vpev' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/algolia-search-uis-with-nuxt-swiftsearch-ms47vpev/download' --output '.skill-downloads/algolia-search-uis-with-nuxt-swiftsearch-ms47vpev/SKILL.md.part' && mv '.skill-downloads/algolia-search-uis-with-nuxt-swiftsearch-ms47vpev/SKILL.md.part' '.skill-downloads/algolia-search-uis-with-nuxt-swiftsearch-ms47vpev/SKILL.md'2. Check prerequisites
Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.
Original excerpt: Installation
npx nuxi@latest module add swiftsearch
// nuxt.config.ts
export default defineNuxtConfig({
modules: ["@atoms-studio/nuxt-swiftsearch"],
});
The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.
3. Load the skill
After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.
Claude Code
test -f '.skill-downloads/algolia-search-uis-with-nuxt-swiftsearch-ms47vpev/SKILL.md' && test -s '.skill-downloads/algolia-search-uis-with-nuxt-swiftsearch-ms47vpev/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/nuxt-swiftsearch' && cp -R '.skill-downloads/algolia-search-uis-with-nuxt-swiftsearch-ms47vpev' '.claude/skills/nuxt-swiftsearch'Cursor
test -f '.skill-downloads/algolia-search-uis-with-nuxt-swiftsearch-ms47vpev/SKILL.md' && test -s '.skill-downloads/algolia-search-uis-with-nuxt-swiftsearch-ms47vpev/SKILL.md' && mkdir -p '.cursor/skills' && test ! -e '.cursor/skills/nuxt-swiftsearch' && cp -R '.skill-downloads/algolia-search-uis-with-nuxt-swiftsearch-ms47vpev' '.cursor/skills/nuxt-swiftsearch'OpenSkills
OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.
Official OpenSkills installationopenskills install './.skill-downloads/algolia-search-uis-with-nuxt-swiftsearch-ms47vpev'openskills read 'algolia-search-uis-with-nuxt-swiftsearch-ms47vpev'Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.
For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.
openskills syncManual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.
4. Try a first task
Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:
Read .skill-downloads/algolia-search-uis-with-nuxt-swiftsearch-ms47vpev/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.
React Hook Form Best Practices
Development
Master React Hook Form: avoid anti-patterns, manage subscriptions, and handle reset, dirty state, and controlled inputs correctly.
Emotion to Mantine Migration
Development
Migrate Emotion styled-components to Mantine components with style props and CSS modules. Use when converting .styled.tsx files or removing @emotion imports.
Scope Creep Detector
Development
Analyzes git diffs against a stated intent to detect scope creep, unrelated files, broad PRs, and oversized changes, then suggests keep, split, or justify actions.