A Street View control for MapLibre GL JS with support for both Google Street View and Mapillary imagery.
- Dual Provider Support: Switch between Google Street View and Mapillary imagery
- Click-to-View: Click anywhere on the map to view street-level imagery
- Interactive Viewers:
- Google Street View: Interactive 360° panoramas via iframe embed
- Mapillary: Full MapillaryJS viewer with navigation
- Collapsible & Resizable Panel: Adjustable panel that doesn't obstruct the map
- Direction Marker: Map marker showing current view location and heading direction
- Nearest Coverage Search: Automatically finds nearby imagery when none exists at clicked location
- React Support: Full React integration with hooks and wrapper component
- TypeScript: Written in TypeScript with complete type definitions
npm install maplibre-gl-streetviewimport maplibregl from 'maplibre-gl';
import { StreetViewControl } from 'maplibre-gl-streetview';
import 'maplibre-gl/dist/maplibre-gl.css';
import 'maplibre-gl-streetview/style.css';
import 'mapillary-js/dist/mapillary.css'; // Required for Mapillary viewer
const map = new maplibregl.Map({
container: 'map',
style: 'https://demotiles.maplibre.org/style.json',
center: [-122.4194, 37.7749],
zoom: 14,
});
map.on('load', () => {
const streetView = new StreetViewControl({
googleApiKey: 'YOUR_GOOGLE_MAPS_API_KEY',
mapillaryAccessToken: 'YOUR_MAPILLARY_ACCESS_TOKEN',
defaultProvider: 'google',
panelWidth: 400,
panelHeight: 300,
});
map.addControl(streetView, 'top-right');
// Listen for events
streetView.on('locationchange', (event) => {
console.log('Viewing:', event.state.location);
});
});import { useEffect, useRef, useState } from 'react';
import maplibregl, { Map } from 'maplibre-gl';
import { StreetViewControlReact, useStreetViewState } from 'maplibre-gl-streetview/react';
import 'maplibre-gl/dist/maplibre-gl.css';
import 'maplibre-gl-streetview/style.css';
import 'mapillary-js/dist/mapillary.css';
function App() {
const mapContainer = useRef<HTMLDivElement>(null);
const [map, setMap] = useState<Map | null>(null);
const { state, toggle, setProvider } = useStreetViewState();
useEffect(() => {
if (!mapContainer.current) return;
const mapInstance = new maplibregl.Map({
container: mapContainer.current,
style: 'https://demotiles.maplibre.org/style.json',
center: [-122.4194, 37.7749],
zoom: 14,
});
mapInstance.on('load', () => setMap(mapInstance));
return () => mapInstance.remove();
}, []);
return (
<div style={{ width: '100%', height: '100vh' }}>
<div ref={mapContainer} style={{ width: '100%', height: '100%' }} />
{map && (
<StreetViewControlReact
map={map}
googleApiKey="YOUR_GOOGLE_MAPS_API_KEY"
mapillaryAccessToken="YOUR_MAPILLARY_ACCESS_TOKEN"
collapsed={state.collapsed}
defaultProvider={state.activeProvider}
onStateChange={(newState) => console.log(newState)}
/>
)}
</div>
);
}- Go to Google Cloud Console
- Create a new project or select existing one
- Enable the Maps Embed API
- Create an API key in Credentials
- Sign up at Mapillary
- Go to Developer Dashboard
- Create a new application
- Copy your client access token
| Option | Type | Default | Description |
|---|---|---|---|
collapsed |
boolean |
true |
Start with panel collapsed |
position |
string |
'top-right' |
Control position on map |
title |
string |
'Street View' |
Panel header title |
panelWidth |
number |
400 |
Panel width in pixels |
panelHeight |
number |
300 |
Panel height in pixels |
defaultProvider |
'google' | 'mapillary' |
'google' |
Default imagery provider |
googleApiKey |
string |
- | Google Maps API key |
mapillaryAccessToken |
string |
- | Mapillary access token |
clickToView |
boolean |
true |
Enable click-to-view on map |
showMarker |
boolean |
true |
Show marker at view location |
maxSearchRadius |
number |
100 |
Max search radius for nearest imagery (meters) |
markerOptions |
MarkerOptions |
- | Customize marker appearance |
| Option | Type | Default | Description |
|---|---|---|---|
color |
string |
'#ff5722' |
Marker dot color |
showDirection |
boolean |
true |
Show direction indicator |
directionColor |
string |
'#1976d2' |
Direction arrow color |
| Event | Description |
|---|---|
expand |
Panel expanded |
collapse |
Panel collapsed |
statechange |
Any state change |
providerchange |
Provider switched |
locationchange |
View location changed |
headingchange |
View heading changed |
load |
Imagery loaded |
error |
Error occurred |
streetView.on('statechange', (event) => {
console.log('State:', event.state);
});
streetView.on('error', (event) => {
console.error('Error:', event.error);
});| Method | Description |
|---|---|
toggle() |
Toggle panel visibility |
expand() |
Expand the panel |
collapse() |
Collapse the panel |
setProvider(provider) |
Switch to a provider |
showStreetView(lngLat) |
Show street view at location |
clearStreetView() |
Clear current street view |
getState() |
Get current state |
State management hook for the street view control.
const {
state,
toggle,
expand,
collapse,
setProvider,
setLoading,
reset,
} = useStreetViewState({ collapsed: true });Provider configuration helper hook.
const {
availableProviders,
isProviderAvailable,
getDefaultProvider,
hasAnyProvider,
} = useStreetViewProvider({
google: { enabled: true, apiKey: 'key' },
mapillary: { enabled: true, accessToken: 'token' },
});# Install dependencies
npm install
# Start development server
npm run dev
# Run tests
npm test
# Build library
npm run build
# Build examples
npm run build:examplesCreate a .env file in the project root:
VITE_GOOGLE_MAPS_API_KEY=your_google_api_key
VITE_MAPILLARY_ACCESS_TOKEN=your_mapillary_tokenVisit the GitHub Pages demo to see the plugin in action.
MIT License - see LICENSE for details.
Contributions are welcome! Please open an issue or submit a pull request.