Versions and SRI
Two path shapes are published, and they behave very differently.
| Path | Cache | Contents |
|---|---|---|
/v1/… | max-age=300 | Floating. Repointed at the newest release on every publish. |
/vX.Y.Z/… | max-age=31536000, immutable | Frozen. 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:
| File | Needed when |
|---|---|
loader.js | Always. |
sdk.js | You call DriveCars.init(). The loader does not inject this one. |
search.js, cart.js, checkout.js, payment.js, hello.js | Injected by the loader on sight of the matching tag. |
map.js | Pulled 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 -5The 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.