Is it possible to use multiple indexes with Nuxt? I'm attempting to search inside a sub component with a different index, but unfortunately Nuxt provides the asyncData hook only on pages and not standard components.
To get around this I'm hoping to pass a second index as a prop, but whenever I try to return two separate search stores in the asyncData method, I seem to overwrite the first store when trying to instantiating the second.
The other tactic i've tried is calling an async method on the mounted()hook per the Nuxt documentation, but that always returns an error that there is no data. I'm attempting something like this.
<script>
import {
createFromAlgoliaCredentials,
createFromSerialized
} from 'vue-instantsearch'
const searchStore = createFromAlgoliaCredentials(
'',
''
)
searchStore.indexName = 'Products'
export default {
data() {
return {
searchStore: null
}
},
mounted() {
this.startAlgolia()
},
created() {
this.searchStore = createFromSerialized(this.serializedSearchStore)
},
methods: {
async startAlgolia() {
searchStore.start()
await searchStore.waitUntilInSync()
return { serializedSearchStore: searchStore.serialize() }
}
}
}
</script>
Is there any example out there of implementing something like this? Thanks!
Hey @abattenburg, thanks for pinging us.
Can you confirm you are trying to have this all working with Server Side rendering?
In that case, the best example we have so far is: https://github.com/algolia/vue-instantsearch-examples/blob/master/examples/nuxt/pages/search.vue
However, SSR is definitely tricky. For now, I would recommend you always load the state from pages, because like you said, it's the only place where it works by default.
I'd gladly see the full repo if accessible.
Hi @rayrutjes, thanks for looking at this. Currently my setup is exactly like the link you put as an example. But instead of using just one index (searchStore.indexName = 'bestbuy' in this case), I would like to add a second index to be used on the same page. Maybe searchStore.indexName = 'bestbuy' and searchStore2.indexName = 'reviews' or something like that for example.
You have a good example here: https://github.com/algolia/vue-instantsearch-examples/blob/master/examples/multi-index/src/App.vue showing two indexes, but I'm having trouble using the same concept with SSR.
I can put together a repo if you would like, but my structure is pretty much exactly the same as the example you posted. Everything I had posted before, was just attempted work arounds to put two index's on one page. Sorry for the lack of context, and let me know if a repo would still be helpful. Thanks again for looking at this!
@abattenburg ,
I've adjusted the example as a POC:
<template>
<div>
<ais-index :searchStore="searchStore1" :auto-search="false"></ais-index>
<ais-index :searchStore="searchStore2" :auto-search="false"></ais-index>
</div>
</template>
<script>
import {
createFromAlgoliaCredentials,
createFromSerialized,
FACET_OR
} from "vue-instantsearch";
let store1, store2;
export default {
name: "search",
asyncData({ context, route }) {
store1 = createFromAlgoliaCredentials(
"latency",
"6be0576ff61c053d5f9a3225e2a90f76"
);
store1.indexName = "ikea";
// store1.query = route.params.query ? route.params.query : "";
store1.addFacet("colors", FACET_OR);
store1.highlightPreTag = "<mark>";
store1.highlightPostTag = "</mark>";
store1.start();
store1.refresh();
store2 = createFromAlgoliaCredentials(
"latency",
"6be0576ff61c053d5f9a3225e2a90f76"
);
store2.indexName = "ikea";
// store2.query = route.params.query ? route.params.query : "";
store2.addFacet("colors", FACET_OR);
store2.highlightPreTag = "<mark>";
store2.highlightPostTag = "</mark>";
store2.start();
store2.refresh();
return Promise.All([
store1.waitUntilInSync().then(() => {
context.state.searchStore1 = store1.serialize();
}),
store2.waitUntilInSync().then(() => {
context.state.searchStore2 = store2.serialize();
})
]);
},
beforeMount() {
if (!window.__INITIAL_STATE__) {
throw new Error("Not state was found.");
}
this.searchStore1 = createFromSerialized(
window.__INITIAL_STATE__.searchStore1
);
this.searchStore2 = createFromSerialized(
window.__INITIAL_STATE__.searchStore2
);
},
watch: {
// $route(to, from) {
// this.searchStore.query = this.$route.params.query
// ? this.$route.params.query
// : "";
// },
// "searchStore1.query"(to, from) {
// if (to.length === 0) {
// this.$router.push({ name: "home" });
// } else {
// this.$router.push({ name: "search", params: { query: to } });
// }
// }
},
data() {
return {
searchStore1: store1,
searchStore2: store2
};
}
};
</script>
In principle this should work.
I've commented out the parts that probably need some testing depending on your app and routing logic.
I hope that helps.
Great thank you so much! That's exactly what I was hoping for.
Most helpful comment
@abattenburg ,
I've adjusted the example as a POC:
In principle this should work.
I've commented out the parts that probably need some testing depending on your app and routing logic.
I hope that helps.