Nuxt Swiftsearch
Composables

useInstantSearch

Access the parent InstantSearch instance from descendant components.

useInstantSearch() returns helpers for the <AisInstantSearch> instance provided by the nearest ancestor.

Returned shape

const { getInstance, parentIndex, setup, status, error } = useInstantSearch();
FieldTypeDescription
getInstance() => Ref<InstantSearch>Throws if the instance was not yet provided. Use it to access helper, mainIndex, renderState.
parentIndexComputedRef<IndexWidget>The instance's mainIndex. Useful when stitching <AisIndex> widgets manually.
statusRef<'idle' | 'loading' | 'stalled' | 'error'>Reactive search status. stalled fires after stalledSearchDelay (default 200ms).
errorRef<Error | undefined>Last search error. Cleared automatically when a new search starts.
setup(widgets, instanceKey?) => Promise<void>Internal — used by <AisInstantSearch> to register widgets and trigger SSR queries.

status and error are shared across every descendant call to useInstantSearch() within the same <AisInstantSearch>, so the same refs power <AisStateResults> and any custom loading UI you build.

Usage

composables/useTotalHits.ts
import { computed } from "vue";

export const useTotalHits = () => {
  const { getInstance, parentIndex } = useInstantSearch();
  const instance = getInstance();

  return computed(() => {
    const renderState = instance.value.renderState[parentIndex.value.getIndexId()];
    return renderState?.stats?.nbHits ?? 0;
  });
};

Loading indicator example

The reactive status ref makes Algolia's loading-indicator pattern straightforward:

components/SearchSpinner.vue
<script setup lang="ts">
const { status } = useInstantSearch();
</script>

<template>
  <div v-if="status === 'stalled'" class="spinner">Loading…</div>
</template>

stalled only triggers after stalledSearchDelay (200ms by default), so the spinner stays hidden during fast queries. Pair it with error for inline failure UI:

<script setup lang="ts">
const { status, error } = useInstantSearch();
</script>

<template>
  <p v-if="status === 'stalled'">Searching…</p>
  <p v-else-if="status === 'error'" class="error">{{ error?.message }}</p>
</template>
On SSR the initial render lands directly in idle because results are pre-fetched and hydrated. The loading states only fire on subsequent client-driven searches (typing, refinement clicks, pagination, etc.).

Throwing behavior

Calling getInstance() outside of an <AisInstantSearch> subtree throws instantiate instantsearch first. Render the component (or guard with try/catch) before calling.

Copyright © 2026