Feature 鈿★笍
Be able to use Multi Index Search in SSR version of InstantSearch 2 within Nuxt. It's a missing feature since 2.0 according to this https://github.com/algolia/vue-instantsearch/issues/348#issuecomment-338928514
Hi,
My proposal is use multi index with InstantSearchSsr, changing the injection $_ais to $_ais-indexname. The problem is that InstantSearchSrr component doesn't allow to set the injection name dynamically since props are not accessible inside inject, so it always inject the same index using $_ais.
The only solution I found was create the InstantSearchSrr component manually.
To avoid problems, I recommend add a new param (multiIndex) to instantSearchOptions in the file createInstantSearch:
const { searchClient, indexName, multiIndex } = instantSearchOptions;
Then edit the rootMixin to change $_ais name based in the index name, if multiIndex is set to true. That way it's only needed to create the custom component if enabled:
const rootMixin = {
provide() {
const name = multiIndex ? `$_ais-${indexName}` : '$_ais';
return {
// should be possible to configure this with {camelcase: ['error', {allow: ['^\\$_']}]}
// but that didn't work
// eslint-disable-next-line camelcase
[name]: search,
};
},
};
And export the function createInstantSearchComponent. So users area able to create their own InstantSearchSsr components:
export {
createInstantSearchComponent,
} from './util/createInstantSearchComponent';
I know it's not so practical as before, but works.
I made an example in CodeSandbox based on yours: https://codesandbox.io/s/zwvxqokz3l
You can also check my fork: https://github.com/JoaoPedroAS51/vue-instantsearch/
Thanks!
2.0.1
In your diff I see how you changed the injection, but I miss a change where it's reading (in rootMixin). Maybe I just missed it though, I haven't had time to look at the complete difference yet.
This is a really good idea by the way, I'd totally be open for a PR for fixing this!
Note that we are currently working on a future version of multi-index which no longer requires multiple instances of the root widget. However, this won't be ready for another few months.
Does the solution in your fork work for you completely?
Cool! Yes, it works perfectly for me!
So, the usage is basically create a new instant search and a new component for each index.
This is a part of the code in the CodeSandbox example
const searchClient = algoliasearch(
"latency",
"6be0576ff61c053d5f9a3225e2a90f76"
);
const {
instantsearch: instantsearch1,
rootMixin: rootMixin1
} = createInstantSearch({
searchClient,
indexName: "instant_search",
multiIndex: true
});
const {
instantsearch: instantsearch2,
rootMixin: rootMixin2
} = createInstantSearch({
searchClient,
indexName: "instant_search_price_desc",
multiIndex: true
});
export default {
mixins: [rootMixin1, rootMixin2],
async asyncData({ store }) {
const query = "iphone";
const algoliaState1 = await instantsearch1
.findResultsState({
query: query,
hitsPerPage: 8,
restrictSearchableAttributes: ["name"]
})
.then(() => instantsearch1.getState());
const algoliaState2 = await instantsearch2
.findResultsState({
query: query,
hitsPerPage: 8,
restrictSearchableAttributes: ["name"]
})
.then(() => instantsearch2.getState());
await store.commit("search/setQuery", query);
return { algoliaState1, algoliaState2 };
},
beforeMount() {
instantsearch1.hydrate(this.algoliaState1);
instantsearch2.hydrate(this.algoliaState2);
},
};
import { createInstantSearchComponent } from "vue-instantsearch";
export default createInstantSearchComponent({
name: "InstantSearchIndex",
inject: {
// should be possible to configure this with {camelcase: ['error', {allow: ['^\\$_']}]}
// but that didn't work
// eslint-disable-next-line camelcase
$_ais: {
from: "$_ais-instant_search",
default() {
throw new Error("`rootMixin` is required when using SSR.");
}
}
},
data() {
return {
instantSearchInstance: this.$_ais
};
},
render(createElement) {
return createElement(
"div",
{
class: {
[this.suit()]: true,
[this.suit("", "ssr")]: true
}
},
this.$slots.default
);
}
});
import { createInstantSearchComponent } from "vue-instantsearch";
export default createInstantSearchComponent({
name: "InstantSearchIndex2",
inject: {
// should be possible to configure this with {camelcase: ['error', {allow: ['^\\$_']}]}
// but that didn't work
// eslint-disable-next-line camelcase
$_ais: {
from: "$_ais-instant_search_price_desc",
default() {
throw new Error("`rootMixin` is required when using SSR.");
}
}
},
data() {
return {
instantSearchInstance: this.$_ais
};
},
render(createElement) {
return createElement(
"div",
{
class: {
[this.suit()]: true,
[this.suit("", "ssr")]: true
}
},
this.$slots.default
);
}
});
Ah yes, i forgot the rootmixin was dynamically created, and that you can easily have multiple.
Your solution of namespacing the provide totally makes sense to me.
I think when we merge this it should also be mentioned in the guide on ssr
I think when we merge this it should also be mentioned in the guide on ssr
Yes, this would be really useful.
I'm happy to help. I really love Algolia!
Hey @Haroenv, was this issue ever merged? I didn't find any information about it in the SSR guide for Nuxt.
@joaomarcelofm, this will be released with the next major version of Vue InstantSearch
@Haroenv I'm arriving a bit late, but is it possible to perform multi index search with SSR in nuxt with Vue InstantSearch 3 ?
Yes, with Vue InstantSearch v3 this works out of the box! please open a new issue with reproduction if anything isn't as expected
Most helpful comment
Yes, this would be really useful.
I'm happy to help. I really love Algolia!