Error: MapboxGL: Access token not found when initializing map in production
0 reputation · 08 Jan 2025, 07:16 UTC
0 reputation · 08 Jan 2025, 07:16 UTC
Goal: Ensure that a Mapbox GL JS map initializes successfully in a production build without depending on the automatic token injection provided by a local development server.
Constraints: The access token must be assigned to mapboxgl.accessToken before any map instance is created, yet some build tools may strip or replace process.env variables, leaving the token undefined in the final bundle. It is unclear whether the token should be baked into the bundle at build time, supplied via a runtime configuration endpoint, or handled through another secure mechanism, and how to confirm its presence without executing the map code.
What to do: The most common, production‑ready pattern is to inject the token at build time using a bundler plugin (Webpack DefinePlugin, Vite import.meta.env, or similar). The token is replaced with a literal string in the final bundle, and you protect it by adding the production domain to the token’s URL whitelist in the Mapbox dashboard. If you prefer not to bake the token into the bundle, fetch it from a protected backend endpoint that returns a signed JSON Web Token (JWT) or a simple string, then assign it to mapboxgl.accessToken before any new mapboxgl.Map() call.
mapboxgl.accessToken is defined synchronously, so the map constructor never throws.VITE_MAPBOX_TOKEN=pk.abc123 to .env.production.import { defineConfig } from 'vite';
// In your main JS file
mapboxgl.accessToken = import.meta.env.VITE_MAPBOX_TOKEN;
import.meta.env.VITE_MAPBOX_TOKEN with the literal value. Vite does this automatically; Webpack users add a DefinePlugin entry: new webpack.DefinePlugin({
'process.env.MAPBOX_TOKEN': JSON.stringify(process.env.MAPBOX_TOKEN)
});
bundle.js and search for the token string. It should appear exactly as it was set in the environment variable.https://example.com) to the token’s URL whitelist. This ensures that even if someone views the bundle, the token will only work from the authorized domain.async function initMap() {
const resp = await fetch('/config/mapbox-token', { credentials: 'include' });
const { token } = await resp.json();
mapboxgl.accessToken = token;
new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v11' });
}
initMap();
console.log(token) before the map constructor call.console.log(mapboxgl.accessToken) before any map code runs. It should output the token string.Sources panel and search for the token string.Do you currently see the token string in your built bundle, or is process.env.MAPBOX_TOKEN being replaced with undefined? That detail will determine whether you need to adjust your bundler configuration or switch to a runtime fetch approach.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.