Web SDKVersions and SRI

Versions and SRI

Two path shapes are published, and they behave very differently.

PathCacheContents
/v1/…max-age=300Floating. Repointed at the newest release on every publish.
/vX.Y.Z/…max-age=31536000, immutableFrozen. Written once, never overwritten. Identical bytes forever.

/vX.Y.Z/ being write-once is enforced, not a convention: a publish that would overwrite an existing version prefix fails and uploads nothing at all.

If you do not need SRI, stay on /v1/. You get fixes automatically, and that is the right default for most partners.

Never take an SRI hash from /v1/

This is the single most common way to break an SDK integration, and it fails in the worst possible way — silently, some days after you shipped, on a deploy you did not make.

/v1/manifest.json describes whatever /v1/ points at right now. The next time we publish, the bytes change, your hash stops matching, and the browser refuses to execute the script. The widget vanishes from your page with only a console error, on a day when nothing on your side changed.

The /v1/ manifest carries a warning field saying exactly this, because a partner who reaches for a manifest is precisely the one about to paste an integrity attribute.

Pinning properly

Pin an immutable version, and take the hash from that version’s manifest:

curl -s https://sdk.drivecars.ai/v0.1.0/manifest.json
{
  "version": "0.1.0",
  "generated": "2026-09-09T10:00:00Z",
  "files": {
    "loader.js":   { "integrity": "sha384-<base64>" },
    "search.js":   { "integrity": "sha384-<base64>" },
    "sdk.js":      { "integrity": "sha384-<base64>" }
  }
}

The integrity values are already in the exact form the attribute takes. Copy them verbatim:

<script
  src="https://sdk.drivecars.ai/v0.1.0/loader.js"
  integrity="sha384-<the loader.js value>"
  crossorigin="anonymous"></script>

crossorigin="anonymous" is required for SRI to work at all on a cross-origin script. The CDN serves permissive CORS headers, so this works as written.

A manifest without a warning field is a pinned one. If the manifest you are reading has that field, you are on /v1/ and must not use its hashes.

Two consequences of pinning

The lazily-injected bundles are not covered. loader.js injects search.js and its siblings itself, and does not attach integrity to those tags. Pinning loader.js pins the loader; the element bundles it pulls from the same /vX.Y.Z/ directory are immutable, but the browser does not hash-verify them.

If you need every bundle verified, add your own <script integrity=…> tags for the specific element bundles you use, before the loader runs. Be aware of what that actually buys you: the loader tracks only its own injections, so it will still inject its own unverified copy of the same bundle. Each element registers itself only once — the second copy is a no-op rather than a crash — but the browser does fetch and execute both. You get a verified copy that wins the race, at the cost of a duplicate request.

Pinning loader.js alone is the pragmatic choice for most partners who want SRI at all.

You stop getting updates, including fixes. Pinning is a deliberate trade, with no auto-upgrade off an immutable path. Re-pin to a newer version on your own schedule, and treat it as a routine maintenance item rather than something you do once and forget.

Which files exist

The manifest lists every .js file in the release. In practice you will reference:

FileNeeded when
loader.jsAlways.
sdk.jsYou call DriveCars.init(). The loader does not inject this one.
search.js, cart.js, checkout.js, payment.js, hello.jsInjected by the loader on sight of the matching tag.
map.jsPulled in by search.js for the results map.

Only add explicit tags for the bundles your page actually uses. The point of the lazy loader is that a search-only page never downloads checkout.

Checking what is live

curl -s https://sdk.drivecars.ai/v1/manifest.json | head -5

The version field tells you what /v1/ currently points at. That is the manifest’s legitimate use — reading the current version — as distinct from pinning, which it must never be used for.