Skip to main content
You can use Algolia’s geographical search capabilities with the connectGeoSearch connector.

Working example

The complete source code of the example on this page is available on GitHub.
This code has been specifically created for Vue 2. Some modifications may be required for it to work correctly in Vue 3.
The demo is built with Google Maps but the core logic isn’t tied to any map provider You can build your own map widget with a different provider (such as Leaflet). This guide uses the vue-googlemaps library to access Google Maps.

Dataset

This guide use a dataset of over 3,000 records of the biggest airports in the world.
JSON
{
  "objectID": "3797",
  "name": "John F Kennedy Intl",
  "city": "New York",
  "country": "United States",
  "iata_code": "JFK",
  "links_count": 911,
  "_geoloc": {
    "lat": 40.639751,
    "lng": -73.778925
  }
}
Latitude and longitude are stored in the record to allow hits to be displayed on the map. You should store them in the _geoloc attribute to enable geo-filtering and geo-sorting. You can download the dataset on GitHub. Have a look at how to import it in Algolia.

Configure index settings

When displaying on a map, you still want the relevance to be good. For that, configure the index as follows:
  • Searchable attributes should be set to enable search in the four textual attributes: name, city, country, and iata_code.
  • Custom ranking: use the number of other connected airports links_count as a ranking metric. The more connections the better.
$index->setSettings([
  'searchableAttributes' => ['name', 'city', 'country', 'iata_code'],
  'customRanking' => ['desc(links_count)']
]);

Displaying hits

1

Add the Google Maps library

JavaScript
// main.js
import "vue-googlemaps/dist/vue-googlemaps.css";
import VueGoogleMaps from "vue-googlemaps";

Vue.use(VueGoogleMaps, {
  load: {
    // Your Google API key
    apiKey: "AIxxxxx",
  },
});
2

Create a custom widget

Create a custom widget for Vue InstantSearch, using connectGeoSearch :
<script>
import { createWidgetMixin } from 'vue-instantsearch/vue3/es';
import { connectGeoSearch } from 'instantsearch.js/es/connectors';

export default {
  mixins: [createWidgetMixin({ connector: connectGeoSearch })],
};
</script>

3

Add map to the template

Now that you have access to the data from the Geo Search connector, you want to add a regular map in the template.
To make the map actually visible, give the map element a height with CSS.
Vue
<template>
  <div v-if="state" class="ais-GeoSearch">
    <googlemaps-map
      :center="center"
      :zoom.sync="zoom"
      class="ais-GeoSearch-map"
    >
    </googlemaps-map>
  </div>
</template>

<script>
export default {
  data() {
    return {
      center: { lat: 0, lng: 0 },
      zoom: 12,
    };
  },
};
</script>
4

Display results

Loop over this.state.items to display the search results:
<template>
  <div v-if="state" class="ais-GeoSearch">
    <googlemaps-map
      :center="center"
      :zoom.sync="zoom"
      class="ais-GeoSearch-map"
    >
      <googlemaps-marker
        v-for="item of state.items"
        :key="item.objectID"
        :title="item.name"
        :position="item._geoloc"
      />
    </googlemaps-map>
  </div>
</template>

<script>
import { createWidgetMixin } from 'vue-instantsearch/vue3/es';
import { connectGeoSearch } from 'instantsearch.js/es/connectors';

export default {
  mixins: [createWidgetMixin({ connector: connectGeoSearch })],
  data() {
    return {
      zoom: 12,
    };
  },
  computed: {
    center() {
      return this.state.items[0]._geoloc;
    },
  },
};
</script>

Going further

This guide only explains how to display hits on a map, but connectGeoSearch connector has more features, such as refining the search when the map moves and automatically centering on the correct items. Feel free to explore the options given to state from the connector to make these experiences.