# How to Add a Real-Time Live Location Tracker on React ## Introduction Real-time Live location is a feature that has been integrated into regular web applications over the years for tracking the efficiency of data across devices. As a developer building a delivery system that requires the use of a live location tracker to enhance user satisfaction by providing transparency and convenience in tracking delivery drivers' locations accurately, is an essential feature to consider. On completing this article, you will learn and explore means of integrating a real-time tracker into your react app, to get a user's live location on their browser through your react app, and potential ways to use this feature to provide value to your users. ![image](https://hackmd.io/_uploads/rkKeEw6C6.png) ## Understanding Real-Time Location Tracking React's component-based architecture and state management make it well-suited for implementing real-time location-tracking features. By using the React state management, you can efficiently handle and update location data in real-time, ensuring a seamless and responsive user experience. Using React's declarative approach to building user interfaces simplifies the integration of location-tracking functionality into applications. You can easily create reusable components for displaying maps, markers, and other location-based elements, streamlining the development process and enhancing code maintainability. In the next sections of this tutorial, you will explore the practical implementation of real-time location tracking in React applications, leveraging the insights gained from understanding its definition, significance, and methods of obtaining live location data. ## Setting Up Environment To kickstart our project, we'll begin by cloning a starter application from GitHub. This starter app will provide us with a foundational structure and boilerplate code to build upon. Navigate to the GitHub repository of the starter app and use the git clone command to create a local copy of the project on your machine. ### The Starter file Go to your terminal and run the code below to create enter and open a new directory on your workspace. ```bash mkdir tracker_app cd tracker_app code tracker ``` Next to clone the starter app to your local environment run the command. ```bash git clone https://github.com/Phenzic/react_live_tracker_starter ``` you notice the newly created project starter in your folder similar to the image below. ![image](https://hackmd.io/_uploads/r1lqVDT0a.png) Next, run the command `npm install` to install all the packages you will need throughout this tutorial. Run the command `npm run dev` to start the application. Now you have the starter app cloned locally, and all the packages installed, you can configure permissions and security settings before proceeding further. which would involve configuring access controls to your Google console, by setting up your API key. Now create a `.env` in your root directory and edit the value of the variable below with your Google Maps API key. [Here](https://youtu.be/hsNlz7-abd0?si=6gspahWWUMxd08z9) is a quick guide on how to get your Google Map API key from Google Console. ```bash VITE_GOOGLE_API_KEY=<your_api_key_here> ``` ## Implementing Live Location Tracking In the next few steps you will be implemtnting the functionalities of your react app. ### Importing Packages Go to the file `App.JSX` in your `/src/` directory, where you be making all the changes for your tracking app, since this will be a minimal tracking app. First you will need to import all the packages you need and replace the code in the file with the one below. ```javascript import { Box, ButtonGroup, Flex, HStack, IconButton, Text, } from "@chakra-ui/react"; import { FaTimes } from "react-icons/fa"; import { useJsApiLoader, GoogleMap, Marker } from "@react-google-maps/api"; import { useMemo, useRef, useState } from "react"; import { ClipLoader } from "react-spinners"; import { Button } from "@material-tailwind/react"; ``` The code snippet above simply imports the packages you will need for the UI component of the app, It includes imports from `chakra-ui` for interface components like `Box`, `ButtonGroup`, `Flex`, `HStack`, `IconButton`, and `Text`, as well as an icon from the React Icons library `FaTimes`. It also imports components and utilities from `@react-google-maps/api` to integrate Google Maps functionality, like GoogleMap and Marker. `useMemo`, `useRef`, and `useState` hooks are also imported from React for managing state and [memoizing](https://www.geeksforgeeks.org/what-is-memoization-a-complete-tutorial/) values. Finally, a loading spinner component `ClipLoader`, and a Button component are imported from the Material Tailwind library for UI consistency. ### Intializing Google Map Next, In your app component you use the `useJpApiLoader` to initialize the Google map and destructure an `isLoaded` value from it. Copy and add the code below to the file. ```javascript function App() { const { isLoaded } = useJsApiLoader({ googleMapsApiKey: `${import.meta.env.VITE_GOOGLE_API_KEY}`, libraries: ["places"], }); const [map, setMap] = useState(/** @type google.maps.Map */ (null)); const [location, setlocation] = useState("You are in"); const [center, setCenter] = useState({ lat: 42.8584, lng: 2.2945 }); const originRef = useRef(); ``` The component uses the `useState` hook to manage state variables: `map`, `location`, and `center`, where the state variable `map` holds a reference to the Google Map instance, initialized as null. The `location` state variable represents the current location, initialized with the text `You are in`. And the `center` state variable holds the coordinates for the map's center, initially set to `{ lat: 42.8584, lng: 2.2945 }`. The code also initializes a `useRef` hook named `originRef`, which will be used to reference the origin point for location tracking. ### Memoizing UseStates Next, the center `usestate` will be [memoized](https://www.geeksforgeeks.org/what-is-memoization-a-complete-tutorial/) by a `useMemo` hook to prevent rerenders, and boost efficiency. Copy and add the code below to the file. ```javascript const memoizedCenter = useMemo(() => center, [center]); if (!isLoaded) { return ( <div style={{ padding: "2.5rem", display: "flex", alignItems: "center", justifyContent: "center", }} > <ClipLoader size={50} color="red" /> </div> ); } ``` The `isloading` is used to know that the map has loaded and we use a clip loader to indicate the code below. ```javascript function clearRoute() { setlocation(""); } ``` Try reInitializing a `clearRoute` function to clear your location. ### Memoizing the Google For the Google map instance you will use the [memoized](https://www.geeksforgeeks.org/what-is-memoization-a-complete-tutorial/) value in the map to indicate the longitude and latitude and add a Google marker to show the position on the map. Copy and add the code below to the file. ```javascript <GoogleMap center={memoizedCenter} zoom={15} mapContainerStyle={{ width: "100%", height: "100%" }} options={{ zoomControl: false, streetViewControl: false, mapTypeControl: false, fullscreenControl: false, }} onLoad={(map) => setMap(map)} > <Marker position={memoizedCenter} /> </GoogleMap>; ``` In the code above the the map instance is set in the `setMap` use state. On clicking the button it triggers an asynchronous function to get the user's current location using the geolocation API. If geolocation is supported by the browser, it retrieves the `latitude` and `long` coordinates and sends a request to the Google Geocoding API to obtain the corresponding address. Upon receiving the address data, it updates the location state variable with the formatted address. Copy and paste the code below into your `App.jsx` file. ```javascript <Button className="bg-[#00d870a0] text-md" type="submit" onClick={async () => { if ("geolocation" in navigator) { navigator.geolocation.getCurrentPosition(async function ( position ) { const { latitude, longitude } = position.coords; const apiKey = `${import.meta.env.VITE_GOOGLE_API_KEY}`; const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}&key=${apiKey}`; setCenter({ lat: latitude, lng: longitude }); try { const response = await fetch(url); const data = await response.json(); if (data.status === "OK" && data.results.length > 0) { const address = data.results[0].formatted_address; setlocation("You are in: " + address); } else { alert("No address found for the provided coordinates"); return "No address found for the provided coordinates"; } } catch (error) { alert("Error fetching address:", error); console.error("Error fetching address:", error); return "Error"; } }); } else { alert("Geolocation is not supported by this browser."); } }} > Get Your Location </Button> <IconButton aria-label="center back" icon={<FaTimes />} onClick={clearRoute} /> </ButtonGroup> </HStack> <HStack spacing={4} mt={2} justifyContent="space-between"> <Text ref={originRef}>{location} </Text> </HStack> </Box> </Flex> ); } export default App; ``` The button at the top of the screen will run the function that will get a user's location on click. In the async function created you make use of the geolocation in navigatior. ## What is a navigator? The `navigator` object in the browser is part of the Web APIs provided by the browser environment. It provides information about the browser's environment and capabilities, allowing web developers to access various properties and methods related to the browser and the user's device. ### Some common properties and methods of the `navigator` object include: - `navigator.userAgent`: Returns a string representing the user-agent header sent by the browser to the server. It can detect the users' browser and operating system. - `navigator.language`: Returns a string representing the preferred language of the user, usually based on the browser's language settings. - `navigator.geolocation`: Provides access to the Geolocation API, allowing web applications to retrieve the user's current geographical location. - `navigator.cookieEnabled`: Returns a boolean indicating whețther cookies are enabled in the browser. - `navigator.onLine`: Returns a boolean indicating whether the browser is currently online or not. - The code uses of the `geolocation` in this navigation to get the user's longitude and latitude. ```javascript const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude }&key=${apiKey}`; ``` - The code gets users' addresses for that `long` and `lat` and displays it to them by adding it to the `setlocat`. - After editing your entire page `App.JSX` should look like the one below. You can copy and paste the entire page with the code below. ```javascript import { Box, ButtonGroup, Flex, HStack, IconButton, Text, } from "@chakra-ui/react"; import { FaTimes } from "react-icons/fa"; import { useJsApiLoader, GoogleMap, Marker } from "@react-google-maps/api"; import { useMemo, useRef, useState } from "react"; import { ClipLoader } from "react-spinners"; import { Button } from "@material-tailwind/react"; function App() { const { isLoaded } = useJsApiLoader({ googleMapsApiKey: `${import.meta.env.VITE_GOOGLE_API_KEY}`, libraries: ["places"], }); const [map, setMap] = useState(/** @type google.maps.Map */ (null)); const [location, setlocation] = useState("You are in"); const [center, setCenter] = useState({ lat: 42.8584, lng: 2.2945 }); const originRef = useRef(); const memoizedCenter = useMemo(() => center, [center]); if (!isLoaded) { return ( <div style={{ padding: "2.5rem", display: "flex", alignItems: "center", justifyContent: "center", }} > <ClipLoader size={50} color="red" /> </div> ); } function clearRoute() { setlocation(""); } return ( <Flex position="relative" flexDirection="column" alignItems="center" h="100vh" w="" > <Box position="absolute" left={0} top={0} h="100%" w="100%"> {/* Google Map Box */} <GoogleMap center={memoizedCenter} zoom={15} mapContainerStyle={{ width: "100%", height: "100%" }} options={{ zoomControl: false, streetViewControl: false, mapTypeControl: false, fullscreen control: false, }} onLoad={(map) => setMap(map)} > <Marker position={memoizedCenter} /> </GoogleMap> </Box> <Box p={4} borderRadius="lg" m={4} bgColor="white" shadow="base" zIndex="1" > <HStack spacing={2} justifyContent="space-between" className="flex-wrap" > <ButtonGroup> <Button className="bg-[#00d870a0] text-md" type="submit" onClick={async () => { if ("geolocation" in navigator) { navigator.geolocation.getCurrentPosition(async function ( position ) { const { latitude, longitude } = position.coords; const apiKey = `${import.meta.env.VITE_GOOGLE_API_KEY}`; const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}&key=${apiKey}`; setCenter({ lat: latitude, lng: longitude }); try { const response = await fetch(url); const data = await response.json(); if (data.status === "OK" && data.results.length > 0) { const address = data.results[0].formatted_address; setlocation("You are in: " + address); } else { alert("No address found for the provided coordinates"); return "No address found for the provided coordinates"; } } catch (error) { alert("Error fetching address:", error); console.error("Error fetching address:", error); return "Error"; } }); } else { alert("Geolocation is not supported by this browser."); } }} > Get Your Location </Button> <IconButton aria-label="center back" icon={<FaTimes />} onClick={clearRoute} /> </ButtonGroup> </HStack> <HStack spacing={4} mt={2} justifyContent="space-between"> <Text ref={originRef}>{location} </Text> </HStack> </Box> </Flex> ); } export default App; ``` - Go to the address local `http://localhost:5173/` on your browser and click on the **GET YOUR LOCATION** button. and voila ![image](https://hackmd.io/_uploads/SkPxXv6Cp.png) ## Enhancing User Experience Incorporating real-time location tracking into your React application opens up opportunities to enhance the overall user experience. Here are some considerations for how you can modify your designs ### Designing User-Friendly Interface Utilizing familiar design patterns, intuitive navigation, and responsive layouts to ensure a seamless user experience across devices can help users with visually appealing interfaces, and actionable information. ### Adding Geofencing and Notifications Geofencing allows you to define virtual boundaries around real-world geographic areas and trigger notifications or actions when users enter or exit these areas. Implement geofencing functionality to create location-based reminders, notifications, or alerts tailored to users' specific locations. This feature adds value by delivering timely and relevant information based on users' proximity to predefined geographic areas. ### Optimizing Performance Real-time location tracking involves continuous data updates and interactions with external services, which can impact application performance if not optimized properly. Implement techniques such as data caching, lazy loading, and debouncing to minimize unnecessary API calls and improve overall responsiveness. You can also consider optimizing battery usage by implementing efficient location-tracking algorithms and minimizing background activity when the application is not in use. ## Conclusion Viola, you have successfully created a live tracker following through the steps in the tutorial 🥂. Integrating real-time location tracking into your React apps offers a wealth of advantages, though it's not without its hurdles. Now you have learned how to use Google Maps to implement a live tracker on React. You have also learned new ways to develop your application to suit crafting interfaces that users would love to interact with. Moving Forward you can consider safeguarding users' privacy and prioritizing their security. By continuously exploring new possibilities, you can create real-time location-tracking experiences that truly make a positive impact on users.