> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/help/llms.txt)

# Use Mapbox GL JS in an Angular app

[Angular](https://angular.dev/) is a popular front-end framework for building web applications. This tutorial will show you how to get started with Angular and [Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js/) and is designed for developers who have some familiarity with JavaScript. You will learn:

-   How to set up an Angular app using the Angular CLI.
-   How to install Mapbox GL JS and its dependencies.
-   Use Mapbox GL JS to render a full screen map.
-   How to add a toolbar which displays map state like `longitude`, `latitude`, and `zoom level` and is updated as the map is interacted with (showing the map to app data flow).
-   How to create a UI button to reset the map to its original view (showing the app to map data flow).

You can test the final result of this tutorial in the preview below.

If you would like to run the finished product locally before following the tutorial, you can find the source code for this tutorial on [GitHub](https://github.com/mapbox/tutorials/tree/main/use-mapbox-gl-js-with-angular/).

If you'd like to get an Angular app running with **Mapbox GL JS** and are not interested in the additional learning of this tutorial use the Mapbox `npm create @mapbox/web-app` utility, choose Angular as your framework and scaffold your application in seconds.

```
$ npm create @mapbox/web-app
```

**Time to get building!** 🛠 This tutorial should take about 20 minutes to complete.

## Prerequisites

You will need a few things in place before starting this tutorial:

-   **A Mapbox access token**: Find yours on the [Access token page](https://console.mapbox.com/account/access-tokens/) of your Developer Console.
-   **A Code editor**: A program like [Visual Studio Code](https://code.visualstudio.com/).
-   **Node.js and npm.** [Download and install](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) the latest version.
-   **Angular CLI.** You will install this below.
-   **Familiarity with a terminal** to execute node.js and npm commands.
-   **Familiarity with Angular development.** Beginner experience with Angular and JavaScript.

> **Note (note): This tutorial uses Angular v19.0**
> 
> This tutorial uses Angular `v19.0` and uses Angular [signals](https://angular.dev/essentials/signals#) which are available in `v17.0` and up. If you are using an older version of Angular, you may need to make some adjustments to the code.

### Verify Node version & install Angular CLI

This tutorial uses the latest version of Angular and requires Node.js v18.20 or higher. You can check your version of Node.js by running the following command in your terminal:

```bash
$ node -v
```

If you are running an older version of Node.js, you can download the latest version from the [Node.js website](https://nodejs.org/en/download/). or use a version manager like [`nvm`](https://github.com/nvm-sh/nvm) to install and manage Node.js versions.

Next, install [Angular CLI](https://angular.dev/tools/cli) using npm with the following command. If you already have Angular CLI installed, you can skip this step.

```bash
$ npm install -g @angular/cli
```

## Create a new Angular app

Create a new Angular project using the Angular CLI. You can name your project whatever you like, but this tutorial will use `mapbox-angular-tutorial`.

```bash
$ ng new mapbox-angular-tutorial
```

You will be prompted to choose a few options for your project. Choose `css` or `scss` for the stylesheet format. Choose 'Yes' to enable server-side rendering. Choose 'No' for routing.

You should see output like this:

```bash
ng new mapbox-angular-tutorial
✔ Which stylesheet format would you like to use? CSS             [ 
https://developer.mozilla.org/docs/Web/CSS                     ]
✔ Do you want to enable Server-Side Rendering (SSR) and Static Site Generation 
(SSG/Prerendering)? Yes
✔ Would you like to use the Server Routing and App Engine APIs (Developer Preview) 
for this server application? No
CREATE mapbox-angular-tutorial/README.md (1479 bytes)
CREATE mapbox-angular-tutorial/.editorconfig (314 bytes)
CREATE mapbox-angular-tutorial/.gitignore (587 bytes)
CREATE mapbox-angular-tutorial/angular.json (2784 bytes)
CREATE mapbox-angular-tutorial/package.json (1261 bytes)
CREATE mapbox-angular-tutorial/tsconfig.json (915 bytes)
CREATE mapbox-angular-tutorial/tsconfig.app.json (489 bytes)
CREATE mapbox-angular-tutorial/tsconfig.spec.json (434 bytes)
CREATE mapbox-angular-tutorial/.vscode/extensions.json (130 bytes)
CREATE mapbox-angular-tutorial/.vscode/launch.json (470 bytes)
CREATE mapbox-angular-tutorial/.vscode/tasks.json (938 bytes)
CREATE mapbox-angular-tutorial/src/main.ts (250 bytes)
CREATE mapbox-angular-tutorial/src/index.html (301 bytes)
CREATE mapbox-angular-tutorial/src/styles.css (80 bytes)
CREATE mapbox-angular-tutorial/src/main.server.ts (264 bytes)
CREATE mapbox-angular-tutorial/src/server.ts (1785 bytes)
CREATE mapbox-angular-tutorial/src/app/app.component.css (0 bytes)
CREATE mapbox-angular-tutorial/src/app/app.component.html (19903 bytes)
CREATE mapbox-angular-tutorial/src/app/app.component.spec.ts (949 bytes)
CREATE mapbox-angular-tutorial/src/app/app.component.ts (293 bytes)
CREATE mapbox-angular-tutorial/src/app/app.config.ts (438 bytes)
CREATE mapbox-angular-tutorial/src/app/app.routes.ts (77 bytes)
CREATE mapbox-angular-tutorial/src/app/app.config.server.ts (351 bytes)
CREATE mapbox-angular-tutorial/public/favicon.ico (15086 bytes)
✔ Packages installed successfully.
    Successfully initialized git.
```

### Install Mapbox GL JS

Next, navigate to the project directory:

```bash
$ cd mapbox-angular-tutorial
```

and install Mapbox GL JS using npm:

```bash
$ npm install mapbox-gl
```

### Add the Mapbox GL CSS to your project

Mapbox GL JS requires a CSS file to be included in your project. With Angular, you can add third party CSS files to your project using the `angular.json` file. Open the `angular.json` file at the top level of your project and add the Mapbox GL JS CSS import to the `styles` array.

```json
...
 "styles": [
    "src/styles.scss",
    // highlight-start
    "node_modules/mapbox-gl/dist/mapbox-gl.css"
    // highlight-end
  ],
```

Now the Mapbox GL JS CSS is included in your project when you build or serve your app.

## Create a map component

Use the Angular CLI [generate component](https://angular.dev/cli/generate/component) command to create a new component called `map`:

```bash
$ ng generate component map
```

This will create a new folder called `map` in the `src/app` directory with the following files:

-   `map.component.css`
-   `map.component.html`
-   `map.component.spec.ts`
-   `map.component.ts`

### The `map.component.ts` file

In the `map.component.ts` file, you will render the map and handle user interactions. Copy and paste the code snippet below into the file.

This code sets up a standalone component named `MapComponent` to create the map and imports the necessary dependencies, including `ElementRef`, `OnInit`, and `OnDestroy` from Angular core, and `isPlatformBrowser` from Angular common. The component uses the `@ViewChild` decorator to get a reference to the map container element in the template. The `ngOnInit` method initializes the map when the component is loaded, and the `ngOnDestroy` method removes the map when the component is destroyed.

The `map.component.ts` file also uses the `PLATFORM_ID` token to check if the code is running in the browser or on the server. This is important because Mapbox GL JS requires a browser environment to work properly. The `isPlatformBrowser` function checks if the current platform is the browser, and if so, it dynamically imports the Mapbox GL JS library and creates a new map instance.

Inside the map instance you pass your Mapbox access token, the container element, the initial center coordinates, and the initial zoom level. The `accessToken` is a required parameter for Mapbox GL JS to authenticate your requests to the Mapbox API. Replace `YOUR_MAPBOX_ACCESS_TOKEN` in the code snippet below with your token, found in the top right corner of your [Mapbox Developer Console](https://console.mapbox.com).

```typescript
import { Component, ElementRef, OnDestroy, OnInit, ViewChild, inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { PLATFORM_ID } from '@angular/core';

@Component({
  selector: 'app-map', 
  standalone: true,
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.css']
})
export class MapComponent implements OnInit, OnDestroy {
  @ViewChild('mapContainer', { static: true }) mapContainer!: ElementRef;
  map: any;
  private platformId = inject(PLATFORM_ID);

  async ngOnInit() {
    if (isPlatformBrowser(this.platformId)) { // SSR check to ensure this runs in the browser as GL JS requires a browser environment
      const mapboxgl = (await import('mapbox-gl')).default // dynamically import mapbox-gl as the default export

      // Create a new map instance
      this.map = new mapboxgl.Map({
        accessToken: 'YOUR_MAPBOX_ACCESS_TOKEN',
        container: this.mapContainer.nativeElement, // Reference to the map container element
        center: [-98.54818, 40.00811], // Center coordinates for map over the continental US
        zoom: 4, // Initial zoom level
      });
    }
  }

  ngOnDestroy(): void {
    if (this.map) {
      this.map.remove();
    }
  }
}
```

### The `map.component.html` file

Next, add the HTML template for the map component. The `map.component.html` file contains a single `div` element with the `mapContainer` reference. This is where the map will be rendered. Copy and paste the code snippet below into the `map.component.html` file.

```html
<div #mapContainer id="map-container"></div>
```

### Add CSS styles

Next, add 2 snippets of CSS. A global snippet to the `src/styles.css` file to remove margins and padding from the `body` and `html` elements.

```css
html, body {
  margin: 0;
  padding: 0;
}
```

And a snippet to the `map.component.css` file to set the height and width of the map container to the full height and width of the viewport.

```css
#map-container {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}
```

### Import your `MapComponent` into the `AppComponent`

Lastly, you need to add your `MapComponent` component and its selector to the `AppComponent`.

Open the `src/app/app.component.ts` file and add the import for our `MapComponent` and add the `MapComponent` to the imports array of the `@Component`. You can remove the `RouterOutlet` as we are not using this in our project. The `app.component.ts` file should look like this.

```typescript
import { Component } from '@angular/core';
// highlight-start
import { MapComponent } from './map/map.component';
// highlight-end

@Component({
  selector: 'app-root',
  // highlight-start
  imports: [MapComponent],
  // highlight-end
  templateUrl: './app.component.html',
  styleUrl: './app.component.scss'
})
export class AppComponent {
  title = 'mapbox-angular-tutorial';
}
```

Now open the `src/app/app.component.html` file and replace the existing content with the following code snippet. This the `MapComponent` selector and will render the map component in the app.

```html
<app-map></app-map>
```

Now you can run the app using the Angular CLI. In your terminal, run the following command:

```bash
$ npm start
```

This will start the development server and give you a URL to view your app in the browser. By default, this will be `http://localhost:4200/`. Open this URL in your browser and you should see a map of the continental United States.

![Map of the US with Sidebar](https://docs.mapbox.com/help/assets/ideal-img/tutorials--use-mapbox-gl-js-with-angular--mapview-of-usa.7edabaa.480.png)

Next, you will add a toolbar to the map that displays the current map state. This will show you how to use Mapbox GL JS to update the map state and how to use Angular signals to update the UI.

## Create the toolbar

To create the toolbar you will update the `map.component.ts` with new imports and functionality for state management and you will add new HTML to render the toolbar and state value, and some CSS to style the toolbar.

Start with `map.component.ts`. Review the highlights in the code snippet below and update your `map.component.ts` to match. The update code adds 2 additional imports, `signal` from `@angular/core` and `CommonModule` from `@angular/common`. It declares 2 `INITIAL_` constants to store the map center and map zoom values and imports the `CommonModule` into the component so that you can use [pipes](https://angular.dev/guide/templates/pipes#) in your toolbar HTML. Lastly it declares 2 [signals](https://angular.dev/guide/signals) (reactive state) to track the map center and zoom and the [map.on('move')](https://docs.mapbox.com/mapbox-gl-js/api/map/#map.event:move) event, to update the signals when the map is being interacted with.

```typescript
import {  Component,
  ElementRef,
  OnDestroy,
  OnInit,
  ViewChild,
  inject,
  // highlight-start
  signal } from '@angular/core'; // Add import for signal
import { isPlatformBrowser, CommonModule } from '@angular/common'; // Add import for CommonModule
// highlight-end
import { PLATFORM_ID } from '@angular/core';

// highlight-start
const INITIAL_CENTER: [number, number] = [-98.54818, 40.00811];
const INITIAL_ZOOM = 3.2;
// highlight-end

@Component({
  selector: 'app-map',
  standalone: true,
  // highlight-start
  imports: [CommonModule], // imports built-in pipes like number, date, currency
  // highlight-end
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.scss']
})
export class MapComponent implements OnInit, OnDestroy {
  @ViewChild('mapContainer', { static: true }) mapContainer!: ElementRef;
  map: any;
  private platformId = inject(PLATFORM_ID);

  // highlight-start
  // Signals to track center and zoom
  center = signal<[number, number]>(INITIAL_CENTER);
  zoom = signal<number>(INITIAL_ZOOM);
 // highlight-end

  async ngOnInit() {
    if (isPlatformBrowser(this.platformId)) {
    // Dynamically import Mapbox GL JS with default export.
    const mapboxgl = (await import('mapbox-gl')).default
  
      this.map = new mapboxgl.Map({
        accessToken: 'pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY203dWs2ajdhMDFnbDJscHRtY2liNnB1byJ9.EsCqiekql3X53WHrRiZ0rg',
        container: this.mapContainer.nativeElement,
        // highlight-start
        center: this.center(),
        zoom: this.zoom()
        // highlight-end  
    });

      // highlight-start
      // GL JS's map.on('move') event listener to update signals
      this.map.on('move', () => {
        const newCenter = this.map.getCenter();
        this.center.set([newCenter.lng, newCenter.lat]);
        this.zoom.set(this.map.getZoom());
      });
      // highlight-end
    }
  }

  ngOnDestroy(): void {
    if (this.map) {
      this.map.remove();
    }
  }
}
```

After your `map.component.ts` file is updated, open the `map.component.html` file add the new lines highlighted in this snippet to render the toolbar. This will add a toolbar to the map that displays the current `longitude`, `latitude` and `zoom` level by calling the signal values. Angular pipes are used to format the latitude and longitude values to 4 decimal places and the zoom level to 2 decimal places.

```html
// highlight-start
<div class="toolbar">
  Longitude: {{ center()[0] | number:'1.4-4' }} |
  Latitude: {{ center()[1] | number:'1.4-4' }} |
  Zoom: {{ zoom() | number:'1.2-2' }}
</div>
// highlight-end
<div #mapContainer id="map-container"></div>
```

Now, open the `map.component.css` file and add the following CSS snippet below your `#map-containter` selector. This will position the toolbar in the top left corner of the map and give it a background color and padding.

```css
.toolbar {
  background-color: rgb(35 55 75 / 90%);
  color: #fff;
  padding: 6px 12px;
  font-family: monospace;
  z-index: 1;
  position: absolute;
  top: 0;
  left: 0;
  margin: 12px;
  border-radius: 4px;
}
```

Now you can refresh your app in the browser and you should see the toolbar in the top left corner of the map. As you interact with the map, the longitude, latitude, and zoom level will update in real time.

Your browser doesn't support HTML5 video. Open [link to the video](https://docs.mapbox.com/help/help/assets/medias/tutorials--use-mapbox-gl-js-with-angular--toolbar-0f37d2b176accc857ecff514f1af21e4.mp4).

## Create the reset button

Now that you are passing map data to the app, the last step is to create a button in the app that will trigger a reset of the map's state. To do this, you will add a button to the `map.component.html` and update the `map.component.ts` file to handle the button click event.

Start with the `map.component.html` file. Add the highlighted code line from the snippet below to your file. This will add a button to the UI and sets a click handler `resetView()` that you will define next..

```html
<div class="toolbar">
  Longitude: {{ center()[0] | number:'1.4-4' }} |
  Latitude: {{ center()[1] | number:'1.4-4' }} |
  Zoom: {{ zoom() | number:'1.2-2' }}
</div>
// highlight-start
<button class="reset-button" (click)="resetView()">Reset View</button> <!-- 👈 Angular click binding -->
// highlight-end
<div #mapContainer id="map-container"></div>
```

Add this CSS snippet to the bottom of your `map.component.css` file to style the button.

```css
...

.reset-button {
  position: absolute;
  top: 45px;
  z-index: 1;
  left: 11px;
  padding: 4px 10px;
  border-radius: 10px;
  cursor: pointer;
}
```

Next, open the `map.component.ts` file and add the `resetView()` method near the bottom of your component declaration right above the `ngOnDestroy()` method. Now when the button is clicked the [map.flyTo](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#flyto) method is used to fly the map to the starting view.

```typescript
 ...
 // highlight-start
  resetView() {
    this.map.flyTo({
      center: INITIAL_CENTER,
      zoom: INITIAL_ZOOM,
      essential: true 
    });
  }
  // highlight-end
  ngOnDestroy(): void {
    if (this.map) {
      this.map.remove();
    }
  }
```

Now you can refresh your app in the browser and you should see the reset button in the top left corner of the map. When you click the button, the map will fly back to its starting view.

![Map of the US with Reset Button](https://docs.mapbox.com/help/assets/ideal-img/tutorials--use-mapbox-gl-js-with-angular--reset-button.889c2cb.480.png)

## Finished Project

🎉 **Congratulations!** You have successfully created an Angular app that uses [Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js/) to render a map. You have also added a toolbar that displays the current map state and a button to reset the map view.

The finished project should look like this.

### Full code snippets

The full code snippets for the `map.component.ts`, `map.component.html` and `map.component.css` files are below.

**TS**

Title: `map.component.ts`

```typescript
import { Component, ElementRef, OnDestroy, OnInit, ViewChild, inject, signal } from '@angular/core';
import { isPlatformBrowser, CommonModule } from '@angular/common';
import { PLATFORM_ID } from '@angular/core';

const INITIAL_CENTER: [number, number] = [-98.54818, 40.00811];
const INITIAL_ZOOM = 3.2;

@Component({
  selector: 'app-map',
  standalone: true,
  imports: [CommonModule],
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.css']
})
export class MapComponent implements OnInit, OnDestroy {
  @ViewChild('mapContainer', { static: true }) mapContainer!: ElementRef;
  map: any;
  private platformId = inject(PLATFORM_ID);

   // Signals to track center and zoom
  center = signal<[number, number]>(INITIAL_CENTER);
  zoom = signal<number>(INITIAL_ZOOM);

  async ngOnInit() {
    if (isPlatformBrowser(this.platformId)) {
    const mapboxgl = (await import('mapbox-gl')).default

      this.map = new mapboxgl.Map({
        accessToken: 'pk.eyJ1IjoiZXhhbXBsZXMiLCJhIjoiY203dWs2ajdhMDFnbDJscHRtY2liNnB1byJ9.EsCqiekql3X53WHrRiZ0rg',
        container: this.mapContainer.nativeElement,
        center: this.center(),
        zoom: this.zoom()
      });

      // GL JS's map.on('move') event listener to update signals
      this.map.on('move', () => {
        const newCenter = this.map.getCenter();
        this.center.set([newCenter.lng, newCenter.lat]);
        this.zoom.set(this.map.getZoom());
      });
    }
  }

  // Click handler to reset the map view
  resetView() {
    if (this.map) {
      this.map.flyTo({
        center: INITIAL_CENTER,
        zoom: INITIAL_ZOOM
      });
    }
  }

  ngOnDestroy(): void {
    if (this.map) {
      this.map.remove();
    }
  }
}
```

**HTML**

Title: `map.component.html`

```html
<div class="toolbar">
  Longitude: {{ center()[0] | number: '1.4-4' }} | Latitude:
  {{ center()[1] | number: '1.4-4' }} | Zoom: {{ zoom() | number: '1.2-2' }}
</div>
<button class="reset-button" (click)="resetView()">Reset View</button>
<div #mapContainer id="map-container"></div>
```

**CSS**

Title: `map.component.css`

```css
#map-container {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}

.toolbar {
  background-color: rgb(35 55 75 / 90%);
  color: #fff;
  padding: 6px 12px;
  font-family: monospace;
  z-index: 1;
  position: absolute;
  top: 0;
  left: 0;
  margin: 12px;
  border-radius: 4px;
}

.reset-button {
  position: absolute;
  top: 45px;
  z-index: 1;
  left: 11px;
  padding: 4px 10px;
  border-radius: 10px;
  cursor: pointer;
}
```

## Next Steps

Now that you have a basic understanding of how to use Mapbox GL JS in an Angular app, you can explore more advanced features and functionality.

### What we covered

-   How to set up an Angular app using the Angular CLI.
-   How to install Mapbox GL JS and its dependencies.
-   Use Mapbox GL JS to render a full screen map.
-   How to add a toolbar which displays map state like `longitude`, `latitude`, and `zoom level` and is updated as the map is interacted with (showing the map to app data flow).
-   How to create a UI button to reset the map to its original view (showing the app to map data flow).

### Learn more

Browse the source code for this tutorial on [GitHub](https://github.com/mapbox/tutorials/tree/main/use-mapbox-gl-js-with-angular/)

If you'd like an additional challenge, try implementing the following features:

-   Create a UI element with links or buttons which will toggle different light presets available in the [Mapbox Standard Style](https://docs.mapbox.com/map-styles/standard/guides/). These can trigger a callback function that uses the [`map.setConfigProperty`](https://docs.mapbox.com/map-styles/standard/guides/#setting-configuration-options-at-runtime) method to change the light preset.
-   Use the [Location Helper](https://labs.mapbox.com/location-helper/) tool to get the coordinates, bearing and pitch of a few of your favorite locations. Store these in an array in your `map.component.ts` and create a 'Next / Previous' button to cycle through and `flyTo` each location.
-   Add [rain](https://docs.mapbox.com/mapbox-gl-js/example/rain/) or [snow](https://docs.mapbox.com/mapbox-gl-js/example/snow/) effects to your map at low zoom levels for an immersive experience.

> **Related content (example): [Browse Mapbox GL JS Examples for inspiration](https://docs.mapbox.com/mapbox-gl-js/example/)**
> 
> There are over 120 examples in the Mapbox GL JS Examples. You can use these as inspiration for your own projects or as a starting point for your own applications.