D3 v7 ES Module Transition: Why Local Scripts Fail in Production
0 reputation · 30 Sept 2022, 22:38 UTC
0 reputation · 30 Sept 2022, 22:38 UTC
We want to load external JSON data with d3.json in a D3 v7 application that is bundled as ES modules and served from a subpath in production. The same code works fine on a local dev server.
d3 object is no longer available unless a UMD build is explicitly loaded.fetch API. In production the origin differs, and the server may not include the necessary Access-Control-Allow-Origin header./app instead of the site root, relative paths break unless adjusted.d3 namespace.d3.json requests to succeed when the application is deployed under a subpath?d3 object for legacy code that still expects it?33275 reputation · 01 Oct 2022, 01:08 UTC
Local development servers typically serve files from the root (/), whereas production deployments often use subpaths (/app/). Because d3.json uses the native Fetch API, relative paths are resolved against the current browser URL. If your app is at example.com/app/index.html, a request for data.json targets example.com/app/data.json instead of the root, leading to 404 errors.
import * as d3 from 'd3' does not create a window.d3 object.d3.json is a wrapper for fetch(). It is subject to the Same-Origin Policy and requires Access-Control-Allow-Origin headers if the data resides on a different domain.Avoid hard-coded relative strings. Use a base URL variable provided by your bundler (e.g., process.env.PUBLIC_URL in React/Webpack) to prefix your data paths:
const dataPath = `${process.env.PUBLIC_URL}/data/dataset.json`;
d3.json(dataPath).then(data => { ... });
If the JSON is hosted on a separate server, ensure that server returns the following header. Do not use * in production; specify your actual domain:
Access-Control-Allow-Origin: https://your-production-domain.com
d3 for Legacy CodeIf you have non-module scripts that expect a global d3 object, explicitly assign it in your main entry point (e.g., index.js):
import * as d3 from 'd3';
window.d3 = d3;
// Now legacy scripts can access d3.select()
To isolate the failure, check the browser Network Tab:
Missing Diagnostic: Are the JSON files hosted on the same origin as the HTML, or a separate CDN/API server?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.