Skip to main content
The Polygon component draws a polygon (a closed shape) on the map. Both Polygon and PolygonF variants are available and functionally identical.

Import

import { Polygon } from '@react-google-maps/api'
// or
import { PolygonF } from '@react-google-maps/api'

Basic Usage

import { GoogleMap, Polygon } from '@react-google-maps/api'

function MyMap() {
  const triangleCoords = [
    { lat: 40.7128, lng: -74.0060 },
    { lat: 40.7580, lng: -73.9855 },
    { lat: 40.7489, lng: -73.9680 }
  ]

  return (
    <GoogleMap
      center={{ lat: 40.7489, lng: -73.9680 }}
      zoom={12}
    >
      <Polygon paths={triangleCoords} />
    </GoogleMap>
  )
}

Props

path
google.maps.MVCArray<google.maps.LatLng> | google.maps.LatLng[] | google.maps.LatLngLiteral[]
The ordered sequence of coordinates for a simple polygon.Example: [{ lat: 40.7128, lng: -74.0060 }, { lat: 40.7580, lng: -73.9855 }]
paths
google.maps.MVCArray | google.maps.LatLng[] | google.maps.LatLng[][] | google.maps.LatLngLiteral[] | google.maps.LatLngLiteral[][]
The paths property can define a single polygon or multiple polygons (for polygons with holes). Use this for complex polygons.
options
google.maps.PolygonOptions
Additional polygon options including stroke and fill styling.
draggable
boolean
Whether the polygon can be dragged by the user.Default: false
editable
boolean
Whether the polygon can be edited by dragging control points.Default: false
visible
boolean
Whether the polygon is visible.Default: true

Events

onClick
(e: google.maps.MapMouseEvent) => void
Fired when the polygon is clicked.
onDblClick
(e: google.maps.MapMouseEvent) => void
Fired when the polygon is double-clicked.
onDrag
(e: google.maps.MapMouseEvent) => void
Fired repeatedly while the polygon is being dragged.
onDragStart
(e: google.maps.MapMouseEvent) => void
Fired when dragging starts.
onDragEnd
(e: google.maps.MapMouseEvent) => void
Fired when dragging ends.
onEdit
(polygon: google.maps.Polygon) => void
Fired when the polygon’s path is edited (points added, removed, or moved).
onMouseMove
(e: google.maps.MapMouseEvent) => void
Fired when the mouse moves over the polygon.
onMouseOver
(e: google.maps.MapMouseEvent) => void
Fired when the mouse enters the polygon.
onMouseOut
(e: google.maps.MapMouseEvent) => void
Fired when the mouse leaves the polygon.
onMouseDown
(e: google.maps.MapMouseEvent) => void
Fired when the mouse button is pressed on the polygon.
onMouseUp
(e: google.maps.MapMouseEvent) => void
Fired when the mouse button is released on the polygon.
onRightClick
(e: google.maps.MapMouseEvent) => void
Fired when the polygon is right-clicked.
onLoad
(polygon: google.maps.Polygon) => void
Callback invoked when the polygon instance has loaded.
onUnmount
(polygon: google.maps.Polygon) => void
Callback invoked when the polygon is unmounted.

Examples

Styled Polygon

import { Polygon } from '@react-google-maps/api'

function StyledPolygon() {
  const paths = [
    { lat: 40.7128, lng: -74.0060 },
    { lat: 40.7580, lng: -73.9855 },
    { lat: 40.7489, lng: -73.9680 },
    { lat: 40.7200, lng: -73.9700 }
  ]

  const options = {
    fillColor: '#FF0000',
    fillOpacity: 0.35,
    strokeColor: '#FF0000',
    strokeOpacity: 0.8,
    strokeWeight: 2
  }

  return <Polygon paths={paths} options={options} />
}

Editable Polygon

import { useState } from 'react'
import { Polygon } from '@react-google-maps/api'

function EditablePolygon() {
  const [paths, setPaths] = useState([
    { lat: 40.7128, lng: -74.0060 },
    { lat: 40.7580, lng: -73.9855 },
    { lat: 40.7489, lng: -73.9680 }
  ])

  return (
    <Polygon
      paths={paths}
      editable={true}
      draggable={true}
      onEdit={(polygon) => {
        const newPath = polygon.getPath()
        const coordinates = []
        for (let i = 0; i < newPath.getLength(); i++) {
          const point = newPath.getAt(i)
          coordinates.push({
            lat: point.lat(),
            lng: point.lng()
          })
        }
        setPaths(coordinates)
        console.log('Updated polygon:', coordinates)
      }}
    />
  )
}

Polygon with Hole

