This document provides recommendations for how to configure the website
Content Security Policy (CSP) for the Maps JavaScript API. Since
a wide variety of browser types and versions are used by end users, developers
are encouraged to use this example as a reference, fine-tuning until no further
CSP violations occur.

> [!NOTE]
> **Note:** Your CSP must allow the `googleapis.com` domains that the Maps JavaScript API uses in directives such as `img-src` and `connect-src`, as shown in the [example](https://developers.google.com/maps/documentation/javascript/content-security-policy.md.txt#example). If you use a [strict CSP](https://developers.google.com/maps/documentation/javascript/content-security-policy.md.txt#strict-csp), you don't need to add `googleapis.com` or other Google domains to `script-src`.

[Learn more about Content Security Policy](https://web.dev/articles/strict-csp).

## Strict CSP

To help protect your website from cross-site scripting (XSS) attacks, we
recommend using a [strict CSP](https://web.dev/articles/strict-csp) instead of
an allowlist CSP. Maps JavaScript API supports the use of
nonce-based strict CSP. Websites must populate both `script` and `style`
elements with a nonce value. Internally, Maps JavaScript API will
find the first such element, and apply its nonce value to style or script
elements inserted by the API script respectively.

The `'strict-dynamic'` keyword in the following example lets a script that has
a valid nonce load other scripts. Because your page loads the
Maps JavaScript API with a nonce, the API can load the additional
scripts that it needs, so you don't need to list any Google domains in
`script-src`. Browsers that support `'strict-dynamic'` ignore the `https:`
source in the example; it's only a fallback for older browsers.

## Example

The following example shows a sample CSP, along with an HTML page where it is
embedded:

### Sample Content Security Policy

```javascript
script-src 'nonce-{script value}' 'strict-dynamic' https: 'unsafe-eval' blob:;
img-src 'self' https://*.googleapis.com https://*.gstatic.com *.google.com *.googleusercontent.com data:;
frame-src *.google.com;
connect-src 'self' https://*.googleapis.com *.google.com https://*.gstatic.com data: blob:;
font-src https://fonts.gstatic.com;
style-src 'nonce-{style value}' https://fonts.googleapis.com;
worker-src blob:;
```

### Sample HTML page

```html
<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="style.css" nonce="{style value}">
    <style nonce="{style value}">...</style>
    ...
  </head>
  <body>
    <div id="map"></div>
    <script src="https://maps.googleapis.com/maps/api/js?key=&callback=initMap" async nonce="{script value}"></script>
    <script nonce="{script value}"> function initMap() { ... } </script>
  </body>
</html>
```

## Allowlist CSP

> [!CAUTION]
> **Caution:** The following allowlist CSP doesn't protect your website from cross-site scripting (XSS) attacks. Its script-src directive includes 'unsafe-inline', which lets injected inline scripts run. It also includes wildcard Google domains such as https://\*.googleapis.com, which cover hosts that serve user-uploaded content, such as Cloud Storage (storage.googleapis.com). To help protect your website from XSS, use a strict CSP instead.

If you have set up allowlist CSP, please consult the [list of Google Maps Domains](https://developers.google.com/maps/gmp-domains).
We recommend consulting this document and the Maps JavaScript API
[release notes](https://developers.google.com/maps/documentation/javascript/releases.md.txt) to stay up to date,
and include any new service domain into the allowlist if needed.

Websites which load the Maps JavaScript API from a legacy
Google APIs domain (for example `maps.google.com`) or a region-specific domain
(for example `maps.google.fr`), must also include these domain names in their
CSP `script-src` setting, as shown in the following example:

```javascript
script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.googleapis.com https://*.gstatic.com *.google.com https://*.ggpht.com *.googleusercontent.com blob:;
img-src 'self' https://*.googleapis.com https://*.gstatic.com *.google.com  *.googleusercontent.com data:;
frame-src *.google.com;
connect-src 'self' https://*.googleapis.com *.google.com https://*.gstatic.com  data: blob:;
font-src https://fonts.gstatic.com;
style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
worker-src blob:;
```