@smarthivelabs-devs/geocore-react
v1.6.5
Published
Geocore React SDK — hooks and components for React 18+
Readme
@smarthivelabs-devs/geocore-react
React hooks and components for the Geocore SDK. Wraps all 14 geo-operations, weather, and the SmartHive Pricing Engine in ergonomic hooks with built-in loading and error state.
Installation
npm install @smarthivelabs-devs/geocore-react @smarthivelabs-devs/geocore-core
# peer deps
npm install react react-domSetup
Wrap your app with GeocoreProvider:
import { GeocoreProvider } from '@smarthivelabs-devs/geocore-react';
// Backend mode (recommended — API keys stay on your server)
function App() {
return (
<GeocoreProvider config={{ apiKey: 'your-geocore-api-key' }}>
<YourApp />
</GeocoreProvider>
);
}
// Direct mode (API keys in the browser)
function App() {
return (
<GeocoreProvider config={{
apiKeys: {
mapbox: { publicToken: 'pk.eyJ1...' },
google: 'AIza...',
},
}}>
<YourApp />
</GeocoreProvider>
);
}Geocoding Hooks
useReverseGeocode — coordinates → display address
The simplest way to turn a lat/lng into a readable address. Uses the browser Geolocation API for auto-fetching device position.
import { useReverseGeocode, getDisplayAddress } from '@smarthivelabs-devs/geocore-react';
// Auto-detect user's browser location
function UserLocation({ geocore }) {
const { address, components, loading, error } = useReverseGeocode({
geocore,
autoFetch: true,
});
if (loading) return <p>Locating…</p>;
if (error) return <p>{error}</p>;
return <p>{address}</p>;
// → "Adum, Kumasi, Ashanti Region, Ghana"
}
// Geocode a map marker
function MarkerAddress({ geocore, markerCoords }) {
const { address, components } = useReverseGeocode({ geocore, coords: markerCoords });
return (
<div>
<p>{address}</p>
<p>{components.city}, {components.state}</p>
</div>
);
}useAddressSearch — debounced search with suggestions
Drop-in hook for address input fields. Handles debouncing, shows autocomplete suggestions, and locks in coordinates once the user selects a result.
import { useAddressSearch } from '@smarthivelabs-devs/geocore-react';
function AddressInput({ geocore, userCoords, onConfirm }) {
const search = useAddressSearch({
geocore,
proximity: userCoords,
limit: 5,
});
useEffect(() => {
if (search.confirmed && search.coords) {
onConfirm(search.value, search.coords);
}
}, [search.confirmed]);
return (
<div>
<input
value={search.value}
onChange={e => search.onChange(e.target.value)}
placeholder="Enter address…"
/>
{search.loading && <span>Searching…</span>}
{search.suggestions.map(s => (
<button key={s.address} onClick={() => search.onSelect(s)}>
<strong>{s.label}</strong>
{s.sublabel && <span>{s.sublabel}</span>}
</button>
))}
</div>
);
}useGeocoding
import { useGeocoding } from '@smarthivelabs-devs/geocore-react';
import { Geocore } from '@smarthivelabs-devs/geocore-core';
function AddressSearch({ geocore }: { geocore: Geocore }) {
const { geocodingResult, loading, error, geocode, reverse, reset } = useGeocoding(geocore);
return (
<div>
<button onClick={() => geocode('Eiffel Tower, Paris')}>Search</button>
{loading && <p>Searching...</p>}
{geocodingResult && (
<p>
{geocodingResult.data.formattedAddress}
{' — '}
{geocodingResult.data.coordinates.lat}, {geocodingResult.data.coordinates.lng}
</p>
)}
{error && <p>Error: {error.message}</p>}
</div>
);
}Directions Hook
useDirections
import { useDirections } from '@smarthivelabs-devs/geocore-react';
function RouteMap({ geocore }) {
const { result, loading, error, getDirections } = useDirections(geocore);
return (
<button onClick={() =>
getDirections(
{ lat: 51.5074, lng: -0.1278 },
{ lat: 48.8566, lng: 2.3522 },
{ mode: 'driving' }
)
}>
Get Route
</button>
);
}Places Hooks
usePlaces · useNearbySearch · useAutocomplete
import { usePlaces, useNearbySearch, useAutocomplete } from '@smarthivelabs-devs/geocore-react';
// Search by query
const { result, loading, searchPlaces } = usePlaces(geocore);
await searchPlaces('coffee', { lat: 51.5, lng: -0.12 }, { radius: 500 });
// Category search around a point
const { result, searchNearby } = useNearbySearch(geocore);
await searchNearby('restaurant', { lat: 51.5, lng: -0.12 });
// Autocomplete suggestions
const { predictions, loading, getSuggestions } = useAutocomplete(geocore);
await getSuggestions('Hyde Park Lo');Spatial Analysis Hooks
useElevation
import { useElevation } from '@smarthivelabs-devs/geocore-react';
const { result, loading, getElevation } = useElevation(geocore);
await getElevation(51.5074, -0.1278);
console.log(result?.data.elevation); // metresuseIsochrone
import { useIsochrone } from '@smarthivelabs-devs/geocore-react';
const { result, getIsochrone } = useIsochrone(geocore);
await getIsochrone(51.5074, -0.1278, [15, 30], { mode: 'walking' });
// result.data.features — GeoJSON FeatureCollectionuseTimezone
import { useTimezone } from '@smarthivelabs-devs/geocore-react';
const { result, getTimezone } = useTimezone(geocore);
await getTimezone(51.5074, -0.1278);
console.log(result?.data.timeZoneId); // 'Europe/London'Utility Hooks
useTraffic
import { useTraffic } from '@smarthivelabs-devs/geocore-react';
const { result, getTraffic } = useTraffic(geocore);
await getTraffic(51.5074, -0.1278);
console.log(result?.data.congestionLevel); // 'free' | 'light' | 'moderate' | 'heavy'useDistanceMatrix
import { useDistanceMatrix } from '@smarthivelabs-devs/geocore-react';
const { result, getMatrix } = useDistanceMatrix(geocore);
await getMatrix(['London, UK', 'Paris, France'], ['Berlin, Germany']);useSnapToRoad · useRouteOptimize · useStaticMap
import { useSnapToRoad, useRouteOptimize, useStaticMap } from '@smarthivelabs-devs/geocore-react';
const { result, snap } = useSnapToRoad(geocore);
const { result, optimise } = useRouteOptimize(geocore);
const { result, getMap } = useStaticMap(geocore);Weather Hook
import { useWeather } from '@smarthivelabs-devs/geocore-react';
function WeatherWidget({ geocore, lat, lng }) {
const { currentResult, forecastResult, loading, error, getWeather, getForecast } = useWeather(geocore);
useEffect(() => {
getWeather(lat, lng);
getForecast(lat, lng, 7);
}, [lat, lng]);
if (loading) return <p>Loading weather...</p>;
return (
<div>
<p>{currentResult?.data.temperature}°C — {currentResult?.data.description}</p>
{forecastResult?.data.days.map(day => (
<p key={day.date}>{day.date}: {day.tempMin}–{day.tempMax}°C</p>
))}
</div>
);
}Pricing Hook — SmartHive Pricing Engine
Converts a base price to the user's local currency. Detects country from GPS or accepts a manual override (country picker).
import { usePricing } from '@smarthivelabs-devs/geocore-react';
function PricingDisplay({ geocore, userLat, userLng }) {
const { result, loading, error, localizePrice, localizePriceByCountry } = usePricing(geocore);
// Auto-detect country from location
useEffect(() => {
localizePrice(100, 'GHS', userLat, userLng);
}, [userLat, userLng]);
// Manual override — user picks country from a dropdown
const handleCountryChange = (code: string) => {
localizePriceByCountry(100, 'GHS', code);
};
return (
<div>
{loading && <p>Calculating price...</p>}
{result && (
<p>
{result.data.symbol}{result.data.amount} {result.data.currency}
{' '}/month
</p>
)}
<select onChange={e => handleCountryChange(e.target.value)}>
<option value="US">United States</option>
<option value="NG">Nigeria</option>
<option value="GH">Ghana</option>
<option value="GB">United Kingdom</option>
</select>
</div>
);
}Direct FX rate lookup
const { rateResult, ratesResult, getRate, getRates } = usePricing(geocore);
await getRate('USD', 'EUR');
console.log(rateResult?.data.rate); // 0.92
await getRates('USD');
console.log(ratesResult?.data.rates); // { EUR: 0.92, GBP: 0.79, NGN: 1580, ... }Error Handling
Every hook exposes an error: Error | null field. Errors are caught internally — they never propagate to your component's error boundary unless you rethrow them.
import { useGeocoding } from '@smarthivelabs-devs/geocore-react';
import { GeocoreError } from '@smarthivelabs-devs/geocore-core';
function AddressSearch({ geocore }) {
const { geocodingResult, loading, error, geocode } = useGeocoding(geocore);
return (
<div>
<button onClick={() => geocode('Unknown Place XYZ')}>Search</button>
{error && (
<p style={{ color: 'red' }}>
{error instanceof GeocoreError
? `${error.code}: ${error.message}`
: error.message}
</p>
)}
</div>
);
}Use reset() to clear error and result state before a new search:
const { geocode, reset, error } = useGeocoding(geocore);
const handleNewSearch = () => {
reset();
geocode('New Address');
};Context Hook
Access the Geocore instance anywhere inside GeocoreProvider:
import { useGeocoreConfig } from '@smarthivelabs-devs/geocore-react';
function AnyChildComponent() {
const { geocore } = useGeocoreConfig();
const { geocodingResult, geocode } = useGeocoding(geocore);
// ...
}Hook Return Shapes
All hooks return { loading: boolean, error: Error | null, reset: () => void } plus the result fields and action callbacks listed below:
| Hook | Result field(s) | Actions |
|------|----------------|---------|
| useGeocoding | geocodingResult, reverseResult | geocode(address, options?), reverse(lat, lng, options?) |
| useDirections | result | getDirections(from, to, options?) |
| usePlaces | result | searchPlaces(query, center, options?) |
| useNearbySearch | result | searchNearby(category, center, options?) |
| useAutocomplete | predictions | getSuggestions(query, options?) |
| useElevation | result | getElevation(lat, lng) |
| useIsochrone | result | getIsochrone(lat, lng, minutes[], options?) |
| useTimezone | result | getTimezone(lat, lng) |
| useTraffic | result | getTraffic(lat, lng, options?) |
| useDistanceMatrix | result | getMatrix(origins[], destinations[], options?) |
| useSnapToRoad | result | snap(points[]) |
| useRouteOptimize | result | optimise(waypoints[], options?) |
| useStaticMap | result | getMap(lat, lng, options?) |
| useWeather | currentResult, forecastResult | getWeather(lat, lng, options?), getForecast(lat, lng, days?, options?) |
| usePricing | result, rateResult, ratesResult | localizePrice(...), localizePriceByCountry(...), getRate(from, to), getRates(base) |
| useProviders | providers, provider, operationProviders | getProviders(), getProvider(name), getProvidersForOperation(op) |
| useMap | map | createMap(options) |
Provider Hook
import { useProviders } from '@smarthivelabs-devs/geocore-react';
const { providers, loading, getProviders, getProvider, getProvidersForOperation } = useProviders(geocore);
await getProviders();
await getProvidersForOperation('geocode');Interactive Map Component
import { MapComponent } from '@smarthivelabs-devs/geocore-react';
<MapComponent
geocore={geocore}
center={{ lat: 51.5074, lng: -0.1278 }}
zoom={13}
markers={[
{ lat: 51.5074, lng: -0.1278, title: 'London' },
]}
onMarkerClick={(marker) => console.log(marker)}
/>All Hooks
| Hook | Returns / Actions | Notes |
|------|-------------------|-------|
| useReverseGeocode | address, components, coords, loading, error, refresh | New in 1.6 — uses navigator.geolocation |
| useAddressSearch | value, suggestions, confirmed, coords, onChange, onSelect, confirm, clear | New in 1.6 — debounced search |
| useGeocoding | geocode, reverse | |
| useDirections | getDirections | |
| usePlaces | searchPlaces | |
| useNearbySearch | searchNearby | |
| useAutocomplete | getSuggestions | |
| useElevation | getElevation | |
| useIsochrone | getIsochrone | |
| useTimezone | getTimezone | |
| useTraffic | getTraffic | |
| useDistanceMatrix | getMatrix | |
| useSnapToRoad | snap | |
| useRouteOptimize | optimise | |
| useStaticMap | getMap | |
| useWeather | getWeather, getForecast | |
| usePricing | localizePrice, localizePriceByCountry, getRate, getRates | |
| useProviders | getProviders, getProvider, getProvidersForOperation | |
| useMap | createMap | |
Every hook exposes { loading, error, reset } alongside its action callbacks.
Changelog
1.6.0
- New
useReverseGeocodehook — reverse-geocode usingnavigator.geolocationfor auto device position, or pass explicit coordinates. Returns normalizedaddressstring and structuredcomponents. - New
useAddressSearchhook — debounced address input with autocomplete suggestions and coordinate confirmation. - Normalized address components —
componentsfrom all hooks now use consistent keys (city,state,area,street, etc.) regardless of provider. Seegeocore-corechangelog for details. getDisplayAddressutility — re-exported from this package for convenience.
License
MIT — SmartHive Labs
