Search code examples
javascriptvue.jsvuejs3algoliavue-instant-search

vue-instantsearch not working in my VueJS 3.0 project


I have a VueJS 3.0 project (Options API) in combination with Firebase and Algolia. Everything works fine. I have multiple indices defined in Algolia and I can search them simultaneously with my own Vue code that I've written, but I would rather use vue-instantsearch from Algolia. I have tried to setup the basics to search one index (companyIndex), however I can't get it to work. Error I get is this (####### are my keys):

[Vue warn]: Unhandled error during execution of created hook 
  at <AisSearchBox> 
  at <AisInstantSearch search-client= {transporter: {…}, appId: '#########', addAlgoliaAgent: ƒ, clearCache: ƒ, search: ƒ, …}addAlgoliaAgent: ƒ (e,t)appId: "#########"clearCache: ƒ ()initIndex: ƒ (t)multipleQueries: ƒ (t,n)multipleSearchForFacetValues: ƒ (t,o)search: ƒ (t,n)searchForFacetValues: ƒ (t,o)transporter: {hostsCache: {…}, logger: {…}, requester: {…}, requestsCache: {…}, responsesCache: {…}, …}[[Prototype]]: Object index-name="companyIndex" > 
  at <Home onAuthenticated=fn<setAuthenticatedUser> onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< null > > 
  at <RouterView onAuthenticated=fn<setAuthenticatedUser> > 
  at <App>
...
runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next 
  at <AisSearchBox> 
  at <AisInstantSearch search-client= {transporter: {…}, appId: '#########', addAlgoliaAgent: ƒ, clearCache: ƒ, search: ƒ, …} index-name="companyIndex" > 
  at <Home onAuthenticated=fn<setAuthenticatedUser> onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< null > > 
  at <RouterView onAuthenticated=fn<setAuthenticatedUser> > 
  at <App>
...
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'instantSearchInstance')
    at Proxy.eval (widget.js?c00b:1)
    at Proxy.created (widget.js?c00b:1)
    at callWithErrorHandling (runtime-core.esm-bundler.js?5c40:154)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?5c40:163)
    at callHook (runtime-core.esm-bundler.js?5c40:3177)
    at applyOptions (runtime-core.esm-bundler.js?5c40:3107)
    at finishComponentSetup (runtime-core.esm-bundler.js?5c40:7218)
    at setupStatefulComponent (runtime-core.esm-bundler.js?5c40:7143)
    at setupComponent (runtime-core.esm-bundler.js?5c40:7074)
    at mountComponent (runtime-core.esm-bundler.js?5c40:5079)

This is my main.js:

import { createApp } from 'vue'
import { fbAuth } from '@/firebase/config'

import App from '@/App.vue'
import router from '@/router'
import VTooltip from 'v-tooltip'
import 'v-tooltip/dist/v-tooltip.css'
import InstantSearch from 'vue-instantsearch/vue3/es'

let app

fbAuth.onAuthStateChanged(_user => {
    // Only mount the app to the DOM if the user is not authenticated
    // This means once authenticted a browser refresh doesn't result into having to login again
    if (!app) {
        app = createApp(App)

        // It's crucial to first define tooltip, before mounting the app
        app.use(VTooltip, {
            defaultDelay: {
                show: 500,
                hide: 500
            }
            // classes: 'bg-primary-blue-900 text-white'
        })
        app.use(InstantSearch)

        app.use(router).mount('#app')
    }
})

And this is a summary of my component:

<template>
  ...
  <ais-instant-search :search-client="searchClient" index-name="companyIndex">
    <ais-search-box />
    <ais-hits>
      <template v-slot:item="{ item }">
        <h2>{{ item.name }}</h2>
      </template>
    </ais-hits>
  </ais-instant-search>
  ...
</template>

<script>
import algoliasearch from 'algoliasearch/lite'
import { AisInstantSearch, AisSearchBox } from 'vue-instantsearch/vue3/es'
...
export default {
  name: 'Search',
  components: {
    AisInstantSearch,
    AisSearchBox,
    ...
  },
  props: [...],
  setup(props) {
    ...
    const searchClient = algoliasearch(
      '#######',
      '#######'
    )
    ...
    return {
      ...
      searchClient,
      ...
    }
  }
}
</script>

What am I doing wrong?


Solution

  • I finally figured out the issue: it was the vue version. It needs to be at least 3.1.2 for vue-instantsearch to work and I had it on 3.0.0! To update to a greater version, you need to specify the right version for the vue compiler. At this moment the latest version is 3.2.20. To upgrade to this version, do this setting in package.json:

      "devDependencies": {
         ...
        "@vue/compiler-sfc": "^3.2.20"
       }
    

    then run npm install and run your project to get it compiled to that vue version.