Vector tile layer
Draws a MapLibre vector style (style.json) into raster tiles in the browser, so any map provider can show it. Maps that cannot read a vector style themselves — Google Maps, MapKit, HERE, ArcGIS, Cesium — end up looking the same as the rest.
01 · Overview
The renderer is written in Rust, compiled to wasm, and runs in a Web Worker. The tiles it draws are served by the SDK's local tile server (a Service Worker) and reach the map as an ordinary RasterLayer. To the map it is just a raster layer, which is why it works with every provider.
It mounts two layers: the ground (fills, lines and circles) and a transparent label layer above it. When a font range arrives only the label layer is redrawn, so the map never blanks for a moment as text appears. The attribution the style's sources ask for — OpenStreetMap and so on — is attached for you.
02 · Install
npm install @mapconductor/js-sdk-core @mapconductor/js-sdk-react \
@mapconductor/react-vectortile@mapconductor/js-vectorstyle comes along as a dependency. The package is ESM only.
Serve the tile Service Worker
Tiles are served from /tile-sw.js — the same requirement the heatmap has. Copy the file that ships in @mapconductor/js-sdk-core into your app's public directory.
{
"scripts": {
"postinstall": "cp node_modules/@mapconductor/js-sdk-core/dist/tile-sw.js public/tile-sw.js"
}
}A Vite production build needs the worker emitted as an ES module (the dev server does not).
import { defineConfig } from 'vite';
export default defineConfig({
worker: { format: 'es' },
});localhost, but opening the app from another device on the LAN needs HTTPS.03 · Basic usage
Put it inside any *MapView. style takes a style.json URL, its text, or the parsed object. The example below blanks Google Maps' own basemap (GoogleMapDesign.None) and draws the vector style in its place.
import { createGeoPoint, createMapCameraPosition } from '@mapconductor/js-sdk-core';
import { GoogleMapDesign, GoogleMapView2D, useGoogleMapViewState } from '@mapconductor/react-for-googlemaps';
import { VectorTileLayer } from '@mapconductor/react-vectortile';
const TOKYO = createGeoPoint({ latitude: 35.6812, longitude: 139.7671 });
const STYLE_URL = 'https://tiles.versatiles.org/assets/styles/colorful/style.json';
export function VectorTileMap() {
const state = useGoogleMapViewState({
apiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY,
mapDesignType: GoogleMapDesign.None,
cameraPosition: createMapCameraPosition({ position: TOKYO, zoom: 12 }),
});
return (
<GoogleMapView2D state={state} style={{ height: 480 }}>
<VectorTileLayer style={STYLE_URL} onDiagnostics={(messages) => console.warn(messages)} />
</GoogleMapView2D>
);
}style is compared by content, so building a new object with the same contents on every render does not redraw anything.
04 · Changing the look
Pass rules from style adjustments as rules and the style is drawn with them applied — colours changed, layers hidden. A role you hide (buildings, labels…) is not drawn at all.
import { useMemo } from 'react';
import { buildStyleRules, LayerRole } from '@mapconductor/js-vectorstyle';
import { VectorTileLayer } from '@mapconductor/react-vectortile';
const rules = useMemo(
() => buildStyleRules((r) => {
r.role(LayerRole.building, { visible: false });
r.role(LayerRole.water, { colorFilter: { mix: { color: '#3a7ca5', amount: 0.6 } } });
r.role(LayerRole.label, { opacity: 0.6 });
}),
[],
);
<VectorTileLayer style={STYLE_URL} rules={rules} />Changing the rules or the style redraws the vector tiles already in memory and fetches nothing: the shapes did not change, only how they are painted. Dragging a colour slider costs no network traffic. Leave rules out and the rules compiler (wasm) is never loaded.
05 · Using it as the basemap
With asBasemap, MapLibre, Mapbox and MapTiler get the style itself instead of raster tiles, and it replaces the map's design. Those three draw vector styles natively, which is faster and sharper. opacity does not apply in that case.
import { MapLibreMapView2D, useMapLibreViewState } from '@mapconductor/react-for-maplibre';
import { VectorTileLayer } from '@mapconductor/react-vectortile';
<MapLibreMapView2D state={state}>
<VectorTileLayer style={STYLE_URL} rules={rules} asBasemap />
</MapLibreMapView2D>On every other provider asBasemap changes nothing; blank the provider's own basemap yourself by switching to its None design.
06 · Props
Tiles that need a key
<VectorTileLayer
style="https://tiles.example.com/styles/basic/style.json"
headers={{ Authorization: `Bearer ${token}` }}
/>07 · Current limits
imports and some layer types are not drawn; they are reported through onDiagnostics.*MapView.