Skip to content
GigadriveDocs

Static assets

How the files your build produces are uploaded, addressed at the edge, and served without invoking a Function.

Everything your build writes into the assets directory is uploaded to object storage during the deployment and served by the edge. No invocation is involved, so a page of images and scripts costs nothing in compute.

What gets published

A framework project publishes its build output directory automatically. Without a framework, name the directory yourself:

version: 4
assets: public

The directory is walked recursively and every regular file inside it becomes an asset, addressed at its path with the directory prefix removed. public/css/app.css is served at /css/app.css.

Unchanged files do not upload again. A deployment that changes one file transfers one file, so redeploying an application with a large asset directory stays fast.

Some files are never published, whichever way the directory was chosen:

  • Anything that is also a Function entrypoint, or whose path is used verbatim as a route source. A public/index.php that your functions block declares stays a Function.
  • node_modules/ and vendor/.
  • package.json, package-lock.json, pnpm-lock.yaml, .gitignore, .git/ and .github/.
  • The gigadrive.yaml file itself.
  • Files ending in .htaccess or .htpasswd.
  • Anything matching a pattern in the Function's excludeFiles.

Symbolic links are rejected rather than followed, and a path that resolves outside the project directory fails the build with a clear error. Assets covers the configuration keys.

Immutable prefixes

A content-hashed build directory can hold tens of thousands of files, and registering each one individually makes the deployment record enormous for no benefit. Frameworks that produce such a directory register it as a single prefix instead: the whole .next/static tree becomes one entry serving /_next/static/, and the edge derives the object key from the part of the request path that follows the prefix.

Prefix lookup is case-sensitive, unlike the route table, because it maps directly onto object keys. A remainder containing ., .., a backslash or a null byte is rejected before any storage read.

Files under a hashed prefix are the ones that benefit most from long cache lifetimes, which is why the per-deployment hostname serves them with a one-year immutable lifetime. See Caching for the full header matrix.

Serving semantics

BehaviourWhat the edge does
MethodsGET, HEAD and OPTIONS. Anything else returns 405 with an Allow header.
Range requestsaccept-ranges: bytes is always set. A single range returns 206, a malformed one 416.
If-None-MatchReturns 304. It takes precedence over If-Modified-Since.
If-MatchReturns 412 when the entity tag does not match, as does a failed If-Unmodified-Since.
Unknown pathReturns 404 with cache-control: no-store.
Missing content typeFalls back to application/octet-stream.

Directory requests

A request path that nothing else answers is retried as a directory before the edge gives up. /about and /about/ both resolve to a published about/index.html or about/index.htm, the way a static host serves a directory, and / resolves the same way at the root.

This runs only once every route your configuration declares has already missed, so a catch-all Function route still answers every path it matches, and publishing public/ unchanged alongside a server Function keeps serving those files at their own paths. A directory with no published index file returns 404 instead of falling back to a page from elsewhere in the site.

Assets from a replaced deployment

Promoting a new deployment does not delete the old one's objects, and that matters more than it sounds. An HTML document already sitting in a browser tab or a CDN cache still points at the previous build's hashed filenames, and those filenames do not exist in the new deployment's index.

So when a request for a hashed asset misses, the edge looks for it in recently replaced deployments of the same environment before returning 404. Eligibility is narrow on purpose: GET and HEAD only, and the path either sits under _next/static/ or has a content-hash-shaped filename ending in .js, .mjs, .css, .map, .woff, .woff2, .json or .wasm. Up to three prior deployments are consulted.

Nothing in your application has to opt in. A rollback is covered the same way, since the deployment it moves away from is one of the candidates.

Warming

After a promotion, the platform requests a sample of the deployment's fully prerendered pages so the first real visitor does not pay for a cold CDN. Only pages that were rendered at build time are warmed, because warming must never invoke a Function.

Warming traffic is identifiable in Request logs by its user agent, Gigadrive-CacheWarmer/1.0.