React Integration Guide
Learn how to integrate route optimization and mapping into your React applications using @route-optimization/react.
Installation
npm install @route-optimization/react @route-optimization/core
# or
pnpm add @route-optimization/react @route-optimization/core
# or
yarn add @route-optimization/react @route-optimization/coreAPI Key Setup
Before using any components, configure your Google Maps API key:
# .env
REACT_APP_GOOGLE_MAPS_API_KEY=your_api_key_hereSecurity
Never commit your API key to version control. Always use environment variables and add .env to your .gitignore file.
TIP
For production deployments, use your hosting platform's environment variable configuration (Vercel, Netlify, etc.). See Authentication Guide for best practices.
Core Concepts
The React package provides hooks that wrap the core functionality with React-specific state management:
useRouteMap- Main hook for map rendering and route managementuseMapControls- Hook for map interaction controlsuseRouteOptimization- Hook for route calculation and optimizationuseOptimizationStatus- Hook for optimization progress tracking
Basic Map Rendering
Simple Route Map
import { useRouteMap } from '@route-optimization/react';
function RouteMapComponent() {
const { mapRef, renderRoute, clearRoute, isReady } = useRouteMap({
apiKey: 'YOUR_GOOGLE_MAPS_API_KEY',
center: { lat: 13.7563, lng: 100.5018 }, // Bangkok
zoom: 12,
});
const handleShowRoute = () => {
renderRoute({
stops: [
{
id: '1',
location: { lat: 13.7563, lng: 100.5018 },
name: 'Start Location',
},
{
id: '2',
location: { lat: 13.7467, lng: 100.5352 },
name: 'End Location',
},
],
});
};
return (
<div>
<div ref={mapRef} style={{ width: '100%', height: '600px' }} />
<button onClick={handleShowRoute} disabled={!isReady}>
Show Route
</button>
<button onClick={clearRoute} disabled={!isReady}>
Clear Route
</button>
</div>
);
}Route Map View Component
For simpler usage, use the pre-built RouteMapView component:
import { RouteMapView } from '@route-optimization/react';
function App() {
const [route, setRoute] = useState(null);
return (
<RouteMapView
apiKey="YOUR_GOOGLE_MAPS_API_KEY"
route={route}
mapConfig={{
center: { lat: 13.7563, lng: 100.5018 },
zoom: 12,
}}
onError={(error) => console.error('Map error:', error)}
/>
);
}Map Controls
Using Map Controls Hook
import { useRouteMap, useMapControls } from '@route-optimization/react';
function InteractiveMap() {
const { mapRef, map, isReady } = useRouteMap({
apiKey: 'YOUR_API_KEY',
});
const { center, zoom, bounds, setCenter, setZoom, fitBounds } = useMapControls(map);
const handleCenterBangkok = () => {
setCenter({ lat: 13.7563, lng: 100.5018 });
};
const handleZoomIn = () => {
setZoom((zoom ?? 12) + 1);
};
return (
<div>
<div ref={mapRef} style={{ width: '100%', height: '600px' }} />
<div className="controls">
<p>
Center: {center?.lat.toFixed(4)}, {center?.lng.toFixed(4)}
</p>
<p>Zoom: {zoom}</p>
<button onClick={handleCenterBangkok}>Center on Bangkok</button>
<button onClick={handleZoomIn}>Zoom In</button>
</div>
</div>
);
}Route Optimization
Basic Optimization
import { useRouteOptimization } from '@route-optimization/react';
function RouteOptimizer() {
const { status, data, error, isLoading, isSuccess, optimize, reset } = useRouteOptimization({
useMockMode: true, // Use mock mode for development
});
const handleOptimize = async () => {
const request = {
shipments: [
{
id: 'shipment-1',
deliveryLocation: { latitude: 13.7563, longitude: 100.5018 },
},
{
id: 'shipment-2',
deliveryLocation: { latitude: 13.7467, longitude: 100.5352 },
},
],
vehicles: [
{
id: 'vehicle-1',
startLocation: { latitude: 13.7563, longitude: 100.5018 },
},
],
};
try {
const response = await optimize(request);
console.log('Optimization result:', response);
} catch (err) {
console.error('Optimization failed:', err);
}
};
return (
<div>
<button onClick={handleOptimize} disabled={isLoading}>
{isLoading ? 'Optimizing...' : 'Optimize Routes'}
</button>
{isSuccess && data && (
<div>
<h3>Optimization Complete!</h3>
<p>Routes: {data.routes?.length ?? 0}</p>
<p>Total Distance: {data.metrics?.totalDistance ?? 0} km</p>
</div>
)}
{error && <div className="error">Error: {error}</div>}
</div>
);
}Production Mode with Google Cloud
import { useRouteOptimization } from '@route-optimization/react';
function ProductionOptimizer() {
const { optimize } = useRouteOptimization({
useMockMode: false,
projectId: 'your-google-cloud-project',
credentials: {
client_email: 'service-account@project.iam.gserviceaccount.com',
private_key: process.env.GOOGLE_PRIVATE_KEY,
},
});
// ... rest of component
}Progress Tracking
import { useRouteOptimization, useOptimizationStatus } from '@route-optimization/react';
function OptimizationWithProgress() {
const { optimize } = useRouteOptimization({ useMockMode: true });
const {
progress,
step,
setProgress,
reset: resetProgress,
} = useOptimizationStatus({
onStart: () => console.log('Optimization started'),
onSuccess: () => console.log('Optimization complete!'),
onError: (error) => console.error('Failed:', error),
});
const handleOptimize = async () => {
resetProgress();
setProgress(0, 'Initializing...');
// Simulate progress
setProgress(25, 'Calculating distances...');
const response = await optimize(request);
setProgress(75, 'Optimizing routes...');
if (response.success) {
setProgress(100, 'Complete!');
}
};
return (
<div>
<button onClick={handleOptimize}>Optimize</button>
<div className="progress">
<div className="progress-bar" style={{ width: `${progress}%` }} />
<p>{step}</p>
</div>
</div>
);
}Complete Example
Combining map rendering with route optimization:
import { useState } from 'react';
import { useRouteMap, useRouteOptimization, RouteMapView } from '@route-optimization/react';
import type { Route } from '@route-optimization/core';
function CompleteApp() {
const [route, setRoute] = useState<Route | null>(null);
const [locations, setLocations] = useState([
{ lat: 13.7563, lng: 100.5018, name: 'Bangkok' },
{ lat: 13.7467, lng: 100.5352, name: 'Chatuchak' },
{ lat: 13.7307, lng: 100.5418, name: 'Victory Monument' },
]);
const { optimize, isLoading, isSuccess } = useRouteOptimization({
useMockMode: true,
});
const handleOptimize = async () => {
const request = {
shipments: locations.map((loc, i) => ({
id: `shipment-${i}`,
deliveryLocation: { latitude: loc.lat, longitude: loc.lng },
})),
vehicles: [
{
id: 'vehicle-1',
startLocation: { latitude: locations[0].lat, longitude: locations[0].lng },
},
],
};
const response = await optimize(request);
if (response.success && response.routes?.[0]) {
// Convert optimization result to Route format
const optimizedRoute: Route = {
stops:
response.routes[0].stops?.map((stop, i) => ({
id: stop.shipmentId || `stop-${i}`,
location: {
lat: stop.location?.latitude ?? 0,
lng: stop.location?.longitude ?? 0,
},
name: locations[i]?.name ?? `Stop ${i + 1}`,
})) ?? [],
};
setRoute(optimizedRoute);
}
};
return (
<div className="app">
<div className="sidebar">
<h2>Route Optimization</h2>
<div className="locations">
{locations.map((loc, i) => (
<div key={i} className="location-item">
{loc.name}
</div>
))}
</div>
<button onClick={handleOptimize} disabled={isLoading}>
{isLoading ? 'Optimizing...' : 'Optimize Route'}
</button>
{isSuccess && <div className="success">✓ Route optimized successfully!</div>}
</div>
<div className="map-container">
<RouteMapView
apiKey={process.env.REACT_APP_GOOGLE_MAPS_API_KEY!}
route={route}
mapConfig={{
center: { lat: 13.7563, lng: 100.5018 },
zoom: 12,
}}
/>
</div>
</div>
);
}
export default CompleteApp;TypeScript Support
All hooks are fully typed. Import types from the packages:
import type {
Route,
Stop,
MapConfig,
OptimizationRequest,
OptimizationResponse,
} from '@route-optimization/core';
import type {
UseRouteMapOptions,
UseRouteMapReturn,
UseMapControlsReturn,
UseRouteOptimizationResult,
} from '@route-optimization/react';Best Practices
1. Environment Variables
Store API keys in environment variables:
# .env.local
REACT_APP_GOOGLE_MAPS_API_KEY=your_api_key
REACT_APP_GOOGLE_PROJECT_ID=your_project_id2. Error Handling
Always handle errors properly:
const { optimize, error } = useRouteOptimization(config);
const handleOptimize = async () => {
try {
const result = await optimize(request);
// Handle success
} catch (err) {
// Handle error
console.error('Optimization failed:', err);
}
};3. Cleanup
Components automatically clean up when unmounted, but you can manually reset:
useEffect(() => {
return () => {
clearRoute();
reset();
};
}, []);4. Memoization
Memoize large configuration objects:
const mapConfig = useMemo(
() => ({
center: { lat: 13.7563, lng: 100.5018 },
zoom: 12,
styles: customMapStyles,
}),
[]
);
const { mapRef } = useRouteMap({
apiKey,
...mapConfig,
});Next Steps
- Learn about Vue Integration
- Explore Route Calculation in depth
- Check out API Reference