Amplify Toolbox
    Preparing search index...

    Type Alias DeployManifest

    Framework-agnostic deployment manifest.

    Produced by framework adapters (Next.js/OpenNext, SvelteKit, Astro). Consumed by the L3 HostingConstruct.

    The L3 NEVER knows which framework produced this manifest.

    type DeployManifest = {
        assetPrefix?: string;
        basePath?: string;
        buildId?: string;
        cache?: CacheConfig;
        compute: Record<string, ComputeResource>;
        errorPages?: Partial<Record<404 | 500, string>>;
        headers?: CustomHeader[];
        imageOptimization?: ImageConfig;
        invalidationPaths?: string[];
        lifecycle?: { days: number; prefix: string }[];
        middleware?: MiddlewareConfig;
        redirects?: Redirect[];
        rewrites?: Rewrite[];
        routes: RouteBehavior[];
        staticAssets: {
            cacheControl?: string;
            directory: string;
            immutablePaths?: string[];
            noCachePaths?: string[];
            spaFallback?: boolean;
        };
        version: 1;
    }
    Index

    Properties

    assetPrefix?: string

    Optional URL prefix that the framework prepends to its built static asset URLs (Next.js assetPrefix, Nuxt's app.buildAssetsDir). When set, the L3 adds CloudFront behaviors at /<prefix>/_next/* (or framework-specific pattern) so chunks/CSS/images load correctly.

    Format: leading slash, no trailing slash. Examples: /shop-static, /cdn, /foo/bar. Set to undefined (or omit) when the framework uses the default same-origin asset URLs.

    basePath?: string

    Optional URL prefix that prefixes every routable URL on the deployed site. Maps to Next.js basePath, Astro base, Nuxt app.baseURL. When set, every CloudFront behavior pattern is prefixed and the bare domain root issues a 308 redirect to /<basePath>/.

    Format: leading slash, no trailing slash. Examples: /app, /docs. Use assetPrefix for asset-only prefixing; basePath covers SSR routes too.

    buildId?: string

    Build ID for atomic deployments.

    cache?: CacheConfig

    Cache infrastructure (provisioned if present)

    compute: Record<string, ComputeResource>

    Named compute resources

    errorPages?: Partial<Record<404 | 500, string>>

    Static error pages emitted by the build (e.g. Next.js output: 'export' writes 404.html from app/not-found.tsx).

    When set, the L3 wires CloudFront CustomErrorResponses to serve the named file at the original status code (404 → /404.html with status 404), instead of the SPA fallback that maps every error to /index.html with status 200. Typical entries:

    { 404: '/404.html' } { 404: '/404.html', 500: '/500.html' }

    Static-only deploys without this field continue to use the SPA fallback (suitable for client-routed React apps).

    headers?: CustomHeader[]

    Custom response headers

    imageOptimization?: ImageConfig

    Image optimization (separate Lambda if present)

    invalidationPaths?: string[]

    OVERRIDE for the CloudFront invalidation paths issued on every deploy, AFTER the atomic KVS cutover. Most adapters leave this UNSET and let the L3 pick the default (see below); set it only to customize the paths or to opt out ([]).

    Why an invalidation is needed at all — the stale-HTML→403 problem:

    Atomic deploys write every object under a brand-new immutable builds/<buildId>/ prefix, so there is nothing stale to invalidate, and HTML served from S3 carries no-cache (the 3-tier Cache-Control split in hosting_construct). So a PURE-STATIC deploy (no compute) needs no invalidation — Astro/Nuxt static pages prerender to S3 and propagate on the next request.

    But ANY compute-backed deploy can edge-cache HTML that goes stale. The shared SSR cache policy honors the origin's Cache-Control, so HTML served by the compute origin with a long s-maxage is edge-cached keyed on the VIEWER path (/about), NOT the build-id prefix. After a redeploy that HTML still references the previous build's hashed assets (_next/static/*, _nuxt/*, _astro/*), and the router rewrites those asset requests to the CURRENT build prefix — which no longer contains them → 403. This is NOT Next-specific:

    • Next/OpenNext: SSG/ISR HTML from the SSR Lambda → s-maxage=31536000.
    • Nuxt/Nitro: routeRules cache.maxAge / swr / isr emit s-maxage=N on compute-origin HTML (see nitro adapter).
    • Astro SSR: pages that set Cache-Control on the response. The common trigger is "a compute origin serving cacheable HTML that references build-prefixed hashed assets" — so the L3 scopes the invalidation on hasCompute, not on the framework.

    Default (when this field is unset): the L3 issues ['/*'] for any deploy with a compute origin, and nothing for pure-static deploys. The invalidation is gated after the KvKeys cutover, so it only flushes the previous build's cached pages — the new build's builds/<id>/... objects were never cached, making /* effectively free. A compute app that emits only no-store HTML still gets the invalidation, but it is a harmless no-op. Set [] to opt out; set explicit patterns to narrow it.

    lifecycle?: { days: number; prefix: string }[]

    Adapter-supplied S3 lifecycle rules for orphaned per-build data that lives outside the build prefix.

    The default DeleteOldBuilds lifecycle on builds/<id>/ covers everything under the build prefix. Some frameworks emit data outside the build prefix that survives across builds and needs its own expiration:

    • Next.js writes _next/data/<buildId>/... JSON files used by getStaticProps fallbacks; older entries linger if the user toggles output: modes.
    • Custom adapters may emit similar per-build asset trees.

    Each entry installs an S3 lifecycle rule expiring objects under prefix after days. Adapter code knows where its framework writes these files; the L3 just installs whatever the adapter declares. Empty / undefined → no extra rules.

    Type Declaration

    • days: number

      Days after object creation before expiration.

    • prefix: string

      S3 key prefix to expire — e.g. _next/data/.

    middleware?: MiddlewareConfig

    Middleware (edge function if present)

    redirects?: Redirect[]

    Redirects

    rewrites?: Rewrite[]

    Rewrites

    routes: RouteBehavior[]

    Route behaviors (maps URL patterns to compute/static)

    staticAssets: {
        cacheControl?: string;
        directory: string;
        immutablePaths?: string[];
        noCachePaths?: string[];
        spaFallback?: boolean;
    }

    Static asset configuration

    Type Declaration

    • OptionalcacheControl?: string

      Cache-Control header for non-hashed assets (HTML, public/, etc.). Defaults to public, max-age=0, must-revalidate so a redeploy invalidates cached HTML on next request — required to avoid PWA "brick" scenarios where a cached index.html references hashed URLs that the new deploy already removed.

    • directory: string

      Path to static files directory

    • OptionalimmutablePaths?: string[]

      Glob patterns (relative to directory) of content-hashed asset directories. Files matching these globs receive a long-lived, immutable Cache-Control; everything else uses the short-lived cache above. Adapters set this to the framework's hashed-output dir(s):

      Next.js / OpenNext: ['_next/static/*'] Astro: ['_astro/*'] Nuxt / Nitro: ['_nuxt/*']

      When omitted, all assets receive the single cacheControl value above (back-compat with adapters that don't yet declare hashed paths).

    • OptionalnoCachePaths?: string[]

      Glob patterns (relative to directory) of files that must never be cached. These receive Cache-Control: no-cache, no-store, must-revalidate. Use for runtime config files (e.g. .blocks-sandbox/config.json) that change between deploys and must never serve stale content even briefly.

    • OptionalspaFallback?: boolean

      Whether this static deploy is a single-page app (SPA) that relies on client-side routing, versus a multi-page site where each route is its own prerendered HTML file.

      Controls how the CloudFront viewer-request function resolves extensionless URLs:

      • true (SPA): every navigation request (no file extension) is rewritten to /index.html so the client-side router can handle deep links. Missing paths serve index.html at HTTP 200. Correct for Vite/React-Router/Vue-Router single-page apps.
      • false (multi-page): each request resolves to its own <path>/index.html (directory-index resolution). A request for /about serves about/index.html, NOT the home page. Correct for static-site generators (Astro static, Hugo, Eleventy) that prerender every route to a separate HTML file.

      Set by the adapter, which is the only layer that knows the framework's routing model (the L3 is framework-blind). When omitted, the L3 falls back to a heuristic: SPA mode when the deploy has no compute AND no errorPages (preserved for back-compat with adapters that don't yet declare this). Ignored when the manifest has compute resources (SSR), since routing then flows through the compute origin rather than static index resolution.

    version: 1