Google maps on ICP

Getting security error when I deploy my google maps application on ICP, when I run locally on mock-backend and windows env, it works. But when I dfx deploy and run on local replica I get security issues and the maps do not show, pleas help!

The error below:
Refused to load the script ‘https://maps.googleapis.com/maps/api/js?libraries=core&v=weekly&callback=google.maps.__ib__
because it violates the following Content Security Policy directive: “script-src ‘self’ ‘unsafe-eval’”.
Note that ‘script-src-elem’ was not explicitly set, so ‘script-src’ is used as a fallback.

What does the error say? I guarantee it’s not related to ICP

Hi!
I Updated my question with the error message

The error message explains that the CSP is not permissive enough. If you want an example on how to set a custom CSP, have a look here

1 Like

Here is my .ic-assets.json file:

[
{
“match”: “**/",
“headers”: {
“Content-Security-Policy”: "default-src ‘self’;script-src ‘self’ ‘unsafe-eval’ https://maps.googleapis.com https://www.paypal.com https://qnkfn-byaaa-aaaap-ahjbq-cai.raw.icp0.io; connect-src ‘self’ https://icp0.io https://
.icp0.io https://icp-api.io; img-src ‘self’ data:; style-src * ‘unsafe-inline’; style-src-elem * ‘unsafe-inline’; font-src *; object-src ‘none’; base-uri ‘self’; frame-ancestors ‘none’; form-action ‘self’; upgrade-insecure-requests;”,
“Permissions-Policy”: “accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), sync-script=(), trust-token-redemption=(), window-placement=(), vertical-scroll=()”,
“X-Frame-Options”: “DENY”,
“Referrer-Policy”: “same-origin”,
“Strict-Transport-Security”: “max-age=31536000; includeSubDomains”,
“X-Content-Type-Options”: “nosniff”,
“X-XSS-Protection”: “1; mode=block”
},
},
]

and here is my folder structure:
src
-declarations
-backend
-frontend
–assets
—.ic-assets.json
—…
–src
—index.html
—components
—…

For google.com, I tried also with wildcard
https://*.googleapis.com

I removed the entry from .ic-assets.json and added directly to index.html as below:

   <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-eval' https://maps.googleapis.com https://www.paypal.com https://fonts.gstatic.com https://qnkfn-byaaa-aaaap-ahjbq-cai.raw.icp0.io; script-src-elem 'self' 'unsafe-eval' https://maps.googleapis.com https://www.paypal.com https://fonts.gstatic.com https://qnkfn-byaaa-aaaap-ahjbq-cai.raw.icp0.io">

Same issue

Your configuration is not valid, each entry should be comma separated. Note that this is a standard web configuration and not something specific to the IC. You can also search for help with this problem on Stackoverflow or use AI tools such as ChatGPT if you need more help.

Updated my last answer, It is in the index.html file, and no need for comma

I know it is a standard web application, I can explain, how is my development environment i currently set.

Local test: Front-end react and .net core for simulating the backend on chain, so I can debug my backend logic and run locally faster both client and server.
Running with no issues

Dfx local: anvironment Same frontend with motoko backend,
CSP problems

ICP: main-net Same front end + motoko backend
CSP problems

The question, why I am having this issue only when I run on ICP?

Please provide a link to your canister running on mainnet

I can write parts of the code below:
index.html:

   <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-eval'   https://maps.googleapis.com https://www.paypal.com; script-src-elem 'self' 'unsafe-eval' 'nonce-abc123' https://maps.googleapis.com https://www.paypal.com;">
map.jsx
  useEffect(() => {
        // Load Google Maps API script
        const script = document.createElement('script');
        script.src = `https://maps.googleapis.com/maps/api/js?key=${GOOGLE_API_KEY}&libraries=places`;
        script.async = true;
        script.onload = () => setMapLoaded(true);
        document.head.appendChild(script);

        return () => {
            document.head.removeChild(script);
        };
    }, []);

The error:

index.js:2 Refused to load the script 'https://maps.googleapis.com/maps/api/js?key=HIDDEN_API_KEY&libraries=places' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval'". Note that 'script-src-elem' was not explicitly set, so 'script-src' is used as a fallback.

setting in .ic-assets.json

[
  {
    "match": "**/*",
    "headers": {
      "Permissions-Policy": "accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), sync-script=(), trust-token-redemption=(), window-placement=(), vertical-scroll=()",
      "X-Frame-Options": "DENY",
      "Referrer-Policy": "same-origin",
      "Strict-Transport-Security": "max-age=31536000; includeSubDomains",
      "X-Content-Type-Options": "nosniff",
      "X-XSS-Protection": "1; mode=block"
    }
  }
]

Did someone managed to have google maps on ICP? can one give me adress so I can check, I tested the code locally as a simple html page on my drive and it works, same code deployed on my local ICP replica (DFX deployed), same old error. I suspect it is impossible to implement google.maps on ICP. Here is my test code (from AI help):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Google Maps Test</title>
</head>
<body>
    <p>helllp</p>
    <div id="map" style="height: 400px; width: 100%;"></div>
    <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDhavq7uYe-a9hy0b3PU3oaMWiy09eUucY&callback=initMap" async defer></script>
    <script>
        function initMap() {
            new google.maps.Map(document.getElementById('map'), {
                center: {lat: -34.397, lng: 150.644},
                zoom: 8
            });
        }
    </script>
</body>
</html>

Problem is solved
Thanks everyone who tried to help!
The issue was that .ic-assets.json5 was not copied to the dist folder during dfx deploy, I missed things in the webpack.json file :rofl:

Now it works like a charm, I love ICP :heart_eyes:

My bad as usual :rofl: :rofl: :rofl:

1 Like