Map Styles

ng-mapcn renders any MapLibre-compatible basemap. Carto is the default; here is a working example for each major provider.

Pass a per-theme styles config to a single map, or call provideMapStyles() once to set the basemap for the whole app — that is exactly what the basemap picker in this site's header does, so every map below (and on every other page) follows it live.

Carto (default)

#

Used when no styles is given: Positron for light, Dark Matter for dark. No API key. Other variants: voyager-gl-style and the *-nolabels-* styles — this preview uses Voyager.

<!-- No [styles] input: Carto Positron (light) / Dark Matter (dark) -->
<ng-map [center]="[2.3522, 48.8566]" [zoom]="11" />

<!-- Other Carto variants, passed explicitly -->
<ng-map
  [styles]="{
    light: 'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json',
    dark: 'https://basemaps.cartocdn.com/gl/dark-matter-nolabels-gl-style/style.json'
  }"
/>

OpenFreeMap

#

Free vector tiles built from OpenStreetMap data — no registration, no API key, no request limits. Styles: liberty, bright, positron, dark, fiord.

import { Component } from '@angular/core';
import { MapComponent, MapStylesConfig } from 'ng-mapcn';

@Component({
  selector: 'app-openfreemap',
  standalone: true,
  imports: [MapComponent],
  template: `
    <div class="h-[420px]">
      <ng-map [center]="[13.388, 52.517]" [zoom]="11" [styles]="styles" />
    </div>
  `,
})
export class OpenFreeMapComponent {
  // No key, no registration, no request limits.
  // Styles: liberty | bright | positron | dark | fiord
  readonly styles: MapStylesConfig = {
    light: 'https://tiles.openfreemap.org/styles/positron',
    dark: 'https://tiles.openfreemap.org/styles/dark',
  };
}

OpenStreetMap

#

OSM does not host a style.json — it serves raster tiles, so the MapLibre style is written by hand. Keep the object in a constant: the map compares the resolved style by identity before calling setStyle. The public tile server is for development and small demos only — read the tile usage policy before shipping it (OpenFreeMap is the drop-in alternative).

import { Component } from '@angular/core';
import type { StyleSpecification } from 'maplibre-gl';
import { MapComponent, MapStylesConfig } from 'ng-mapcn';

// OpenStreetMap serves raster tiles, not a hosted style.json — build the
// MapLibre style by hand. Keep it as a constant: ng-map compares the resolved
// style by identity before calling setStyle().
const OSM_STYLE: StyleSpecification = {
  version: 8,
  sources: {
    osm: {
      type: 'raster',
      tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'],
      tileSize: 256,
      maxzoom: 19,
      attribution: '© OpenStreetMap contributors',
    },
  },
  layers: [{ id: 'osm', type: 'raster', source: 'osm' }],
};

@Component({
  selector: 'app-osm-map',
  standalone: true,
  imports: [MapComponent],
  template: `
    <div class="h-[420px]">
      <ng-map [center]="[-0.1276, 51.5074]" [zoom]="12" [styles]="styles" />
    </div>
  `,
})
export class OsmMapComponent {
  // Raster has no dark variant — same style for both themes.
  readonly styles: MapStylesConfig = { light: OSM_STYLE, dark: OSM_STYLE };
}

MapTiler

#

Requires an API key (?key=). Style ids follow the streets-v4 / streets-v4-dark pattern (also dataviz-v4, satellite). To preview it live, pick MapTiler in the header and paste your key — it is kept in your browser only.

Select MapTiler in the header and paste an API key to preview this basemap.
import { Component } from '@angular/core';
import { MapComponent, MapStylesConfig } from 'ng-mapcn';

@Component({
  selector: 'app-maptiler-map',
  standalone: true,
  imports: [MapComponent],
  template: `
    <div class="h-[420px]">
      <ng-map [center]="[-46.633, -23.55]" [zoom]="11" [styles]="styles" />
    </div>
  `,
})
export class MapTilerMapComponent {
  // Get a key at https://cloud.maptiler.com/account/keys/
  // Style ids: streets-v4, streets-v4-dark, dataviz-v4, dataviz-v4-dark,
  //            satellite, outdoor-v2, ... (v2 ids still work)
  private readonly key = 'YOUR_MAPTILER_KEY';

  readonly styles: MapStylesConfig = {
    light: `https://api.maptiler.com/maps/streets-v4/style.json?key=${this.key}`,
    dark: `https://api.maptiler.com/maps/streets-v4-dark/style.json?key=${this.key}`,
  };
}

Stadia Maps

#

Keyless on localhost (rate limited); in production use ?api_key= or domain-based auth. Styles: alidade_smooth, alidade_smooth_dark, outdoors, osm_bright.

import { Component } from '@angular/core';
import { MapComponent, MapStylesConfig } from 'ng-mapcn';

@Component({
  selector: 'app-stadia-map',
  standalone: true,
  imports: [MapComponent],
  template: `
    <div class="h-[420px]">
      <ng-map [center]="[12, 53]" [zoom]="5" [styles]="styles" />
    </div>
  `,
})
export class StadiaMapComponent {
  // On localhost / 127.0.0.1 the key is optional (rate limited). In production
  // use an API key or domain-based auth: https://client.stadiamaps.com/
  // Styles: alidade_smooth, alidade_smooth_dark, outdoors, osm_bright, stamen_*
  private readonly auth = '?api_key=YOUR_STADIA_KEY';

  readonly styles: MapStylesConfig = {
    light: `https://tiles.stadiamaps.com/styles/alidade_smooth.json${this.auth}`,
    dark: `https://tiles.stadiamaps.com/styles/alidade_smooth_dark.json${this.auth}`,
  };
}

App-wide basemap

#

provideMapStyles() sets the default basemap for every ng-map in the app. Precedence: [styles] → [blank] → provideMapStyles() → Carto. Pass a signal and the basemap swaps at runtime — the header picker on this site is that signal.

// basemap.service.ts — one signal holding the app's basemap
import { computed, Injectable, signal } from '@angular/core';
import { MapStylesConfig } from 'ng-mapcn';

@Injectable({ providedIn: 'root' })
export class BasemapService {
  readonly provider = signal<'carto' | 'openfreemap'>('carto');

  readonly styles = computed<MapStylesConfig | undefined>(() =>
    this.provider() === 'openfreemap'
      ? {
          light: 'https://tiles.openfreemap.org/styles/positron',
          dark: 'https://tiles.openfreemap.org/styles/dark',
        }
      : undefined, // undefined = built-in Carto defaults
  );
}

// app.config.ts
import { inject } from '@angular/core';
import { provideMapStyles } from 'ng-mapcn';

export const appConfig: ApplicationConfig = {
  providers: [
    // Also accepts a plain config: provideMapStyles({ light, dark })
    provideMapStyles(() => inject(BasemapService).styles),
  ],
};