Frontend map integrations often need an API key, but the hard part is not adding the key. It is deciding which key can safely live in the browser, where to store it during development and deployment, and what restrictions should exist around it. This guide gives you a reusable checklist for handling map API keys in frontend projects across React, Next.js, Vite, and similar setups. It focuses on secure patterns that hold up over time: separating public and secret values, using environment variables correctly by framework, adding provider-side restrictions, and knowing when a key belongs on your server instead of in client code.
Overview
If you only remember one rule, remember this: any value shipped to the browser should be treated as public. Environment variables in frontend builds help you manage configuration, but they do not make a browser-exposed key secret.
That point matters a lot for mapping products because providers often issue two kinds of credentials in practice:
- Public client keys or tokens meant to be used in JavaScript running in the browser, usually with domain or referrer restrictions.
- Secret server keys meant for geocoding, admin actions, bulk processing, or other privileged requests that should never be exposed in bundled frontend code.
A safe setup usually looks like this:
- Use a public, restricted key for loading maps, tiles, styles, or browser SDKs.
- Use a backend or serverless function for any sensitive API call.
- Store both values in environment variables, but expose only the public one to the client bundle.
- Rotate and audit keys as part of normal release hygiene.
This is especially useful when you are working through a mapping api tutorial, a google maps api example, or a mapbox tutorial, because sample code often stops at “paste your key here.” In production, the details around exposure, build tooling, and provider restrictions matter more than that one line of code.
Before choosing a pattern, answer these four questions:
- Is this key intended for browser use according to the provider?
- Can I restrict it by domain, referrer, app origin, or API scope?
- Does this request reveal anything sensitive or trigger costly billing operations?
- Would I be comfortable if any user could inspect this value in DevTools?
If the answer to the last two questions is no, do not keep the operation purely in the frontend.
Checklist by scenario
Use this section as a practical pre-launch checklist. Pick the scenario that matches your app and work through it before shipping.
Scenario 1: Public browser map key for tiles or SDK loading
This is the common case for interactive maps in the browser. You are loading a JavaScript SDK, map style, or tile layer that the provider expects to be called from a client app.
Checklist:
- Confirm the provider allows browser-side usage for this credential.
- Create a dedicated key for the frontend app instead of reusing a shared all-purpose key.
- Restrict the key by allowed domains, referrers, or origins where possible.
- Limit product or API scope if the provider supports granular permissions.
- Store the key in an environment variable that is explicitly marked for client exposure in your framework.
- Do not hardcode the key directly inside source files, examples, or component props.
- Add billing alerts or quota guardrails if your provider supports them.
Vite example:
// .env
VITE_MAPBOX_TOKEN=your_public_token
// app code
const token = import.meta.env.VITE_MAPBOX_TOKEN;In Vite, only variables with the right public prefix are exposed to client code. That makes vite env variables mapbox setups straightforward, but it does not make the token secret. The prefix is an exposure rule, not a security boundary.
Next.js example:
// .env.local
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY=your_public_key
// client component or browser code
const apiKey = process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY;For a typical nextjs google maps api key setup, the same rule applies: anything using the NEXT_PUBLIC_ prefix is bundled for the browser. Use it only for keys designed for public client usage.
Create React App and similar bundlers:
Older React setups and many bundlers use their own client-exposed naming rules. The principle stays the same: only expose the minimum required public key, and assume users can inspect it.
Scenario 2: Geocoding, reverse geocoding, or search that can create risk or cost
Geocoding often looks simple in demos, but it is a common place to move logic off the client. Requests may be rate-limited, billable, or sensitive depending on how your product works.
Checklist:
- Do not place secret provider keys in frontend code.
- Route requests through a backend endpoint or serverless function.
- Validate inputs server-side before forwarding them to the mapping provider.
- Add caching where appropriate for repeated lookups.
- Return only the data your UI needs rather than the full provider payload.
- Log errors and request volumes on the server to track abuse or unexpected cost.
This pattern is especially useful for a geocoding api example or reverse geocoding javascript workflow that may later grow in volume. It also gives you a place to normalize provider responses and swap services without rewriting the whole client app.
Safer pattern:
// client
await fetch('/api/geocode?query=Berlin');
// server
const providerKey = process.env.GEOCODING_API_SECRET;The frontend never sees the secret. The browser only calls your own endpoint.
Scenario 3: Next.js app using both server and client components
Next.js gives you more than one execution environment, which is powerful but easy to misuse if teams blur the line between server-only and browser-exposed variables.
Checklist:
- Keep sensitive map service credentials in server-only environment variables without a public prefix.
- Use public-prefixed variables only for browser-safe map SDK initialization.
- Do not pass secret values through props to client components.
- Keep route handlers, server actions, or API routes responsible for privileged map requests.
- Document which variable is public and why.
A good mental model: if a component renders in the browser and needs a value at runtime, that value is public by definition. If a request requires trust, perform it on the server.
Scenario 4: Vite, React, or static SPA deployed to a CDN
Static frontend deployments are common for dashboard and locator apps. They are fast and simple, but every exposed env value becomes part of the built output.
Checklist:
- Assume all client-exposed values are discoverable after build.
- Use separate environment files for local, staging, and production.
- Never commit real secrets to the repository, even in ignored examples copied into docs.
- Verify deployment platform settings match your local variable names.
- Rebuild the app after environment changes; static apps do not usually update variables at runtime.
This is where many teams get caught by a quiet build issue: they update a deployment variable but forget that the bundle was already generated with an older value. If your map suddenly fails after a deployment, compare the built variable name, the platform setting, and the final host domain restrictions. If the map is still blank, the checklist in Why Your Map Is Blank: A Debugging Checklist for JavaScript Mapping Apps is a useful follow-up.
Scenario 5: Leaflet with third-party tiles or plugins
A leaflet js tutorial often feels key-free at first, but real projects frequently add tile providers, geocoders, routing layers, or plugins that do require credentials.
Checklist:
- Identify which service actually needs the key: tiles, search, routing, analytics, or plugin-specific APIs.
- Read the provider’s intended usage pattern before assuming browser use is acceptable.
- Keep plugin configuration separate from secret operational credentials.
- Document provider terms, expected request volume, and fallback options.
If you are comparing approaches, Mapbox GL JS vs Leaflet in 2026: When to Use Each and How to Choose a Map Tile Provider for Performance, Cost, and Terms of Use provide good context for architectural decisions that affect key management.
Scenario 6: Multi-provider setups or live map products
Some apps combine mapping, weather, traffic, vehicle data, and geocoding from different vendors. In those setups, key sprawl becomes a bigger risk than any single leak.
Checklist:
- Use one variable per provider and per environment.
- Name variables by system and exposure level, such as
PUBLIC_MAP_STYLE_KEYandSERVER_GEOCODER_KEY. - Keep a small internal registry of where each key is used and who owns it.
- Review billing impact before exposing a client-callable endpoint that users can trigger frequently.
- Proxy high-risk or high-volume requests through your backend.
For apps with real-time updates, architecture choices can affect both costs and operational risk. See WebSocket vs Polling for Live Map Updates: Which Architecture Fits Your App? if your frontend is doing frequent provider calls.
What to double-check
Before launch, test the setup as if you were auditing someone else’s project. These are the checks most likely to catch a bad assumption.
- Variable prefix rules: In modern frontend tooling, a variable often needs a specific prefix to be exposed. If the prefix is wrong, the value may be undefined. If the prefix is public, the value is exposed by design.
- Build-time versus runtime behavior: Many frontend frameworks replace environment variables at build time. Changing the hosting environment later may do nothing until you rebuild and redeploy.
- Domain restrictions: If your map works on localhost but fails in production, verify the final deployed domain, subdomain, protocol, and any preview URLs allowed by the provider.
- API scope: A key may load a map but fail for geocoding or autocomplete if those services require separate enablement or permissions.
- Quota and billing: Public keys can still generate real usage. It is worth reviewing cost controls early. For provider-specific planning, see Mapbox Pricing Explained: MAUs, Requests, and How to Estimate Cost and Google Maps API Billing Explained: SKU Costs, Quotas, and Budget Controls.
- Logs and errors: A failed map request may look like a rendering issue when it is actually an auth error, blocked origin, or network policy problem. Check browser network logs, provider dashboards, and server logs if you proxy requests.
- CORS assumptions: Moving a request from server to client can introduce cross-origin issues even if the key is valid. If that happens, review CORS Errors with Mapping APIs: Common Causes and Fixes.
A practical review exercise is to search your built code and repository for provider names, token prefixes, and known key formats. That catches accidental hardcoding, copied test values, and stale examples left in config files.
Common mistakes
Most frontend key problems come from a few repeatable mistakes. Avoiding them is usually more valuable than learning another framework-specific trick.
- Treating frontend env vars as secrets. They are configuration helpers, not secret storage, once bundled for the browser.
- Using one key for everything. Separate keys by environment, app, and purpose so that restrictions and rotation are manageable.
- Skipping provider restrictions. If a browser-safe key can be locked to specific domains or APIs, do it.
- Sending sensitive requests directly from the client. Geocoding, batch jobs, account-level APIs, and expensive operations usually belong behind your own endpoint.
- Committing keys to the repository. Even temporary test keys tend to linger in history, screenshots, gists, and examples.
- Confusing local success with production readiness. Localhost allowances, preview environments, and alternate domains often behave differently from the final production host.
- Failing to document the reason a key is public. Future maintainers may see a visible token and assume the setup is unsafe, or worse, copy the pattern for a secret that should never be public.
A short internal comment can help a lot. For example: “This token is browser-exposed by design and restricted to approved domains for map rendering only.” That gives the next developer context without encouraging bad reuse.
When to revisit
This topic is worth revisiting whenever your workflow changes, not only when something breaks. A small release process change can quietly alter how keys are exposed, injected, or restricted.
Review your setup in these situations:
- Before seasonal planning cycles or major traffic periods.
- When migrating from one frontend toolchain to another, such as CRA to Vite or Vite to Next.js.
- When adding a new provider for maps, tiles, routing, search, or geocoding.
- When enabling preview deployments, branch deploys, or new subdomains.
- When costs rise unexpectedly and you need clearer separation between browser-safe and server-only requests.
- When a team member copies a demo into production code.
- When provider dashboards, key policies, or allowed referrer settings are updated.
A practical maintenance routine looks like this:
- List every map-related key in use.
- Label each one as public or server-only.
- Verify restrictions and allowed domains.
- Check where each value is injected: build time, runtime, server, or client.
- Rotate anything that was over-shared, committed, or reused too broadly.
- Update your project README with one clear paragraph on how map credentials are handled.
If you are actively comparing providers or planning a rebuild, it also helps to review broader implementation choices in Google Maps vs Mapbox vs Leaflet: Pricing, Features, and Best Use Cases and pricing-specific tradeoffs in Geocoding API Pricing Comparison: Google, Mapbox, HERE, and OpenCage.
The simplest durable rule is still the best one: public frontend keys should be intentionally public, tightly restricted, and limited to low-risk use cases. Everything else belongs behind your server. If you build around that distinction, your environment variable setup will stay understandable even as frameworks, providers, and deployment workflows change.