Embed the map
Add the maintained GPUQuant map to your site with JavaScript or an iframe, including exact colors, fixed or editable filters, independent popup controls and all configuration defaults.
Add the maintained GPUQuant infrastructure map to an article, dashboard or company site. Choose its view, filters, interactions and exact colors in a JavaScript object. Publishers need no GPUQuant account or API key.
Quick start#
Add a container, load the script, then call GPUQuant.embed(selectorOrElement, options). All options are optional. This example fills the container’s width with a 520-pixel-tall map.
<div id="map"></div>
<script src="https://gpuquant.com/embed/v1.js"></script>
<script>
GPUQuant.embed('#map', {
height: 520,
theme: 'dark'
});
</script>The call returns the created iframe. You can pass an element instead of a selector and mount several maps in separate containers. Load the script once; call it after each container exists. Calling it again for the same container replaces the iframe it previously created there. Missing containers and invalid selectors throw a TypeError.
Filters and interaction#
Filters choose which data appears. Their lock, their visible controls, point popups and hover are separate settings. A locked map can still open records; disabling popups does not disable hover. The default filters are locked and their controls are hidden.
GPUQuant.embed('#map', {
filters: {
gpus: ['h100', 'b200'],
providers: ['aws', 'gcp'],
siteTypes: ['datacenter'],
locked: true
},
controls: { filters: true },
interaction: { popups: true, hover: true }
});This displays the selected filters read-only while keeping popups and hover available. Use filters.locked: false with controls.filters: true to let readers change them. Use interaction.popups: false to stop clicks selecting sites or regions and opening their panels. Set interaction.hover: false separately to remove hover feedback.
filters.gpus and filters.providers affect published cloud-region prices. Selecting AWS does not restrict the facility layer to buildings operated by AWS. Use filters.siteTypes to choose facility types, or an empty array to hide that layer. An empty GPU or provider array hides region prices while leaving selected facility types available.
Omitted filter arrays include all supported values. An explicit [] includes none. Mixed valid and unknown identifiers keep the valid ones; an entirely invalid, nonempty array falls back to all supported values. Identifiers are case-sensitive.
All defaults#
Pass only the options you want to change. null for the initial center or zoom leaves framing automatic, using the selected destination when one is available. An empty colors object keeps the selected theme’s colors.
{
theme: 'dark',
view: {
projection: 'globe',
center: null,
zoom: null,
minZoom: 0,
maxZoom: 22
},
selection: null,
filters: {
gpus: ["h100","b200","h200","a100-80gb"],
providers: ["aws","azure","gcp","oracle"],
siteTypes: ["datacenter","fab","equipment","assembly","headquarters","office"],
priceRange: [0.6, 1.4],
locked: true
},
interaction: {
pan: true,
zoom: true,
rotate: false,
hover: true,
popups: true,
scrollZoom: false
},
controls: {
filters: false,
legend: true,
zoom: true,
fullscreen: true,
relationships: true
},
colors: {},
width: '100%',
height: 520,
borderRadius: 12,
borderColor: 'transparent',
title: 'GPUQuant infrastructure map'
}Option reference#
These options configure the map inside the frame. Unsupported options are ignored; invalid values use the validated defaults.
| Option | Values and meaning |
|---|---|
theme | dark or light, independent of the publisher’s page. |
view.projection | globe or mercator for a flat map. |
view.center | [longitude, latitude], in that order. Longitude is between −180 and 180; latitude between −90 and 90. |
view.zoom | Initial zoom, constrained by the configured zoom limits. |
view.minZoom, view.maxZoom | Allowed zoom interval, from 0 to 22. The minimum cannot exceed the maximum. |
selection | { kind, value } for an initial facility, place or region, or null for none. |
filters.gpus | h100, b200, h200, a100-80gb. |
filters.providers | aws, azure, gcp, oracle. |
filters.siteTypes | datacenter, fab, equipment, assembly, headquarters, office. |
filters.priceRange | [low, high] as ratios to the GPU’s reference price, within 0.6 to 1.4 and at least 0.01 apart. The end buckets include prices beyond the scale. |
filters.locked | Enforces the configured filters even when their controls are visible. |
interaction.pan | Allows the reader to move the map. |
interaction.zoom | Allows zooming. Disabling this also disables scroll and button zoom. |
interaction.rotate | Allows drag and touch rotation, independently of zoom. |
interaction.scrollZoom | Allows wheel or trackpad scroll to zoom when zooming is enabled. Off by default so the page remains easy to scroll. |
interaction.hover | Shows hover feedback independently of click popups. |
interaction.popups | Allows clicking a site or region to select it and open its panel. |
controls.filters | Shows the filter panel. Set filters.locked: false to make it editable. |
controls.legend | Shows the compact legend, or the price color scale when filters are visible. Hiding it keeps the price-range filters available. |
controls.zoom | Shows zoom controls when zoom interaction is enabled. |
controls.fullscreen | Shows the fullscreen control. The iframe and publisher must permit fullscreen. |
controls.relationships | Enables relationship lines for a selected facility and their controls. |
colors | Overrides the named colors listed below. |
Use the slug from a record’s URL for a facility or place; use provider/region-code for a region. For example, these are three separate selections:
{ selection: { kind: 'facility', value: 'asml-veldhoven' } }
{ selection: { kind: 'place', value: 'london' } }
{ selection: { kind: 'region', value: 'aws/eu-west-2' } }A named selection needs an available location or priced shape. An unavailable selection is explained in the map instead of being placed at guessed coordinates. Explicit view.center and view.zoom let you frame a particular area.
The loader also accepts these options for the iframe itself:
| Option | Default | Meaning |
|---|---|---|
width | '100%' | Iframe width. |
height | 520 | Iframe height. |
borderRadius | 12 | Rounded outer corners. |
borderColor | 'transparent' | Outer iframe border; accepts transparent or a hex color. |
title | GPUQuant infrastructure map | Accessible iframe title. Use a descriptive title when embedding a particular place. |
Numeric sizes are pixels. Size strings may use px, %, vh, vw or rem, such as '65vh'. Percentage height needs a parent with a defined height. Layout options are separate from the map’s colors.border and are set as iframe attributes or styles in the plain iframe form. Arbitrary CSS, HTML and external basemap URLs are not options.
Exact colors#
Each color accepts #RGB or #RRGGBB. For example, '#abc' is equivalent to '#aabbcc'. Use literal hex colors; CSS variables, color names, RGB functions and alpha hex values are not accepted. Unspecified colors retain the selected theme.
GPUQuant.embed('#map', {
theme: 'light',
colors: {
background: '#f4f1e8',
land: '#f4f1e8',
water: '#dae8ef',
panel: '#ffffff',
text: '#24303a',
accent: '#2255cc',
datacenter: '#7655bb',
priceLow: '#207a5b',
priceMid: '#c6a94e',
priceHigh: '#be4455'
}
});| Color key | Changes |
|---|---|
background | Map background outside the basemap. |
land | Land in the basemap. |
water | Water in the basemap. |
roads | Basemap roads. |
borders | Geographic boundaries in the basemap. |
labels | Basemap place labels. |
panel | Control and popup backgrounds. |
text | Primary control and popup text. |
mutedText | Secondary control and popup text. |
accent | Accent color for controls and links. |
border | Control and popup borders. |
datacenter | Datacenter marks. |
fab | Wafer-fab marks. |
equipment | Equipment-maker marks. |
assembly | Assembly and packaging marks. |
headquarters | Headquarters marks. |
office | Office and R&D marks. |
own | Lines to the selected operator’s other sites. |
sells | Lines to customers. |
buys | Lines to suppliers. |
stake | Ownership and investment lines. |
priceLow | Low end of the region-price color scale. |
priceMid | Middle of the region-price color scale. |
priceHigh | High end of the region-price color scale. |
The legend uses the same overridden colors as the map. Changing colors does not change price calculations or location precision. Choose colors that keep labels legible and the price scale distinguishable; the map methodology explains what each mark represents.
Plain iframe#
A CMS that allows iframes can use the hosted map without loading the JavaScript loader. Put map options in one config query parameter as URL-encoded JSON:
'https://gpuquant.com/embed/map?config=' +
encodeURIComponent(JSON.stringify({
theme: 'light',
filters: { siteTypes: ['datacenter'], locked: true }
}))This is the resulting copyable iframe, with the JSON already encoded:
<iframe
src="https://gpuquant.com/embed/map?config=%7B%22theme%22%3A%22light%22%2C%22filters%22%3A%7B%22siteTypes%22%3A%5B%22datacenter%22%5D%2C%22locked%22%3Atrue%7D%7D"
title="GPUQuant infrastructure map"
width="100%"
height="520"
loading="lazy"
allow="fullscreen"
style="border: 0; border-radius: 12px;"
></iframe>For all defaults, use https://gpuquant.com/embed/map as the source. Put theme, view, selection, filters, interaction, controls and colors inside the JSON object. Set width, height, border and title on the iframe itself. Do not append separate ?theme= or ?facility= parameters as configuration.
Updates and credit#
The embed uses the same maintained data as the full map, with an hourly refresh schedule. New data appears on the next frame load after it becomes available; an already-open frame does not continuously poll. The embed needs no publisher login, API key, cookies or storage, and your page’s CSS does not restyle the map inside the frame.
GPUQuant credit and source attribution remain available inside the map. Its GPUQuant, facility, company, place and region links are normal followed links that open a new tab. Open full map carries the current view and filters into the full map. Map interactions do not add entries to the publisher page’s browser history. No extra backlink is injected into your page or required beside the frame.
CMS and troubleshooting#
| Symptom | Check |
|---|---|
| The CMS removes the script. | Use its custom HTML or code block. If it permits only iframe markup, use the plain iframe example. |
The GPUQuant API is unavailable. | Load https://gpuquant.com/embed/v1.js before calling the API. With an asynchronous loader, call the API from its load handler. |
| The container cannot be found. | Match the selector to an existing element, use unique IDs for multiple maps, and call after the CMS or application has mounted that element. |
| The frame has no visible height. | Use a pixel height such as 520, or give its parent a defined height before using a percentage. Check for CMS styles hiding the iframe. |
| A content security policy blocks loading. | Allow https://gpuquant.com in the publisher’s frame-src. For the loader, also allow it in script-src. Put the initialization in your allowed script, or use your policy’s nonce or hash for the inline example. |
| A sandbox blocks interaction or new tabs. | If your CMS adds an iframe sandbox, it must permit scripts, the map’s normal origin, and popups. Use allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox for those capabilities. |
| Fullscreen does not work. | Keep allow="fullscreen" on the iframe and check the publisher’s Permissions Policy and any enclosing iframe restrictions. |
| Filters are visible but cannot change. | Set filters.locked: false to unlock them. Popup and hover permissions do not unlock filters. |
| There are no region prices. | Check empty GPU/provider arrays, the price range, and whether the selected region has a published priced shape. Facility types are filtered separately. |
| The map cannot draw or basemap tiles are missing. | Check WebGL support and whether the network blocks GPUQuant or the map’s CARTO requests. Use the frame’s full-map fallback when rendering fails. |
| Published data has not changed in an open frame. | Reload the frame after the next hourly update; open embeds do not poll continuously. |