0

I'm building a JavaScript app with the ArcGis JavaScript SDK. We have a requirement that the app should run on prem without external dependencies. How can I use the SDK without it making calls to js.arcgis.com?

here is my package.json

{
  "engines": {
    "npm": ">=10.8.3 <=10.8.3",
    "node": ">=22.9.0 <=22.9.0"
},
  "name": "buildingmonitor",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
  "dev": "vite",
  "build": "tsc -b && vite build && npm run copyAssets",
  "lint": "eslint .",
  "preview": "vite preview --port 5173",
  "postinstall": "npm run copyAssets",
  "copyAssets": "shx mkdir -p ./public/assets && shx cp -r node_modules/@esri/calcite-components/dist/calcite/assets/* ./public/assets/",
  },
  "dependencies": {
    "@arcgis/map-components-react": "^4.31.6",
    "@esri/arcgis-rest-auth": "^3.7.0",
    "@esri/arcgis-rest-request": "^4.2.3",
    "@esri/calcite-components-react": "^2.13.2",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-router": "^7.0.2"
  },
  "devDependencies": {
    "@eslint/js": "^9.15.0",
    "@types/node": "^22.10.2",
    "@types/react": "^18.3.12",
    "@types/react-dom": "^18.3.1",
    "@types/react-modal": "^3.16.3",
    "@vitejs/plugin-react": "^4.3.4",
    "eslint": "^9.16.0",
    "eslint-plugin-react": "^7.37.2",
    "eslint-plugin-react-hooks": "^5.0.0",
    "eslint-plugin-react-refresh": "^0.4.14",
    "globals": "^15.12.0",
    "shx": "^0.3.4",
    "typescript": "~5.6.2",
    "typescript-eslint": "^8.15.0",
    "vite": "^6.0.0"
  }
}

When I look at my network tab I can see a lot of calls to js.argis.com, and I found that domain hard coded in arcgis node modules folders: node modules code search

When I inspect my app with dev tools, I see a lot of network calls to js.arcgis.com: network tab screenshot

Map Widget:

import "@arcgis/map-components/dist/components/arcgis-map";
import { ArcgisMap } from "@arcgis/map-components-react";
import { ArcgisMapCustomEvent } from "@arcgis/map-components/dist/types";

const MapWidget = () => {
  const handleMapReady = (event: ArcgisMapCustomEvent<void>) => {};

  return (
    <ArcgisMap
      onArcgisViewReadyChange={handleMapReady}
    />
  );
};

export default MapWidget;

2 Answers 2

0

When building from npm, and to use local assets there are two steps: (1) copying the assets and (2) configure the asset paths in your code/

It looks like you're only doing step 1. You need to also set the assets path.

The hardcoded paths you're seeing is just the default.

Refs:

2
  • 1
    I failed to include that set asset path in my snippet, but I am calling it during my app startup. Even with that, the node packages were making calls to js.arcgis.com. I'm planning on creating a paired down version of my app to share in this stack overflow. I'm not happy that I had to resort to the service worker url rewrite, but it is the only solution I found so far.
    – Danwize
    Commented Jan 20 at 20:01
  • If you're setting the asset path, there should be no requests to js.arcgis.com. Are you sure it's getting set correctly? Are any assets requests at all going to your own assets folder? Commented Jan 22 at 19:35
-2
  • Download the ArcGIS JavasScript library

  • unzip and copy the contents into your react app public folder

  • create a service-worker.js file:

    self.addEventListener('install', (event) => {
      const extendableEvent = event;
      extendableEvent.waitUntil(self.skipWaiting());
    });
    
    
    self.addEventListener('activate', (event) => {
      const extendableEvent = event;
      extendableEvent.waitUntil(self.clients.claim());
    });
    
    self.addEventListener('fetch', (event) => {
      console.log('Intercepting request:', event.request.url);
      try{
    
        const fetchEvent = event;
        const url = new URL(fetchEvent.request.url);
        if (url.href.startsWith('https://js.arcgis.com')) {
          console.log("rewriting url", url.href);
          const newUrl = url.href.replace('https://js.arcgis.com', `${self.location.protocol}//${self.location.hostname}:${self.location.port}/arcgis/javascript`);
          console.log("new url", newUrl);
          fetchEvent.respondWith(
            fetch(newUrl, {
              mode: 'cors', // Ensure CORS mode is set
              credentials: 'same-origin', // Include credentials if needed
              headers: {
                ...fetchEvent.request.headers,
                'Origin': self.location.origin // Set the Origin header
              }
            })
          );
        } else {
          fetchEvent.respondWith(fetch(fetchEvent.request));
        }
      } catch(err){
        console.error(err);
      }
    });
    
    
    
    
  • register the service worker before creating your app root

    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('/service-worker.js', {scope: `/`}) 
        .then((registration) => {
          console.log('Service Worker registered with scope:', registration.scope);
        })
        .catch((error) => {
          console.error('Service Worker registration failed:', error);
        });
    }
    
2
  • The user is asking for help when building locally. There's no need to download the "CDN" version locally in this case. Commented Dec 26, 2024 at 23:26
  • Esri tech support recommended that I download the CDN version to solve my issue with calls to js.arcgis.com. I was unable to get anything to work until I used this service worker solution.
    – Danwize
    Commented Jan 20 at 19:57

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.