Skip to main content

Location and tracking

Contents

Request runtime permission

Declare location permissions in Getting started, then request runtime permission before rendering <UserLocation> or enabling trackUserLocation. Without granted permission, the map loads but the location puck does not appear.

On Android, request permission explicitly:

import { PermissionsAndroid, Platform } from "react-native";

async function requestLocationPermission(): Promise<boolean> {
  if (Platform.OS !== "android") {
    return true;
  }

  const granted = await PermissionsAndroid.request(
    PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
  );

  return granted === PermissionsAndroid.RESULTS.GRANTED;
}

On iOS, add the Info.plist usage-description keys from getting started. The system permission dialog appears when location is first accessed.

User location and follow-me

Add <UserLocation> as a child of <Map> to show the device location puck. Combine with <Camera trackUserLocation> to follow the user as they move:

import {
  Camera,
  Map,
  TrimbleMaps,
  UserLocation,
} from "@trimblemaps/maps-react-native";
import { useEffect, useState } from "react";

function FollowMe() {
  const [locationReady, setLocationReady] = useState(false);

  useEffect(() => {
    requestLocationPermission().then(setLocationReady);
  }, []);

  if (!locationReady) {
    return null;
  }

  return (
    <Map mapStyle={TrimbleMaps.StyleURL.MobileDay} style={{ flex: 1 }}>
      <Camera trackUserLocation="default" zoom={16} />
      <UserLocation accuracy heading />
    </Map>
  );
}

Map press events

Handle taps on the map with the onPress prop. The event provides the tapped coordinate in GeoJSON order [longitude, latitude]:

import { Map, TrimbleMaps, type PressEvent } from "@trimblemaps/maps-react-native";
import { useState } from "react";

function ClickableMap() {
  const [press, setPress] = useState<PressEvent | null>(null);

  return (
    <Map
      mapStyle={TrimbleMaps.StyleURL.MobileDay}
      style={{ flex: 1 }}
      onPress={(event) => setPress(event.nativeEvent)}
    />
  );
}

Access the coordinate with press.lngLat[0] (longitude) and press.lngLat[1] (latitude).

Cycling between locations

Use a Camera ref with flyTo to animate between preset locations:

const LOCATIONS = [
  { name: "Princeton", center: [-74.6672, 40.3573] as [number, number] },
  { name: "Richmond", center: [-77.436, 37.5407] as [number, number] },
];

cameraRef.current?.flyTo({
  center: LOCATIONS[index].center,
  zoom: 12,
  duration: 600,
});
Last updated September 3, 2026.
Contents