Active url with vue-router for facet and queries

Hey folks,

I’m trying to create active routes for search queries and selected facet filters but getting this weird output and not sure how to clean it up. I followed the Vue-router example here: https://github.com/algolia/vue-instantsearch-examples/tree/master/examples/vue-router. The goal is to have a functioning url so links can be used to direct people to a pre-filtered search page.

This is what my url looks like:
/literatures#/search?query=&disjunctiveFacets%5B0%5D=supplier&disjunctiveFacets%5B1%5D=markets&disjunctiveFacets%5B2%5D=category&page=1&highlightPreTag=%3Cem%3E&highlightPostTag=%3C%2Fem%3E

I’m trying to get the default url to be just literature/search and then if you search in the input it adds ?query=Search+Term and then if a facet filter is selected to append &supplier=Supplier-Name&category=Category-Name

Thank you for any help
Josh

1 Like

Hi @jhamilton,

In case you missed it, we have a dedicated section in our docs that covers the URL synchronization with the Vue Router.

The example you are pointing at, is easy to setup, however gives very few liberties regarding what the URL actually looks like.

What you could do is follow the example of the docs, and add the facet as well in the same principle.

Let me know if you manage to make it work. Our docs on that part could use some re-working, so do not hesitate with us the code you have so far so that we can give a concrete example.

Cheers,

Thanks @rayrutjes for the reply, yeah I did see the doc example. I have it working like the example but am not a fan of all the extra “stuff” - disjunctiveFacets%5B0%5D in the URL (&disjunctiveFacets%5B0%5D=supplier&disjunctiveFacets%5B1%5D=markets&disjunctiveFacets%5B2%5D=category&page=1&highlightPreTag=%3Cem%3E&highlightPostTag=%3C%2Fem%3E) Would like to remove all that if possible

I’m a Newby to Vue so I’m stumbling through a bit :slight_smile:

Hi, @rayrutjes when you say “add the facet as well in the same principle” Could you help me understand what you mean? Not sure I follow.

Josh

Hi @jhamilton,

Sorry about the delay.

In order to better understand what you expect in terms of URL could you give me an example of good looking URL?

I understand you want to remove parts of it, but unsure which parts.

Cheers,

Morning @rayrutjes

Really trying to remove the unnessesary info: disjunctiveFacets%5B0%5D, highlightPreTag=%3Cem%3E&highlightPostTag=%3C%2Fem%3E in the URL - (&disjunctiveFacets%5B0%5D=supplier&disjunctiveFacets%5B1%5D=markets&disjunctiveFacets%5B2%5D=category&page=1&highlightPreTag=%3Cem%3E&highlightPostTag=%3C%2Fem%3E

It’s throwing all that in as the default when you hit the page instead of in our case /literature. What we are looking for is a url that just displays the query and facets that have been selected. So after you land on /literatures and type in the search field the query gets added to the url. /literatures?q=Acrylic

If a facet is selected it would do the same /literatures?FacetName=SelectedTerm then append the additional paramiters if selected. /literatures?FacetName=SelectedTerm&AnotherFacet=SelectedTerm

Hope that helps
Josh

Morning @rayrutjes, Any direction or advice on this or is it a limitation to Vue-InstantSearch?

Hello,

In order to parse and change the query, you will need to use the parseQuery and stringifyQuery to add your own mapping of the query and filters in the URL.

In the vue-router example you can follow this piece of code: https://github.com/algolia/vue-instantsearch-examples/blob/master/examples/vue-router/src/main.js#L22-L28

I hope this will help, feel free to ask us anything else.

Cheers, Maxime.

Thank you @iam4x! Before I saw your post I found a way to only display the query and facet in the url but did it through the watch.

watch: {
        'searchStore.queryParameters'(parameters) {
            const query = parameters;
            delete query.supplier;
            delete query.index;
            delete query.disjunctiveFacets;
            delete query.highlightPreTag;
            delete query.highlightPostTag;
            console.log(query.disjunctiveFacetsRefinements.supplier);
            if(query.disjunctiveFacetsRefinements.supplier != undefined){
                query.disjunctiveFacetsRefinements.supplier.forEach(function(element) {
                    if(query.supplier === undefined) {
                        query.supplier = element;
                    } else {
                        query.supplier = query.supplier + '-' + element;
                    }
                });

            }
            delete query.disjunctiveFacetsRefinements;
            if (query.query.length === 0 && query.supplier === undefined) {
                this.$router.push({ name: 'home' });
            } else {
                this.$router.push({ name: 'lit', query });
            }

I’m sure there is a cleaner way to do this but this is where I got to. If it’s better to go through the parseQuery and stringifyQuery method could you provide an example?

Hello @jhamilton

With the solution you found, it looks like you won’t be able to share the URL since you delete some parts of the search parameters from the query and you don’t have a way to parse them back.

You should go with parseQuery and stringifyQuery in order to keep the URL sharable:

  • parseQuery -> You get a query string and you should return an object
  • stringifyQuery -> The opposite of the parseQuery function

For instance:

import qs from 'qs';

[...]

parseQuery(queryString) {
  const params = qs.parse(queryString);

  // then you do your mapping of the params keys for vue-instantsearch to understand:
  params.bar = params.foo;
  delete params.foo;

  return params;
}

stringifyQuery(params) {
  params.foo = params.bar;
  delete params.bar;

  return qs.stringify(params);
}

In the above example I mapped the ?bar= to become ?foo= you can do the same with any query added from vue-instantsearch.

If your solution suit your use case it is still good to use :slight_smile:

Cheers, Maxime.

Thanks for the help @iam4x! We’ll give that a try and compare the results and see which route makes more sense.