> ## Content Index
> Fetch the complete content index at: https://blog.afi.io/llms.txt
> Use this file to discover other available public pages before exploring further.

# Google reverse geocoding: Get addresses from coordinates
- URL: https://blog.afi.io/blog/google-reverse-geocoding-get-addresses-from-coordinates/
- Published: 2025-07-26T13:33:17.000Z
- Updated: 2026-08-21T05:15:37.000Z
- Description: Learn how to use the Google Geocoding API for reverse geocoding - convert GPS coordinates into human readable addresses.
- Author: Afian Anwar
- Tags: googlemaps

Reverse geocoding is the process of converting geographic coordinates (latitude and longitude) into a human readable address. In this blog post, I’ll show you how to use the [Google Geocoding API](https://developers.google.com/maps/documentation/geocoding?ref=blog.afi.io) to reverse geocode latitude and longitude coordinates into a clean, formatted address and display it on a map. 

![What we'll build - a reverse geocoding demo app that used the Google Geocoding API](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2025/07/Google-Geocode-3.png)

What we'll build - a reverse geocoding demo app that used the Google Geocoding API

Part 1: [A practical guide to the Google Geocoding API](https://blog.afi.io/blog/a-practical-guide-to-the-google-geocoding-api/)  
Part 2: [Forward geocoding with the Google Geocoding API](https://www.afi.io/blog/forward-geocoding-with-the-google-geocoding-api/?ref=blog.afi.io)  
**Part 3: Google reverse geocoding: Get addresses from coordinates (this article)**  
Part 4: [Fix bad addresses with the Google Address Validation API](https://blog.afi.io/blog/fix-bad-addresses-with-the-google-address-validation-api/)  
Part 5: [Google Maps Building Outlines and Entrances API](https://blog.afi.io/blog/google-maps-building-outlines-and-entrances-api/)

As with our other tutorials, we'll use what we've learned to build a simple demo app ([https://google-reverse-geocoding.afi.dev/](https://google-reverse-geocoding.afi.dev/?ref=blog.afi.io)). Code ([frontend](https://github.com/afilabs/google%5Freverse%5Fgeocoding?ref=blog.afi.io) / [backend](https://github.com/afilabs/google%5Fgeocoding%5Fbackend?ref=blog.afi.io)) for this project is available for free on GitHub.

[Google Reverse Geocoding DemoHow to use the Google Geocoding API to convert geographic coordinates into addresses![](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/icon/logo192-35.png)![](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/thumbnail/logo512-40.png)](https://google-reverse-geocoding.afi.dev/?ref=blog.afi.io)

### What is reverse geocoding?

Reverse geocoding turns any latitude and longitude pair into a structured, human readable address or place name, known as a reverse geocode. It’s the inverse of forward geocoding, which transforms addresses into geographic coordinates.

![](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2025/07/Screenshot-2025-07-18-at-2.09.57---PM.png)

When you send a pair of coordinates to the reverse geocoding endpoint of the [Google Geocoding API](https://developers.google.com/maps/documentation/geocoding?ref=blog.afi.io), Google matches them to the closest known feature in its geospatial database and returns a complete, display-ready address string. It's a technology thats widely used on social media apps for geotagging photos, recommending content and grouping posts based on neighborhoods, cities, or landmarks.

![Reverse geocoding used in Instagram to automatically location tag posts](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2025/07/image-11.png)

Reverse geocoding used in Instagram to automatically location tag posts

### Google Geocoding API example (reverse geocoding)

Here's a simple geocoding example that returns an address string for 49.2846966, -123.1119349 in downtown Vancouver.

**Endpoint**: `GET`

[https://maps.googleapis.com/maps/api/geocode/json?](https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&key=YOUR%5FAPI%5FKEY&ref=blog.afi.io)  
[latlng={LATLNG}&](https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&key=YOUR%5FAPI%5FKEY&ref=blog.afi.io)  
[key={YOUR\_API\_KEY](https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&key=YOUR%5FAPI%5FKEY&ref=blog.afi.io)}

**{LATLNG}** is the comma separated latitude and longitude coordinates of the location you want to convert into the nearest human readable address.

**{YOUR\_API\_KEY}** is your Google Maps API key with the Google Geocoding API enabled.

**Endpoint:** `GET`

```
https://maps.googleapis.com/maps/api/geocode/json?latlng=49.2846966,-123.1119349&key={YOUR_API_KEY}
```

**Response**

```
{
    "plus_code": {
        "compound_code": "7VMQ+V6G Vancouver, BC, Canada",
        "global_code": "84XR7VMQ+V6G"
    },
    "results": [
        
        {
            "address_components": [
                //... address components array
            ],
            "formatted_address": "555 W Hastings St, Vancouver, BC V6B 4N4, Canada",
            "geometry": {
                "bounds": {
                    "northeast": {
                        "lat": 49.2851751,
                        "lng": -123.111479
                    },
                    "southwest": {
                        "lat": 49.28441489999999,
                        "lng": -123.1126507
                    }
                },
                "location": {
                    "lat": 49.2844998,
                    "lng": -123.1128788
                },
                "location_type": "ROOFTOP",
                "viewport": {
                    "northeast": {
                        "lat": 49.28614398029149,
                        "lng": -123.1107158697085
                    },
                    "southwest": {
                        "lat": 49.28344601970849,
                        "lng": -123.1134138302915
                    }
                }
            },
            "navigation_points": [
                {
                    "location": {
                        "latitude": 49.2845048,
                        "longitude": -123.1124829
                    }
                }
            ],
            "place_id": "ChIJUcKFZ3hxhlQREJGVU1foPaE",
            "types": [
                "premise",
                "street_address"
            ]
        },
        //... 14 more entries
    ],
    "status": "OK"
}
```

Just like with [forward geocoding](https://developers.google.com/maps/documentation/geocoding/requests-geocoding?ref=blog.afi.io), the response to the [reverse geocoding](https://developers.google.com/maps/documentation/geocoding/requests-reverse-geocoding?ref=blog.afi.io) endpoint of the [Google Geocoding API](https://developers.google.com/maps/documentation/geocoding?ref=blog.afi.io) is an array, `results`. Unlike forward geocoding though, reverse geocoding typically returns multiple results, ranked from most precise to least precise - starting with the exact street address and followed by broader regions like neighborhoods, cities, counties, and states. In the response above, 15 locations were returned:

1. `street_address` 1200-555 W Hastings St, Vancouver, BC V6B 4N6, Canada
2. `street_address` `premise` 555 W Hastings St, Vancouver, BC V6B 4N4, Canada

...

1. `city` `political` Vancouver, BC, Canada
2. `administrative_area_level_2` `political` Metro Vancouver, BC, Canada
3. `administrative_area_level_1` `political` British Columbia, Canada
4. `country` `political` Canada

From the list above, you can see that the geocoded point may be denoted as a `street_address`, a `city` (Vancouver), a province `administrative_level_1` (British Columbia) or as a `country` (Canada). All are "addresses" to the geocoder. Which one you use depends on your needs. For deliveries or field services, you'll want exact street level accuracy. But for tasks like geospatial analytics, a more general "address" - like a postal code or district, might be enough.

![Reverse geocoded addresses are not necessarily at the input coordinates location](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2025/07/Screenshot-2025-07-22-at-10.18.49---PM.png)

Reverse geocoded addresses are not necessarily at the input coordinates location

An interesting detail about reverse geocoding is that the returned address (reverse geocode) isn’t always located exactly at the input coordinates - it’s often the nearest known address instead. The easiest way to illustrate this is by reverse geocoding coordinates in the ocean (picture above) and notice how the returned address appears on the nearest shoreline. 

In each `result` object:

The `formatted_address` field contains the complete, human readable version of the address - exactly how you’d write it for mailing purposes, such as on a letter or postcard.

The `types` field is an array that describes the categories associated with the geocoded result. Most addresses belong to multiple types. For instance, “Vancouver, Canada” is labeled as both `locality` and `political`, indicating that it functions as a city and also as a recognized political region.

The `geometry` object contains geographic details about the geocoded result, specifically:

- `location`, which contains the exact `location.lat` and `location.lng` of the place,

```
{
    "location": {
        "lat": 49.2846966,
        "lng": -123.1119349
    }
}
```

- `location_type`, which indicates the accuracy of the geocoded result.
  - "ROOFTOP" means the result is highly precise, accurate down to a specific street address.
  - "RANGE\_INTERPOLATED" and "APPROXIMATE" suggest the location is estimated and less reliable.

The `place_id` ([docs](https://developers.google.com/maps/documentation/places/web-service/place-id?ref=blog.afi.io)) is a unique identifier assigned by Google Maps to a specific place. You can use this ID to look up more detailed information about the location, such as photos, user ratings, and reviews.

### Filtering reverse geocoding results by type

Because the reverse geocoding endpoint returns multiple addresses - ranging from a precise street address to broader areas like neighborhoods, cities, and states, it's important to filter the results by precision to fit your use case.

For example, if you are using reverse geocoding to show where a delivery occurred, you would want to use a result with the "street\_address" `type`. If you are using it to tag photos, broader `types` like "neighborhood" or "locality" might be more appropriate.

To filter by type, add the `result_type` parameter to the Google Geocoding API call like so:

```
https://maps.googleapis.com/maps/api/geocode/json?latlng=49.2846966,-123.1119349&key={YOUR_API_KEY}&result_type=street_address
```

Including `result_type=street_address` in your request filters the response to only include results of the `type` "street\_address". Note that `result_type` doesn't limit the search itself - instead, it acts as a post-processing filter. The API retrieves all possible results for the given coordinates, then removes any that don’t match the specified `type`.

### Building a Google Maps reverse geocoding demo app

In this final section, we’ll build a web app ([https://google-reverse-geocoding.afi.dev/](https://google-reverse-geocoding.afi.dev/?ref=blog.afi.io)) using the reverse geocoding endpoint of the [Google Geocoding API](https://developers.google.com/maps/documentation/geocoding?ref=blog.afi.io) to better understand how reverse geocoding works. Users can drag and drop a marker anywhere on a Google Map to retrieve the `formatted_address` of the nearest reverse geocode. A blue circle icon will indicate the location of that address. This app highlights how the input coordinates and the returned reverse geocode location can sometimes differ - often significantly.

### How our code is structured

[google\_reverse\_geocoding](https://github.com/afilabs/google%5Freverse%5Fgeocoding?ref=blog.afi.io) is a single page React app that uses Vite as the build tool and development server. The app works together with [google\_geocoding\_backend](https://github.com/afilabs/google%5Fgeocoding%5Fbackend?ref=blog.afi.io), which retrieves reverse geocode data from the [Google Geocoding API](https://developers.google.com/maps/documentation/geocoding/overview?ref=blog.afi.io). As with our other tutorials, we'll be using the super useful Google Maps React component library from [@vis.gl/react-google-maps](https://visgl.github.io/react-google-maps/?ref=blog.afi.io) to quickly scaffold our app and manage map interactions and UI in a way that is consistent with [React](https://react.dev/?ref=blog.afi.io). The `<Map/>`, `<DraggableMarker/>` and `<LocationMarker/> `components are examples of this.

**App.jsx**

`App.jsx` is the main entry point of the app. It manages the overall layout, routing, structure, and handles the call to the backend to perform reverse geocoding using the Google Geocoding API.

![The structure of our reverse geocoding demo app](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2025/07/image-13.png)

The structure of our reverse geocoding demo app

`App.jsx` has four main components:

1. `<SearchBox/>`, which holds the [Place Autocomplete](https://developers.google.com/maps/documentation/places/web-service/place-autocomplete?ref=blog.afi.io) text box (`<PlaceAutocompleteInput/>`) that is used to switch the map view to any location worldwide.
2. `<GoogleMap/>`, a React wrapper around the 2D Maps JavaScript API provided by the [@vis.gl/react-google-maps](https://visgl.github.io/react-google-maps/?ref=blog.afi.io) library.
3. `<DraggableMarker/>` and `<LocationMarker/>`, the marker components for the draggable red balloon pin and its corresponding reverse geocoded location (displayed on the map as a blue dot), and
4. `<InfoWindow/>`, a temporary overlay that shows up when `<DraggableMarker/>` is clicked. This pop up shows the `formatted_address` of the reverse geocoded pin location, together with the actual latitude and longitude of the pin marker.

```
/*** App.jsx ***/
import { APIProvider } from "@vis.gl/react-google-maps";
import { useState, useEffect } from "react";
import axios from "axios";

import GoogleMap from "~/components/GoogleMap";
import SearchBox from "~/components/SearchBox";

import "./App.scss";

function App() {
  const [autocompletePlace, setAutocompletePlace] = useState(null);
  const [reversePlace, setReversePlace] = useState(null);

  const handleSearchPlace = async ({ lat, lng }) => {
    const res = await axios.get(
      `${import.meta.env.VITE_API_URL}/reverse-geocode`,
      {
        params: { lat, lng },
      },
    );

    if (res.data && res.data.results) {
      const nearestPlace = res.data.results?.find((place) => !place.plus_code);
      setReversePlace(nearestPlace);
    }
  };

  const handleDragEnd = (location) => {
    handleSearchPlace(location);
  };
  // Reset reverse place
  useEffect(() => {
    if (autocompletePlace) {
      setReversePlace(autocompletePlace);
    }
  }, [autocompletePlace]);

  return (
    <APIProvider apiKey={import.meta.env.VITE_GOOGLE_API_KEY}>
      <div className="App">
        <SearchBox onSelectAutocompletePlace={setAutocompletePlace} />

        <GoogleMap
          autocompletePlace={autocompletePlace}
          reversePlace={reversePlace}
          onDragEnd={handleDragEnd}
        />
      </div>
    </APIProvider>
  );
}

export default App;

```

**SearchBox.jsx**

`SearchBox.jsx` is a basic presentational component that contains a text input field, implemented using the `<PlaceAutoCompleteInput/>` child component. The input is powered by [Google Place Autocomplete](https://developers.google.com/maps/documentation/places/web-service/legacy/autocomplete?ref=blog.afi.io), which allows users to quickly find and select addresses or place names.

```
/*** components/SearchBox.jsx ***
import { useMap, useMapsLibrary } from "@vis.gl/react-google-maps";
import { useCallback, useEffect, useState } from "react";

import Icon from "~/components/Icon";
import PlaceAutocompleteInput from "~/components/PlaceAutocompleteInput";
import "./SearchBox.scss";

const SearchBox = ({ onSelectAutocompletePlace }) => {
  const map = useMap();
  const googleMaps = useMapsLibrary("places");

  const [placeService, setPlaceService] = useState(null);

  useEffect(() => {
    if (googleMaps && map) {
      setPlaceService(new googleMaps.PlacesService(map));
    }
  }, [map, googleMaps]);

  const handlePlaceSelect = useCallback(
    (autocompletePlace) => {
      onSelectAutocompletePlace(autocompletePlace);
    },
    [placeService],
  );

  return (
    <div className="SearchBox">
      <label className="label">Location</label>

      <div className="input-group">
        <PlaceAutocompleteInput onPlaceSelect={handlePlaceSelect} />
        <Icon type="search" size={24} />
      </div>
    </div>
  );
};

export default SearchBox;

```

**PlaceAutocompleteInput.jsx**

The `<PlaceAutocompleteInput/>` component, as the name suggests, contains a text input field that uses [Google Places Autocomplete](https://blog.afi.io/blog/google-address-autocomplete-with-the-places-api/) to suggest places dynamically as the user types. When the user selects a place from the dropdown menu, Google triggers a `place_changed` event on the Autocomplete instance.

`PlaceAutocompleteInput.jsx` listens for this event and uses `getPlace()` to retrieve the selected place's details (`place_id`, `geometry`, `name`, and `formatted_address`), and saves it to an `autocompletePlace` object. This data is passed on to its parent component via the `onPlaceSelect()` prop and eventually passed to `App.jsx` where it is saved in state. 

```
/*** components/PlaceAutocomepleteInput.jsx ***
import { useMapsLibrary } from "@vis.gl/react-google-maps";
import { useEffect, useRef, useState } from "react";

const PlaceAutocompleteInput = ({ onPlaceSelect }) => {
  const [placeAutocomplete, setPlaceAutocomplete] = useState(null);
  const inputRef = useRef(null);
  const places = useMapsLibrary("places");

  useEffect(() => {
    if (!places || !inputRef.current) return;

    const options = {
      fields: ["place_id", "geometry", "name", "formatted_address"],
    };

    setPlaceAutocomplete(new places.Autocomplete(inputRef.current, options));
  }, [places]);

  useEffect(() => {
    if (!placeAutocomplete) return;

    placeAutocomplete.addListener("place_changed", () => {
      onPlaceSelect(placeAutocomplete.getPlace());
    });
  }, [onPlaceSelect, placeAutocomplete]);

  return (
    <div className="PlaceAutocompleteInput">
      <input ref={inputRef} />
    </div>
  );
};

export default PlaceAutocompleteInput;
```

**GoogleMap.jsx**

`GoogleMap.jsx`, found in `components/GoogleMap/index.jsx`, is a React component that displays a full screen Google Map using the [@vis.gl/react-google-maps](https://visgl.github.io/react-google-maps/?ref=blog.afi.io) library. It handles three main tasks:

1. Centers the map at a new location whenever `autocompletePlace` is updated.
2. Displays a draggable red pin marker and a blue circle icon at the location of `reversePlace`.
3. Calls the `handleDragEnd()` function (passed through the `onDragEnd` prop) when the user finishes dragging the red pin marker.

```
/*** components/GoogleMap/index.jsx ***
import { Map } from "@vis.gl/react-google-maps";

import MapHandler from "./MapHandler";
import LocationMarker from "./LocationMarker";
import DraggableMarker from "./DraggableMarker";

const DEFAULT_CENTER = { lat: 49.25307278849622, lng: -123.12095840000302 };

const GoogleMap = ({ autocompletePlace, reversePlace, onDragEnd }) => {
  return (
    <div className="GoogleMap">
      <Map
        style={{
          height: "100dvh",
          width: "100dvw",
        }}
        defaultZoom={12}
        mapId={import.meta.env.VITE_GOOGLE_MAP_ID}
        defaultCenter={DEFAULT_CENTER}
        gestureHandling="greedy"
        disableDefaultUI
        reuseMaps
      >
        <MapHandler place={autocompletePlace} />

        {reversePlace && (
          <LocationMarker key={reversePlace.place_id} place={reversePlace} />
        )}

        {autocompletePlace && (
          <DraggableMarker
            place={autocompletePlace}
            reversePlace={reversePlace}
            onDragEnd={onDragEnd}
          />
        )}
      </Map>
    </div>
  );
};

export default GoogleMap;

```

When `autocompletePlace` is not `null` (meaning the user has selected a location from the address autocomplete input), the red pin `<DraggableMarker/>` is displayed on the map. When a reverse geocoded location is available (i.e., `reversePlace` is not `null`), the blue circle icon from `<LocationMarker/>` is also shown.

**DraggableMarker.jsx**

![Drag and drop marker used to reverse geocoded any point on a Google Map](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2025/07/Screenshot-2025-07-23-at-1.03.42---PM.png)

Drag and drop marker used to reverse geocoded any point on a Google Map

`<DraggableMarker/>` uses the `<AdvancedMarker/>` component from the [@vis.gl/react-google-maps](https://visgl.github.io/react-google-maps/?ref=blog.afi.io)[ library](https://visgl.github.io/react-google-maps/?ref=blog.afi.io) as a wrapper for Google's [AdvancedMarkerElement](https://developers.google.com/maps/documentation/javascript/reference/advanced-markers?ref=blog.afi.io). It works seamlessly with React state, and re-renders intelligently when props like `position`, `zIndex`, or `children` change.

```
/*** components/GoogleMap/DraggableMarker.jsx ***/
<AdvancedMarker
  ref={markerRef}
  draggable={true}
  zIndex={2}
  position={position}
  onDragEnd={handleDragEnd}
  onClick={() => setInfoOpen((prev) => !prev)}
>
  <Pin />
</AdvancedMarker>;
```

In the return statement of `DraggableMarker.jsx`, we render an `<AdvancedMarker/>` with `draggable={true}`. This allows users to click and drag the marker on the map just as if you had set `marker.setDraggable(true)` in plain Javascript. Google Maps also automatically adds an “X” icon at the base of the marker on hover to indicate that the marker can be dragged, which is the default behavior from the Google Maps Javascript API’s [Web Components](https://mapsplatform.google.com/resources/blog/build-maps-faster-web-components/?ref=blog.afi.io) library.

When the user finishes dragging the marker - that is, when they drop it anywhere on the map - the `onDragEnd` event fires and `handleDragEnd()` is called. This function receives `e`, the event object from Google Maps which contains the marker’s new position. The state of `<DraggableMarker/>` is then updated with this new location using `setPosition(location)`, which sets it in place.

```
/*** components/GoogleMap/DraggableMarker.jsx ***/
const handleDragEnd = (e) => {
  const location = { lat: e.latLng.lat(), lng: e.latLng.lng() };
  setPosition(location);
  onDragEnd(location);
};

```

Finally, the location object is passed to `onDragEnd()`, a callback function provided via props from `App.jsx`. In `App.jsx`, `onDragEnd` points to `handleDragEnd` which in turn calls the `handleSearchPlace()` method, which is responsible for implementing an API loading wrapper design pattern to reverse geocode the coordinates in `location`.

```
/*** App.jsx ***/
const handleSearchPlace = async ({ lat, lng }) => {
  const res = await axios.get(
    `${import.meta.env.VITE_API_URL}/reverse-geocode`,
    {
      params: { lat, lng },
    },
  );

  if (res.data && res.data.results) {
    const nearestPlace = res.data.results?.find((place) => !place.plus_code);
    setReversePlace(nearestPlace);
  }
};

const handleDragEnd = (location) => {
  handleSearchPlace(location);
};

```

After receiving a response from the `/reverse-geocode` endpoint of [google\_geocoding\_backend](https://github.com/afilabs/google%5Fgeocoding%5Fbackend?ref=blog.afi.io), we loop through the results and select the first one that doesn’t include a `plus_code` property with `const nearestPlace = res.data.results?.find((place) => !place.plus_code);`. Since [Plus Codes](https://maps.google.com/pluscodes/?ref=blog.afi.io) are used for locations without traditional street addresses - and we’re looking for actual addresses - we skip those. Because reverse geocoding results are sorted by precision, this ensures we get the nearest and most relevant address for our marker’s location. The result is used to update the `reversePlace` state with the value of `nearestPlace`. 

`nearestPlace` is the closest human readable address to our marker coordinates. It's a [Geocoding Response Object](https://developers.google.com/maps/documentation/geocoding/requests-geocoding?ref=blog.afi.io#GeocodingResponses) with the following structure (we've seen it before in our earlier reverse geocoding example):

```
{
    "address_components": [
        //... address components array
    ],
    "formatted_address": "555 W Hastings St, Vancouver, BC V6G 3J4, Canada",
    "geometry": {
        "location": {
            "lat": 49.2844998,
            "lng": -123.1128788
        },
        "location_type": "ROOFTOP",
        // ... javascript object
    },
    "navigation_points": [
        //... javascript object
    ],
    "place_id": "ChIJw6AQfXhxhlQRSgv78ppPKXc",
    "types": [
        "street_address",
        "subpremise"
    ]
}
```

The `formatted_address` is used as the heading of the `<InfoWindow/>` component while its geographic coordinates (`geometry.location.lat` and `geometry.location.lng`) are used to position the blue circle `<LocationMarker/>` . In the example above, the reverse geocoded `nearestPlace` is actually across the street from the location of the draggable marker.

![Data returned by the reverse geocoding endpoint of the Google Geocoding API](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2025/07/image-14.png)

Data returned by the reverse geocoding endpoint of the Google Geocoding API

**LocationMarker.jsx**

Like `<DraggableMarker />`, `<LocationMarker />` is a wrapper around Google Map's [AdvancedMarkerElement](https://developers.google.com/maps/documentation/javascript/reference/advanced-markers?ref=blog.afi.io#AdvancedMarkerElement) class. However, instead of using the default red balloon pin like `<DraggableMarker />`, `<LocationMarker/>` displays a custom SVG icon styled as a blue circle.

```
/*** components/GoogleMap/LocationMarker.jsx ***/
import { AdvancedMarker, Pin } from "@vis.gl/react-google-maps";
import { useEffect, useState } from "react";

import Icon from "~/components/Icon";

import { getLatLng } from "~/utils";
import "./Marker.scss";

const LocationMarker = ({ place }) => {
  const [position, setPosition] = useState(() =>
    getLatLng(place.geometry.location),
  );

  return (
    <AdvancedMarker
      draggable={false}
      zIndex={1}
      position={getLatLng(place.geometry.location)}
    >
      <Icon type="marker" />
    </AdvancedMarker>
  );
};

export default LocationMarker;
```

Here's a detailed explanation of how this works:

1. The `<Icon/>` component returns an SVG element, and when nested inside an `<AdvancedMarker/>` element from [@vis.gl/react-google-maps](https://visgl.github.io/react-google-maps/?ref=blog.afi.io), React allows you to insert that SVG directly in to the map as a custom marker with your own design and styling.
2. `<Icon/>` is imported from `/components/Icon.jsx`, which returns an `<ImageSVG/>` taken from `/assets/index.js`.
3. `<Icon/>` was given a `type` prop of "marker". In `Icon.jsx`, the line `const ImageSVG = icons[type]` means that when `type` is "marker", `<ImageSVG/>` gets its data from `icons["marker"]`, which in `/assets/index.js` points to `assets/marker.svg`.
4. `marker.svg` was added to our app with the line `import marker from '~/assets/marker.svg?react'`. The `?react` appended at the end tells the build system to load the SVG as a React component, instead of a URL or an image file.
5. When rendered as an SVG, the marker is styled as a blue circle with a white border (below).

![SVG file imported into React used to create custom markers](https://storage.ghost.io/c/c6/4d/c64da7e8-63a6-4cff-acdc-2782a6ebc377/content/images/2025/07/Screenshot-2025-07-26-at-9.36.47---PM.png)

SVG file imported into React used to create custom markers

When the red `<DraggableMarker/>` is moved to a new position, the app calls the reverse geocoding endpoint of the Google Geocoding API again, and updates `reversePlace` with the new location.

### See reverse geocoding in action

To see reverse geocoding at work, head over to [https://google-reverse-geocoding.afi.dev/](https://google-reverse-geocoding.afi.dev/?ref=blog.afi.io) and enter an address or place name e.g. "Vancouver, BC" in the text field at the top left. Drag the marker around the map to see the reverse geocoded address and location details update in real time.

If you prefer to run the app locally:

1. Fork both [google\_reverse\_geocoding](https://github.com/afilabs/google%5Freverse%5Fgeocoding?ref=blog.afi.io) and [google\_geocoding\_backend](https://github.com/afilabs/google%5Fgeocoding%5Fbackend?ref=blog.afi.io) repositories on GitHub.
2. In [google\_geocoding\_backend](https://github.com/afilabs/google%5Fgeocoding%5Fbackend?ref=blog.afi.io), run `npm install` to install the dependencies followed by `npm start`.
3. In [google\_reverse\_geocoding](https://github.com/afilabs/google%5Freverse%5Fgeocoding?ref=blog.afi.io), run `npm install` followed by `vite run dev` to start the app. Open your browser to [http://localhost:3000/](http://localhost:3000/?ref=blog.afi.io) to view the app.

Remember to update the `.env` files in both folders with a Google Maps API key that has the [Google Geocoding API](https://developers.google.com/maps/documentation/geocoding/overview?ref=blog.afi.io) enabled.

### Coming up

In the next section, we'll touch on the [Google Address Validation API](https://developers.google.com/maps/documentation/address-validation/overview?ref=blog.afi.io), which is used to validate, correct, and standardize postal addresses according to official data sources. Unlike the Google Geocoding API, which tells you *where* an address is (or in reverse geocoding, what approximate address matches a set of coordinates), the Address Validation API checks whether an address is real, complete, and *deliverable -* in other words, if you mailed a letter to that address, it would actually arrive.

**This article was written by** [**Afi Labs**](https://afi.io/?ref=blog.afi.io)**, a** [**Google Maps Premier Partner**](https://www.afi.io/?ref=blog.afi.io) **and reseller. We build route optimization, navigation, and fleet tracking software on Google Maps, and offer volume pricing on GMP licensing.** [**Talk to an engineer**](https://www.afi.io/contact%5Fus?ref=blog.afi.io) **or** [**follow Afian on LinkedIn**](https://www.linkedin.com/in/afian-anwar/?ref=blog.afi.io)**.**

Next: Part 4: [Fix bad addresses with the Google Address Validation API](https://blog.afi.io/blog/fix-bad-addresses-with-the-google-address-validation-api/)