For the complete documentation index, see llms.txt. This page is also available as Markdown.

Bundle requirements and limits

What a valid hosted app bundle looks like, the limits CARTO enforces, and the headers and CSP it serves

Private Preview: Hosted Apps is available to selected accounts during its Private Preview. To request access, contact your CARTO representative.

A hosted app is a directory of built static files. CARTO serves them as they were uploaded, under the rules on this page.

Bundle rules

Rule
Detail

A directory

You pass a directory to carto app deploy, not an archive.

index.html at the root

Required. Otherwise the deploy fails with Bundle directory must contain index.html at the root. Point the command at your build output, not at the project root.

Subdirectories

Preserved. Each file is served at its path in the bundle.

carto.json

At the root, it is the manifest: read when you deploy and never uploaded. In a subdirectory, it is an ordinary file.

Symbolic links

Skipped. Anything a link points to must be a real file inside the directory to be deployed.

Relative asset paths

The app is served under /app/<slug>/, not at the root of a domain, so asset URLs must be relative. In Vite, set base: './'. An absolute path like /assets/app.js returns 404.

Whole files

Files are always served whole. HTTP range requests are not supported.

Client-side routing

Client-side routing works, with one rule:

  • A page request to a path without a file extension and without a trailing / that does not match any file returns index.html, so your router can handle it. /app/my-app/dashboard/2026 loads the app, but /app/my-app/dashboard/ returns 404.

  • A path with a file extension that does not match any file returns 404. /app/my-app/assets/missing.js is an error, never HTML.

Limits

Limit
Value

Total bundle size

50 MB

File size

25 MB

Files per bundle

1000

Slug

1 to 40 characters matching /^[a-z0-9](?:[a-z0-9-]{0,38}[a-z0-9])?$/: lowercase letters, digits and hyphens, not starting or ending with a hyphen

Version label

1 to 64 characters matching /^(?!.*\.\.)[a-zA-Z0-9.:_-]{1,64}$/: letters, digits, ., :, _ and -, with no ..

App name

1 to 200 characters

App description

Up to 2000 characters

Connections per manifest

20

Named Sources per connection

200

SQL per Named Source

100,000 characters

These limits are checked before any file is uploaded, so a bundle over a limit fails without uploading anything. If a bundle is too large, the usual causes are source maps and unoptimized images: disable source maps for the deployed build, and compress images.

Response headers

CARTO sets these headers on every file it serves from a bundle. A bundle cannot change them.

Header
Value
Consequence

Cache-Control

no-store

Nothing is cached by the browser or by intermediate caches. A redeploy takes effect on the next page load, and every load downloads the bundle again, so keep it small.

Vary

Origin, Cookie, Authorization

Responses are tied to the user's session.

X-Frame-Options

SAMEORIGIN

The app cannot be embedded in an iframe on another site.

Content-Security-Policy

See below

The app can only load resources from, and connect to, the allowed origins.

Content-Type

Based on the file extension

Files with an unknown extension are served as application/octet-stream.

The Content Security Policy

CARTO serves this policy with every file of a bundle:

Directive
Allowed sources

script-src

The bundle, inline scripts and eval, unpkg.com, cdn.jsdelivr.net and *.cartocdn.com.

style-src

The bundle, inline styles, unpkg.com, cdn.jsdelivr.net, *.cartocdn.com and fonts.googleapis.com.

connect-src

The bundle, *.carto.com, *.cartodb.com, *.cartocdn.com, *.googleapis.com, unpkg.com and cdn.jsdelivr.net.

img-src

The bundle, data: and blob: URIs, *.cartocdn.com, *.googleapis.com and *.gstatic.com.

font-src

The bundle, data: URIs, *.cartocdn.com and fonts.gstatic.com.

worker-src

The bundle and blob: URIs.

In practice:

  • Libraries load from the bundle, or from unpkg.com and cdn.jsdelivr.net. Including them in the bundle is the most reliable option.

  • Basemaps must come from an allowed origin, such as the CARTO basemaps (BASEMAP in @deck.gl/carto), served from *.cartocdn.com.

  • Images, fonts and other files from other hosts are blocked. Include them in the bundle, or use data: URIs.

  • APIs other than CARTO and the allowed origins cannot be called from the app.

  • Embedding the app in another site is not possible, because of X-Frame-Options: SAMEORIGIN.

No environment variables or secrets

A hosted app has no environment variables and no secrets. Its configuration comes from two places:

  • carto-info.json, for the user's access token, the API base URL and the user's identity. See Runtime and authentication.

  • The bundle, for anything else, set at build time.

Anyone who can open the app can read its files. Keep SQL in Named Sources, and never include a credential in the bundle.

Last updated

Was this helpful?