assetPrefix

Points the /_next/ JavaScript and CSS URLs at a CDN origin instead of the app server.

Signature
assetPrefix?: string

Parameters

ParameterTypeDescription
$assetPrefixoptionalstring= '' (empty string)An origin, optionally with a path, prepended to URLs Next.js emits for files under /_next/ (the contents of .next/static). Set it to undefined during development so the dev server keeps serving its own assets.

Changelog

  • PHP v9.5.0basePath added, and is now the recommended option for sub-path hosting rather than assetPrefix.

With assetPrefix: 'https://cdn.mydomain.com', a chunk request that would have gone to /_next/static/chunks/…js is emitted as https://cdn.mydomain.com/_next/static/chunks/…js. Your server keeps rendering HTML; the CDN carries the bundle traffic.

When to reach for it

  • Self-hosting where the app server should not serve bundle bytes.
  • Putting build output on a CDN close to users in another region.
  • Splitting asset delivery from a rate-limited or metered origin.

What trips people up

Only .next/static belongs on the CDN, uploaded so it is reachable at _next/static. Do not upload the rest of .next/ — it contains server code and configuration. The prefix does not cover public/, so those files still come from your origin unless you prefix them yourself. Wrap the value in a phase check: applying a CDN origin during next dev points the browser at chunks that do not exist yet. And if what you actually want is to host the app at example.com/docs, this is the wrong key — use basePath, which handles routing too.

Example

Example · typescript
import { PHASE_DEVELOPMENT_SERVER } from 'next/constants'
import type { NextConfig } from 'next'

export default (phase: string): NextConfig => ({
  assetPrefix:
    phase === PHASE_DEVELOPMENT_SERVER
      ? undefined
      : 'https://cdn.mydomain.com',
})

When to use it

  • Serve build chunks from CloudFront while the Node server only renders HTML
  • Push .next/static to object storage as part of a self-hosted deploy pipeline
  • Keep asset URLs on a cookieless domain

Frequently asked questions

Which files do I upload to the CDN?

Only the contents of .next/static, published so they are served from _next/static. The rest of .next contains server code and build manifests and must not be exposed publicly.

Why are my public/ files still served from the app server?

assetPrefix only rewrites URLs under /_next/. Files in the public folder are referenced by the paths you write, so if you want them on the CDN you have to add the prefix to those URLs yourself.

Can I use assetPrefix to host the app under /docs?

No — use basePath. assetPrefix does not change routing, only the origin of /_next/ assets. The docs explicitly recommend basePath for sub-path hosting.

More examples

Deploy step that publishes the assets

The path mapping matters: files from .next/static must answer at _next/static under the CDN origin, because that is the URL shape Next.js emits. The immutable Cache-Control is safe here because every filename contains a content hash — the same reason Next.js refuses to let you change that header through the headers() config.

Example · bash
# build first
next build

# upload ONLY .next/static, published at _next/static on the CDN origin
aws s3 sync .next/static s3://my-bucket/_next/static \
  --cache-control "public, max-age=31536000, immutable"

# the rest of .next stays on the server
node .next/standalone/server.js

Assets on a CDN, app on a sub-path

The two options answer different questions. basePath changes where routes and links resolve; assetPrefix changes only the host that serves /_next/ files. They compose, but assetPrefix alone will not make the app reachable at /docs, and files in public/ are unaffected by either — those you reference with the basePath written in by hand.

Example · typescript
import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  // routing: the app lives at example.com/docs
  basePath: '/docs',

  // delivery: bundles come from the CDN
  assetPrefix: 'https://cdn.mydomain.com',
}

export default nextConfig

Discussion

  • Be the first to comment on this lesson.