Navigation with Mapbox for Flutter apps
Mapbox is a powerful alternative to Google Maps Platform

When it comes to building great apps, the importance of maps cannot be overlooked. A diverse set of industries, ranging from logistics and automotive to transportation and government, use location, maps, and navigation daily to provide a great user experience in their mobile applications.
Love videos and find articles hard to read? I got you covered.😇 Watch the video below for a complete tutorial.
One of the first choices that come to mind is the Google Maps Platform. However, suppose you are a startup that’s just stepping into the market, a developer looking to publish your next great app on the App Store, or a student community building solutions for your school. In that case, Google Maps might get a little too costly for you, especially as the user base scales. This is where alternate solutions like Mapbox come into the picture.
Mapbox is an advanced and flexible map service that can be easily integrated into your mobile and web applications. It has some fantastic features such as Mapbox Studio, Vision, Atlas, and other commonly known SDKs. Many companies, including Facebook, Snap Inc., and Shopify, have benefitted from its mapping services.
In this article, let’s look at an implementation of Mapbox in a Flutter application and demonstrate the usage of its Maps and Navigation SDKs. We will do this by building a simple project involving a hungry you on a bicycle and a set of restaurants and cafes! And yes, as always, make sure to check out the video above for a complete tutorial.
Project description
So it’s your lucky day, and you find yourself in Apple Park, Cupertino, California, on a bicycle. But you are hungry as usual, you got four restaurants and need to locate the nearest one to you. It’d be great to additionally know how far they are and how long it would take for you to reach them, and also the best route to get there. This is how your problem will look visually.

First things first …
Before delving into Mapbox and implementing the above project, we need to set up our Flutter app. I have prepared a starter app for you, which you can use to follow along. Clone the repository, open the folder mapbox_navigation_starter in VS Code or Android Studio, and follow the instructions in the README to get things started.
In summary, you will have to add a few tokens and do some initial setup with Android and IOS separately before you can get started. You can find the complete set of instructions in the documentation below, and I have also demonstrated this in the video tutorial.
Understanding existing code
This is how the starter app looks initially after running successfully.



We have the data of 4 restaurants in the constants/restaurants.dart
file. Each restaurant has an id, name, items, image, and coordinates. The other data (wait time, close time, etc.) are dummy. Note that 2km is the same for all restaurants, but we will fix that in a bit. Let me quickly walk you through the other files in the project’s lib
folder.
helpers
folder contains 4 helper functions which handle things like managing fetched data from APIs, managing Shared Preferences data, and formatting or modifying data.requests
folder contains 1 file —mapbox_requests.dart
which has code to send a request to the Mapbox direction API. We’ll see more of this later when we start implementing this feature.screens
contain the 3 actual screens we see in the application — one for home, one for maps and one for a tabular view of restaurants.ui
contains 1 file —splash.dart
, which is our splash screen. It also has some crucial logic in itsinitState()
function.widgets
contains 1 file —carousel_card.dart
, which will be later used to create a carousel on the map and then switch between choices of restaurants.
Implement location capturing
In this section, we will first capture the user location, and then display it on the Restaurant Maps screen. For this, we will begin by ensuring that all required permissions are available and then capture the user location. We will then store this data in Shared Preferences. Finally, we will remove how Navigation is done with a Future.delayed()
. The contents of the function void initializeLocationAndSave()
are as below:
Now that location is stored in sharedPreferences
, all we have to do is capture this in the RestaurantMap
class and show the data to the user. We use the helper function LatLng getLatLngFromSharedPrefs(){}
for this purpose.
Use Mapbox Maps SDK
Now we can render a map on the screen and show our location on it. For this purpose we have to declare 2 variables —
late CameraPosition _initialCameraPosition;
late MapboxMapController controller;
We can then initalize the _initialCameraPosition
inside the initState()
function, and set it to current user location. Similarly, the controller is set to the controller returned inside _onMapCreated()
function.
@override
void initState() {
super.initState();
_initialCameraPosition = CameraPosition(target: latLng, zoom: 15);
}_onMapCreated(MapboxMapController controller) async {
this.controller = controller;
}
Finally, we modify the flutter code to show the map on the screen using the MapboxMap
widget and yaaay! We have the user location on a map rendered on the screen!


We have also added a floating action button in the bottom right, which redirects user to the current location, and it has the following code —
floatingActionButton: FloatingActionButton(
onPressed: () {
controller.animateCamera(
CameraUpdate.newCameraPosition(_initialCameraPosition));
},
child: const Icon(Icons.my_location),
),
Use Mapbox Directions API
In this section, let’s look at the Direction API, it’s response and how we use it in our application. We can see the response of the API in the Mapbox Playground here —
In the response 3 things are important to us. They are the geometry
object which represents coordinates to use in the line-layer, the distance
and the duration
. We make a note of these and add the following lines in the splash.dart
file inside the initState()
function.
// Get and store the directions API response in sharedPreferences
for (int i = 0; i < restaurants.length; i++) {
Map modifiedResponse = await getDirectionsAPIResponse(currentLatLng, i);
saveDirectionsAPIResponse(i, json.encode(modifiedResponse));
}
Finally as a check, we restart the app and remove the hardcoded distance and show the actual distance obtained from the API in the Restaurants Table
file.
Stack a CarouselSlider on the map
A carousel slider consisting of cards of restaurants can be stacked on the top of the Map. The idea would be to show a particular route whenever a specific item is highlighted. We would also sort the restaurants based on the time taken to reach them.
Add Symbols and Line Layers
Now we can finally add symbols and line layers on the map to represent the routes. For this, we will use the addSymbol
and addLineLayer
methods on the controller object. Also we will make sure to remove the previous line layers so that we do not have multiple layers.
After adding codes for these, our restaurants_map.dart
file finally looks like this -
Winding up finally!
Finally, we can run our app and after a hot restart, here are the final screens we can see:



You can run it on the Android Emulator as well, and see a different result if you set your current location to one that is slightly away from the location above. This shows that the app will work great if you can track the user location dynamically instead of adding them to Shared Preferences.
Conclusion
This blog has demonstrated how easily you can integrate Mapbox into your Flutter app, but the same holds for any kind of app as well. We can also implement a turn-by-turn navigation to guide the user to a location even as they are travelling, which would be an interesting thing to do.
If you have used Mapbox before in Flutter or elsewhere, let me know how your experience was as compared to Google Maps Platform. If any step here in the blog confuses you, the comment section is all yours!
The Github repository for this can be found here (already mentioned before in the blog but still!) —
Also you can connect with me on LinkedIn here —
And as always, Happy Hacking!!! 😄