Skip to main content
The Rectangle component draws a rectangle on the map defined by geographical bounds. Both Rectangle and RectangleF variants are available and functionally identical.

Import

import { Rectangle } from '@react-google-maps/api'
// or
import { RectangleF } from '@react-google-maps/api'

Basic Usage

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

function MyMap() {
  const bounds = {
    north: 40.7580,
    south: 40.7128,
    east: -73.9680,
    west: -74.0060
  }

  return (
    <GoogleMap
      center={{ lat: 40.7354, lng: -73.9870 }}
      zoom={12}
    >
      <Rectangle bounds={bounds} />
    </GoogleMap>
  )
}

Props

bounds
google.maps.LatLngBounds | google.maps.LatLngBoundsLiteral
The bounds of the rectangle.Example: { north: 40.7580, south: 40.7128, east: -73.9680, west: -74.0060 }
options
google.maps.RectangleOptions
Additional rectangle options including stroke and fill styling.
draggable
boolean
Whether the rectangle can be dragged by the user.Default: false
editable
boolean
Whether the rectangle can be edited by dragging control points.Default: false
visible
boolean
Whether the rectangle is visible.Default: true
clickable
boolean
Whether the rectangle responds to click events.Default: true

Events

onClick
(e: google.maps.MapMouseEvent) => void
Fired when the rectangle is clicked.
onDblClick
(e: google.maps.MapMouseEvent) => void
Fired when the rectangle is double-clicked.
onDrag
(e: google.maps.MapMouseEvent) => void
Fired repeatedly while the rectangle is being dragged.
onDragStart
(e: google.maps.MapMouseEvent) => void
Fired when dragging starts.
onDragEnd
(e: google.maps.MapMouseEvent) => void
Fired when dragging ends.
onBoundsChanged
() => void
Fired when the rectangle’s bounds change (via dragging or editing).
onMouseMove
(e: google.maps.MapMouseEvent) => void
Fired when the mouse moves over the rectangle.
onMouseOver
(e: google.maps.MapMouseEvent) => void
Fired when the mouse enters the rectangle.
onMouseOut
(e: google.maps.MapMouseEvent) => void
Fired when the mouse leaves the rectangle.
onMouseDown
(e: google.maps.MapMouseEvent) => void
Fired when the mouse button is pressed on the rectangle.
onMouseUp
(e: google.maps.MapMouseEvent) => void
Fired when the mouse button is released on the rectangle.
onRightClick
(e: google.maps.MapMouseEvent) => void
Fired when the rectangle is right-clicked.
onLoad
(rectangle: google.maps.Rectangle) => void
Callback invoked when the rectangle instance has loaded.
onUnmount
(rectangle: google.maps.Rectangle) => void
Callback invoked when the rectangle is unmounted.

Examples

Styled Rectangle

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

function StyledRectangle() {
  const bounds = {
    north: 40.7580,
    south: 40.7128,
    east: -73.9680,
    west: -74.0060
  }

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

  return <Rectangle bounds={bounds} options={options} />
}

Editable Rectangle

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

function EditableRectangle() {
  const [bounds, setBounds] = useState({
    north: 40.7580,
    south: 40.7128,
    east: -73.9680,
    west: -74.0060
  })

  return (
    <Rectangle
      bounds={bounds}
      editable={true}
      draggable={true}
      onBoundsChanged={() => {
        console.log('Bounds changed')
      }}
      onLoad={(rectangle) => {
        console.log('Rectangle loaded')
      }}
    />
  )
}

Interactive Area Selector

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

function AreaSelector() {
  const [bounds, setBounds] = useState({
    north: 40.7580,
    south: 40.7128,
    east: -73.9680,
    west: -74.0060
  })
  const [area, setArea] = useState(0)

  const calculateArea = (bounds) => {
    const latDiff = bounds.north - bounds.south
    const lngDiff = bounds.east - bounds.west
    // Simplified area calculation
    return Math.abs(latDiff * lngDiff * 111 * 111) // Approximate km²
  }

  return (
    <div>
      <div>Selected Area: {area.toFixed(2)} km²</div>
      <GoogleMap center={{ lat: 40.7354, lng: -73.9870 }} zoom={12}>
        <Rectangle
          bounds={bounds}
          editable={true}
          draggable={true}
          options={{
            fillColor: '#4285F4',
            fillOpacity: 0.25,
            strokeColor: '#4285F4',
            strokeWeight: 2
          }}
          onLoad={(rectangle) => {
            setArea(calculateArea(rectangle.getBounds()?.toJSON() || bounds))
          }}
          onBoundsChanged={() => {
            // Note: In real implementation, you'd get bounds from the instance
            setArea(calculateArea(bounds))
          }}
        />
      </GoogleMap>
    </div>
  )
}

Highlighting Map Region

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

function HighlightRegion() {
  const [hovering, setHovering] = useState(false)

  const bounds = {
    north: 40.7580,
    south: 40.7128,
    east: -73.9680,
    west: -74.0060
  }

  return (
    <Rectangle
      bounds={bounds}
      options={{
        fillColor: hovering ? '#00FF00' : '#FF0000',
        fillOpacity: hovering ? 0.5 : 0.35,
        strokeColor: hovering ? '#00FF00' : '#FF0000',
        strokeWeight: hovering ? 3 : 2
      }}
      onMouseOver={() => setHovering(true)}
      onMouseOut={() => setHovering(false)}
      onClick={() => console.log('Region clicked')}
    />
  )
}

Multiple Zones

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

function MultipleZones() {
  const zones = [
    {
      id: 'zone-1',
      name: 'Downtown',
      bounds: { north: 40.7580, south: 40.7128, east: -73.9680, west: -74.0060 },
      color: '#FF0000'
    },
    {
      id: 'zone-2',
      name: 'Midtown',
      bounds: { north: 40.7780, south: 40.7580, east: -73.9680, west: -74.0060 },
      color: '#0000FF'
    },
    {
      id: 'zone-3',
      name: 'Uptown',
      bounds: { north: 40.7980, south: 40.7780, east: -73.9680, west: -74.0060 },
      color: '#00FF00'
    }
  ]

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

Draggable Coverage Area

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

function CoverageArea() {
  const [bounds, setBounds] = useState({
    north: 40.7580,
    south: 40.7128,
    east: -73.9680,
    west: -74.0060
  })

  return (
    <Rectangle
      bounds={bounds}
      draggable={true}
      options={{
        fillColor: '#4285F4',
        fillOpacity: 0.2,
        strokeColor: '#4285F4',
        strokeWeight: 2,
        strokeOpacity: 0.8
      }}
      onDragEnd={() => {
        console.log('Coverage area moved')
      }}
    />
  )
}

Search Result Bounding Box

<Rectangle
  bounds={{
    north: searchResult.viewport.northeast.lat,
    south: searchResult.viewport.southwest.lat,
    east: searchResult.viewport.northeast.lng,
    west: searchResult.viewport.southwest.lng
  }}
  options={{
    fillColor: 'transparent',
    strokeColor: '#FF0000',
    strokeWeight: 2,
    strokeOpacity: 0.8
  }}
/>

Common Options

The options prop accepts a google.maps.RectangleOptions 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)
  • zIndex - Stack order of the rectangle
  • clickable - Whether the rectangle responds to clicks

Bounds Format

The bounds prop accepts:
// Literal object
{
  north: number,
  south: number,
  east: number,
  west: number
}

// Or google.maps.LatLngBounds instance
new google.maps.LatLngBounds(
  { lat: southLat, lng: westLng },
  { lat: northLat, lng: eastLng }
)

Component Variants

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

Build docs developers (and LLMs) love