React.js Google Maps API integration with components and hooks for seamless Google Maps functionality
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Components for displaying markers, info windows, and custom overlay content positioned on the map, including advanced overlay positioning and DOM content integration.
Places interactive markers on the map at specified positions with extensive customization and event handling options.
/**
* Places markers on the map at specified positions
* Supports clustering, custom icons, and rich interaction events
*/
interface MarkerProps {
// Required
position: google.maps.LatLng | google.maps.LatLngLiteral;
children?: React.ReactNode;
options?: google.maps.MarkerOptions;
animation?: google.maps.Animation;
clickable?: boolean;
cursor?: string;
draggable?: boolean;
icon?: string | google.maps.Icon | google.maps.Symbol;
label?: string | google.maps.MarkerLabel;
opacity?: number;
shape?: google.maps.MarkerShape;
title?: string;
visible?: boolean;
zIndex?: number;
// Clustering integration
clusterer?: Clusterer | google.maps.MarkerClusterer;
noClustererRedraw?: boolean;
// Mouse events
onClick?: (e: google.maps.MapMouseEvent) => void;
onDblClick?: (e: google.maps.MapMouseEvent) => void;
onDrag?: (e: google.maps.MapMouseEvent) => void;
onDragEnd?: (e: google.maps.MapMouseEvent) => void;
onDragStart?: (e: google.maps.MapMouseEvent) => void;
onMouseDown?: (e: google.maps.MapMouseEvent) => void;
onMouseOut?: (e: google.maps.MapMouseEvent) => void;
onMouseOver?: (e: google.maps.MapMouseEvent) => void;
onMouseUp?: (e: google.maps.MapMouseEvent) => void;
onRightClick?: (e: google.maps.MapMouseEvent) => void;
// Property change events
onClickableChanged?: () => void;
onCursorChanged?: () => void;
onAnimationChanged?: () => void;
onDraggableChanged?: () => void;
onFlatChanged?: () => void;
onIconChanged?: () => void;
onPositionChanged?: () => void;
onShapeChanged?: () => void;
onTitleChanged?: () => void;
onVisibleChanged?: () => void;
onZindexChanged?: () => void;
// Lifecycle events
onLoad?: (marker: google.maps.Marker) => void;
onUnmount?: (marker: google.maps.Marker) => void;
}
function Marker(props: MarkerProps): JSX.Element;Usage Examples:
import React, { useState } from 'react';
import { GoogleMap, LoadScript, Marker } from '@react-google-maps/api';
// Basic marker
function BasicMarkerExample() {
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<GoogleMap
center={{ lat: 40.7128, lng: -74.0060 }}
zoom={10}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
<Marker position={{ lat: 40.7128, lng: -74.0060 }} />
</GoogleMap>
</LoadScript>
);
}
// Interactive markers with custom icons
function InteractiveMarkers() {
const [selectedMarker, setSelectedMarker] = useState<string | null>(null);
const markers = [
{
id: 'marker1',
position: { lat: 40.7128, lng: -74.0060 },
title: 'New York City',
icon: 'https://maps.google.com/mapfiles/ms/icons/blue-dot.png'
},
{
id: 'marker2',
position: { lat: 40.7589, lng: -73.9851 },
title: 'Times Square',
icon: 'https://maps.google.com/mapfiles/ms/icons/red-dot.png'
}
];
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<GoogleMap
center={{ lat: 40.7128, lng: -74.0060 }}
zoom={12}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
{markers.map(marker => (
<Marker
key={marker.id}
position={marker.position}
title={marker.title}
icon={marker.icon}
animation={selectedMarker === marker.id ? google.maps.Animation.BOUNCE : undefined}
onClick={() => setSelectedMarker(marker.id)}
onLoad={(markerInstance) => console.log('Marker loaded:', marker.id)}
/>
))}
</GoogleMap>
</LoadScript>
);
}
// Draggable markers with custom labels
function DraggableMarkers() {
const [markerPosition, setMarkerPosition] = useState({ lat: 40.7128, lng: -74.0060 });
const customLabel: google.maps.MarkerLabel = {
text: 'DRAG ME',
color: 'white',
fontSize: '14px',
fontWeight: 'bold'
};
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<GoogleMap
center={markerPosition}
zoom={10}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
<Marker
position={markerPosition}
draggable={true}
label={customLabel}
title="Draggable Marker"
onDragEnd={(e) => {
if (e.latLng) {
const newPos = e.latLng.toJSON();
setMarkerPosition(newPos);
console.log('New position:', newPos);
}
}}
/>
</GoogleMap>
</LoadScript>
);
}Functional component variant of Marker that uses React hooks internally.
/**
* Functional variant of Marker component using hooks internally
* Provides the same API as Marker but with modern React patterns
*/
function MarkerF(props: MarkerProps): JSX.Element;Displays content in a popup window above the map, typically attached to markers or positioned at specific coordinates.
/**
* Displays content in a popup window above the map
* Can be anchored to markers or positioned at specific coordinates
*/
interface InfoWindowProps {
children?: React.ReactNode;
anchor?: google.maps.MVCObject;
options?: google.maps.InfoWindowOptions;
position?: google.maps.LatLng | google.maps.LatLngLiteral;
zIndex?: number;
// Event handlers
onCloseClick?: () => void;
onDomReady?: () => void;
onContentChanged?: () => void;
onPositionChanged?: () => void;
onZindexChanged?: () => void;
// Lifecycle events
onLoad?: (infoWindow: google.maps.InfoWindow) => void;
onUnmount?: (infoWindow: google.maps.InfoWindow) => void;
}
function InfoWindow(props: InfoWindowProps): JSX.Element;Usage Examples:
import React, { useState } from 'react';
import { GoogleMap, LoadScript, Marker, InfoWindow } from '@react-google-maps/api';
// InfoWindow attached to marker
function MarkerWithInfoWindow() {
const [isOpen, setIsOpen] = useState(false);
const position = { lat: 40.7128, lng: -74.0060 };
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<GoogleMap
center={position}
zoom={10}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
<Marker
position={position}
onClick={() => setIsOpen(true)}
/>
{isOpen && (
<InfoWindow
position={position}
onCloseClick={() => setIsOpen(false)}
>
<div>
<h3>New York City</h3>
<p>The most populous city in the United States</p>
<img
src="https://example.com/nyc.jpg"
alt="NYC"
style={{ width: '200px', height: '150px' }}
/>
</div>
</InfoWindow>
)}
</GoogleMap>
</LoadScript>
);
}
// Multiple InfoWindows with rich content
function MultipleInfoWindows() {
const [activeMarker, setActiveMarker] = useState<string | null>(null);
const locations = [
{
id: 'nyc',
position: { lat: 40.7128, lng: -74.0060 },
title: 'New York City',
description: 'The Big Apple',
image: 'https://example.com/nyc.jpg'
},
{
id: 'sf',
position: { lat: 37.7749, lng: -122.4194 },
title: 'San Francisco',
description: 'The Golden City',
image: 'https://example.com/sf.jpg'
}
];
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<GoogleMap
center={{ lat: 39.8283, lng: -98.5795 }}
zoom={4}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
{locations.map(location => (
<React.Fragment key={location.id}>
<Marker
position={location.position}
onClick={() => setActiveMarker(location.id)}
/>
{activeMarker === location.id && (
<InfoWindow
position={location.position}
onCloseClick={() => setActiveMarker(null)}
options={{
pixelOffset: new google.maps.Size(0, -40)
}}
>
<div style={{ maxWidth: '300px' }}>
<h3>{location.title}</h3>
<p>{location.description}</p>
<img
src={location.image}
alt={location.title}
style={{ width: '100%', height: '150px', objectFit: 'cover' }}
/>
<button onClick={() => console.log(`More info about ${location.title}`)}>
Learn More
</button>
</div>
</InfoWindow>
)}
</React.Fragment>
))}
</GoogleMap>
</LoadScript>
);
}Functional component variant of InfoWindow that uses React hooks internally.
/**
* Functional variant of InfoWindow component using hooks internally
* Provides the same API as InfoWindow but with modern React patterns
*/
function InfoWindowF(props: InfoWindowProps): JSX.Element;Enhanced info window component with additional styling options and features beyond the standard InfoWindow.
/**
* Enhanced info window with additional styling options
* Provides more customization than standard InfoWindow
*/
interface InfoBoxProps {
children?: React.ReactNode;
options?: InfoBoxOptions;
position?: google.maps.LatLng | google.maps.LatLngLiteral;
visible?: boolean;
zIndex?: number;
// Event handlers
onCloseClick?: () => void;
onDomReady?: () => void;
onContentChanged?: () => void;
onPositionChanged?: () => void;
// Lifecycle events
onLoad?: (infoBox: InfoBox) => void;
onUnmount?: (infoBox: InfoBox) => void;
}
interface InfoBoxOptions {
alignBottom?: boolean;
boxClass?: string;
boxStyle?: React.CSSProperties;
closeBoxMargin?: string;
closeBoxURL?: string;
content?: string | Node;
disableAutoPan?: boolean;
enableEventPropagation?: boolean;
infoBoxClearance?: google.maps.Size;
isHidden?: boolean;
maxWidth?: number;
pixelOffset?: google.maps.Size;
position?: google.maps.LatLng | google.maps.LatLngLiteral;
zIndex?: number;
}
function InfoBox(props: InfoBoxProps): JSX.Element;Usage Examples:
import React, { useState } from 'react';
import { GoogleMap, LoadScript, Marker, InfoBox } from '@react-google-maps/api';
function StyledInfoBox() {
const [isOpen, setIsOpen] = useState(false);
const position = { lat: 40.7128, lng: -74.0060 };
const infoBoxOptions: InfoBoxOptions = {
boxStyle: {
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
color: 'white',
padding: '15px',
borderRadius: '10px',
boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
fontFamily: 'Arial, sans-serif'
},
closeBoxMargin: '5px',
closeBoxURL: 'https://example.com/close-icon.png',
pixelOffset: new google.maps.Size(-150, -50),
maxWidth: 300
};
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<GoogleMap
center={position}
zoom={10}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
<Marker
position={position}
onClick={() => setIsOpen(true)}
/>
{isOpen && (
<InfoBox
position={position}
options={infoBoxOptions}
onCloseClick={() => setIsOpen(false)}
>
<div>
<h3 style={{ margin: '0 0 10px 0' }}>Styled InfoBox</h3>
<p style={{ margin: '0' }}>
This InfoBox has custom styling and enhanced features!
</p>
</div>
</InfoBox>
)}
</GoogleMap>
</LoadScript>
);
}Functional component variant of InfoBox that uses React hooks internally.
/**
* Functional variant of InfoBox component using hooks internally
*/
function InfoBoxF(props: InfoBoxProps): JSX.Element;Custom overlay component that displays DOM content positioned precisely on the map using geographic coordinates.
/**
* Custom overlay that displays DOM content positioned on the map
* Allows precise positioning of React components at geographic coordinates
*/
interface OverlayViewProps {
children?: React.ReactNode;
position: google.maps.LatLng | google.maps.LatLngLiteral;
pane?: string;
mapPaneName?: string;
getPixelPositionOffset?: (width: number, height: number) => { x: number; y: number };
// Lifecycle events
onLoad?: (overlayView: google.maps.OverlayView) => void;
onUnmount?: (overlayView: google.maps.OverlayView) => void;
}
function OverlayView(props: OverlayViewProps): JSX.Element;
// Overlay pane constants
declare const FLOAT_PANE: string;
declare const MAP_PANE: string;
declare const MARKER_LAYER: string;
declare const OVERLAY_LAYER: string;
declare const OVERLAY_MOUSE_TARGET: string;Usage Examples:
import React from 'react';
import {
GoogleMap,
LoadScript,
OverlayView,
OVERLAY_MOUSE_TARGET
} from '@react-google-maps/api';
// Custom overlay with precise positioning
function CustomOverlayExample() {
const position = { lat: 40.7128, lng: -74.0060 };
const getPixelPositionOffset = (width: number, height: number) => ({
x: -(width / 2),
y: -(height / 2)
});
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<GoogleMap
center={position}
zoom={15}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
<OverlayView
position={position}
pane={OVERLAY_MOUSE_TARGET}
getPixelPositionOffset={getPixelPositionOffset}
>
<div style={{
background: 'white',
border: '2px solid #ff6b6b',
borderRadius: '20px',
padding: '10px',
fontSize: '14px',
fontWeight: 'bold',
color: '#333',
boxShadow: '0 2px 10px rgba(0,0,0,0.3)',
cursor: 'pointer'
}}>
Custom Overlay Content
<div style={{ fontSize: '12px', fontWeight: 'normal', marginTop: '5px' }}>
Positioned at: {position.lat.toFixed(4)}, {position.lng.toFixed(4)}
</div>
</div>
</OverlayView>
</GoogleMap>
</LoadScript>
);
}
// Multiple overlays with different panes
function MultipleOverlays() {
const locations = [
{ lat: 40.7128, lng: -74.0060, label: 'NYC' },
{ lat: 40.7589, lng: -73.9851, label: 'Times Square' },
{ lat: 40.7505, lng: -73.9934, label: 'Empire State' }
];
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<GoogleMap
center={{ lat: 40.7128, lng: -74.0060 }}
zoom={13}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
{locations.map((location, index) => (
<OverlayView
key={index}
position={location}
pane={OVERLAY_MOUSE_TARGET}
getPixelPositionOffset={(w, h) => ({ x: -w/2, y: -h })}
>
<div style={{
background: '#4285f4',
color: 'white',
padding: '8px 12px',
borderRadius: '16px',
fontSize: '12px',
fontWeight: 'bold',
boxShadow: '0 2px 8px rgba(0,0,0,0.3)',
whiteSpace: 'nowrap'
}}>
{location.label}
</div>
</OverlayView>
))}
</GoogleMap>
</LoadScript>
);
}Functional component variant of OverlayView that uses React hooks internally.
/**
* Functional variant of OverlayView component using hooks internally
*/
function OverlayViewF(props: OverlayViewProps): JSX.Element;Displays images overlaid on the map, anchored to geographic coordinates and scaled appropriately.
/**
* Displays images overlaid on the map
* Images are anchored to geographic coordinates and scaled with the map
*/
interface GroundOverlayProps {
url: string;
bounds: google.maps.LatLngBounds | google.maps.LatLngBoundsLiteral;
options?: google.maps.GroundOverlayOptions;
opacity?: number;
clickable?: boolean;
// Event handlers
onClick?: (e: google.maps.MapMouseEvent) => void;
onDblClick?: (e: google.maps.MapMouseEvent) => void;
// Lifecycle events
onLoad?: (groundOverlay: google.maps.GroundOverlay) => void;
onUnmount?: (groundOverlay: google.maps.GroundOverlay) => void;
}
function GroundOverlay(props: GroundOverlayProps): JSX.Element;Usage Examples:
import React, { useState } from 'react';
import { GoogleMap, LoadScript, GroundOverlay } from '@react-google-maps/api';
function GroundOverlayExample() {
const [opacity, setOpacity] = useState(0.8);
const bounds = {
north: 40.7739,
south: 40.7517,
east: -73.9657,
west: -73.9963
};
return (
<LoadScript googleMapsApiKey="YOUR_API_KEY">
<div>
<div style={{ padding: '10px' }}>
<label>
Opacity:
<input
type="range"
min="0"
max="1"
step="0.1"
value={opacity}
onChange={(e) => setOpacity(parseFloat(e.target.value))}
/>
{opacity}
</label>
</div>
<GoogleMap
center={{ lat: 40.7628, lng: -73.981 }}
zoom={14}
mapContainerStyle={{ width: '100%', height: '400px' }}
>
<GroundOverlay
url="https://example.com/central-park-overlay.png"
bounds={bounds}
opacity={opacity}
clickable={true}
onClick={() => console.log('Ground overlay clicked')}
onLoad={() => console.log('Ground overlay loaded')}
/>
</GoogleMap>
</div>
</LoadScript>
);
}Functional component variant of GroundOverlay that uses React hooks internally.
/**
* Functional variant of GroundOverlay component using hooks internally
*/
function GroundOverlayF(props: GroundOverlayProps): JSX.Element;Install with Tessl CLI
npx tessl i tessl/npm-react-google-maps--api