<Polygon
  paths={[
    // Outer boundary
    [
      { lat: 40.7200, lng: -74.0100 },
      { lat: 40.7600, lng: -74.0100 },
      { lat: 40.7600, lng: -73.9600 },
      { lat: 40.7200, lng: -73.9600 }
    ],
    // Inner hole
    [
      { lat: 40.7350, lng: -73.9950 },
      { lat: 40.7450, lng: -73.9950 },
      { lat: 40.7450, lng: -73.9750 },
      { lat: 40.7350, lng: -73.9750 }
    ]
  ]}
  options={{
    fillColor: '#0000FF',
    fillOpacity: 0.35,
    strokeColor: '#0000FF',
    strokeWeight: 2
  }}
/>

Interactive Polygon

import { useState } from 'react'
import { GoogleMap, Polygon } from '@react-google-maps/api'

function InteractivePolygon() {
  const [selected, setSelected] = useState(false)
  
  const area = [
    { lat: 40.7128, lng: -74.0060 },
    { lat: 40.7580, lng: -73.9855 },
    { lat: 40.7489, lng: -73.9680 },
    { lat: 40.7200, lng: -73.9700 }
  ]

  return (
    <GoogleMap center={area[0]} zoom={12}>
      <Polygon
        paths={area}
        options={{
          fillColor: selected ? '#00FF00' : '#FF0000',
          fillOpacity: selected ? 0.5 : 0.35,
          strokeColor: selected ? '#00FF00' : '#FF0000',
          strokeWeight: selected ? 3 : 2
        }}
        onClick={() => setSelected(!selected)}
        onMouseOver={() => console.log('Mouse over polygon')}
      />
    </GoogleMap>
  )
}

Multiple Polygons (Zones)

import { Polygon } from '@react-google-maps/api'

function MultipleZones() {
  const zones = [
    {
      id: 'zone-1',
      name: 'Red Zone',
      paths: [
        { lat: 40.7128, lng: -74.0060 },
        { lat: 40.7280, lng: -74.0060 },
        { lat: 40.7280, lng: -73.9860 },
        { lat: 40.7128, lng: -73.9860 }
      ],
      color: '#FF0000'
    },
    {
      id: 'zone-2',
      name: 'Blue Zone',
      paths: [
        { lat: 40.7380, lng: -74.0060 },
        { lat: 40.7530, lng: -74.0060 },
        { lat: 40.7530, lng: -73.9860 },
        { lat: 40.7380, lng: -73.9860 }
      ],
      color: '#0000FF'
    }
  ]

  return (
    <>
      {zones.map((zone) => (
        <Polygon
          key={zone.id}
          paths={zone.paths}
          options={{
            fillColor: zone.color,
            fillOpacity: 0.35,
            strokeColor: zone.color,
            strokeWeight: 2
          }}
          onClick={() => console.log(`Clicked ${zone.name}`)}
        />
      ))}
    </>
  )
}

Heatmap-style Polygons

const densityLevels = [
  { paths: [...], density: 'high', color: '#FF0000' },
  { paths: [...], density: 'medium', color: '#FFA500' },
  { paths: [...], density: 'low', color: '#00FF00' }
]

return (
  <>
    {densityLevels.map((level, index) => (
      <Polygon
        key={index}
        paths={level.paths}
        options={{
          fillColor: level.color,
          fillOpacity: 0.4,
          strokeColor: level.color,
          strokeWeight: 1
        }}
      />
    ))}
  </>
)

Draggable Area Selector

import { useState } from 'react'
import { Polygon } from '@react-google-maps/api'

function AreaSelector() {
  const [area, setArea] = useState([
    { lat: 40.7128, lng: -74.0060 },
    { lat: 40.7280, lng: -74.0060 },
    { lat: 40.7280, lng: -73.9860 },
    { lat: 40.7128, lng: -73.9860 }
  ])

  return (
    <Polygon
      paths={area}
      draggable={true}
      editable={true}
      options={{
        fillColor: '#4285F4',
        fillOpacity: 0.25,
        strokeColor: '#4285F4',
        strokeWeight: 2,
        strokeOpacity: 0.8
      }}
      onDragEnd={() => console.log('Area moved')}
      onEdit={(polygon) => {
        console.log('Area edited')
      }}
    />
  )
}

Common Options

The options prop accepts a google.maps.PolygonOptions object with properties including:
  • fillColor - Fill color (hex string)
  • fillOpacity - Fill opacity (0.0 - 1.0)
  • strokeColor - Border color (hex string)
  • strokeWeight - Border width in pixels
  • strokeOpacity - Border opacity (0.0 - 1.0)
  • geodesic - Whether edges follow the curvature of the Earth
  • zIndex - Stack order of the polygon

Path vs Paths

  • Use path for simple polygons (single boundary)
  • Use paths for complex polygons with holes or multiple areas

Component Variants

Both Polygon and PolygonF are available and functionally identical:
  • Polygon - Default export
  • PolygonF - Functional component variant (same implementation)
import { Polygon } from '@react-google-maps/api'
// or
import { PolygonF } from '@react-google-maps/api'

Build docs developers (and LLMs) love