Using the SDK
@trackthatride/react-map 1.1.2 draws the delivery on a MapLibre map and keeps it live with @trackthatride/realtime:
// npm install @trackthatride/react-map maplibre-gl
import 'maplibre-gl/dist/maplibre-gl.css';
import { TrackingMap } from '@trackthatride/react-map';
export function DeliveryTracker({ token }) {
// token is the delivery's public_tracking_token; apiBaseUrl defaults to https://trackthatride.com
return <TrackingMap trackingCode={token} style={{ width: '100%', height: 420 }} />;
} TrackingInfo and useTrackingSession are exported too, for showing the status and arrival time beside the map.
On React Native, @trackthatride/react-native-map 1.1.0 does the same with
react-native-maps.
Without the SDK: a hook and a map
- Install the map library:
npm install react-leaflet leaflet - Have a delivery’s
public_tracking_tokento hand (your server gets it when it creates the delivery).
1. The hook
// React hook: follow one Track That Ride delivery live, straight from the browser.
// No dependencies beyond React 18. `token` is the delivery's public_tracking_token (no API key).
// The public tracking endpoints allow cross-origin reads, so the hook calls Track That Ride directly.
// Optional: to proxy through your own server (examples/node/tracking-relay.mjs), set API = '/track'.
import { useEffect, useState } from 'react';
const API = 'https://trackthatride.com/api/public/track';
export function useDeliveryTracking(token) {
const [state, setState] = useState({ status: null, eta: null, driver: null, position: null, updates: [], error: null });
useEffect(() => {
if (!token) return undefined;
const url = `${API}/${encodeURIComponent(token)}`;
const stream = new EventSource(`${url}/events`);
stream.onmessage = (e) => {
const msg = JSON.parse(e.data);
setState((s) => {
switch (msg.type) {
case 'connected':
return {
...s,
status: msg.delivery.status,
eta: msg.delivery.eta ?? s.eta,
driver: msg.driver,
position: msg.driver?.latitude != null ? { lat: msg.driver.latitude, lng: msg.driver.longitude } : s.position,
};
case 'driver_location':
return { ...s, position: { lat: msg.location.latitude, lng: msg.location.longitude } };
case 'ride_status_change':
return { ...s, status: msg.status };
case 'eta_update':
return { ...s, eta: msg.eta };
case 'ride_update':
return { ...s, updates: [msg.update, ...s.updates] };
default:
return s; // heartbeat, reconnect, resync…
}
});
};
stream.onerror = () => {
if (stream.readyState === EventSource.CLOSED) setState((s) => ({ ...s, error: 'This tracking link is not valid or has expired.' }));
};
return () => stream.close();
}, [token]);
return state;
}
2. The map component
// Show a delivery's driver on a map with react-leaflet (OpenStreetMap tiles, no API key).
// npm install react-leaflet leaflet
import 'leaflet/dist/leaflet.css';
import { MapContainer, TileLayer, CircleMarker, useMap } from 'react-leaflet';
import { useEffect } from 'react';
import { useDeliveryTracking } from './useDeliveryTracking';
function FollowDriver({ position }) {
const map = useMap();
useEffect(() => {
if (position) map.panTo([position.lat, position.lng]);
}, [map, position]);
return null;
}
export function DeliveryMap({ token }) {
const { status, eta, driver, position, updates, error } = useDeliveryTracking(token);
if (error) return <p>{error}</p>;
return (
<div>
<p>
{driver?.name ? `${driver.name} · ` : ''}
{status ?? 'Connecting…'}
{eta ? ` · arriving about ${new Date(eta).toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' })}` : ''}
</p>
<MapContainer center={[51.5074, -0.1278]} zoom={13} style={{ height: 400 }}>
<TileLayer url="https://tile.openstreetmap.org/{z}/{x}/{y}.png" attribution="© OpenStreetMap contributors" />
{position && <CircleMarker center={[position.lat, position.lng]} radius={10} />}
<FollowDriver position={position} />
</MapContainer>
<ul>
{updates.map((u) => (
<li key={u.id}>{u.title}</li>
))}
</ul>
</div>
);
}
3. Use it
<DeliveryMap token={order.trackingToken} /> Optional: proxy through your own server
Not needed, because the public tracking endpoints allow cross-origin reads. If you want the requests on your own domain, run the relay
from the JavaScript quickstart at /track and set API = '/track'
in the hook.
What we tested
Both example files compile with esbuild as part of our checks, and the hook’s message handling matches the stream format documented in
real-time streams. @trackthatride/react-map is tested with a mocked map: pickup, drop-off and
driver markers from the API’s fields, and the driver marker moving on each location update. The stream it uses,
@trackthatride/realtime, was run end to end against a local copy of the API.