Build Output API (v3)Beta
The Build Output API is a file-system-based specification for a directory structure that can produce a Vercel deployment.
Framework authors can implement this directory structure as the output of their build command, so that the framework may utilize all of the Vercel platform features.
ENABLE_VC_BUILD
to be set to 1
in order to enable the feature.Overview
The Build Output API closely maps to the Vercel product features in a logical and easy-to-understand format.
It is primarily targeted toward authors of web frameworks who would like to utilize all of the Vercel platform features, such as Serverless Functions, Edge Functions, Routing, Caching, etc.
If you are a framework author looking to integrate with Vercel, you can use
this reference as a way to understand which files the framework should emit to the
.vercel/output
directory.
If you are not using a framework and would like to still take advantage of any of the features
that those frameworks provide, you can create the .vercel/output
directory and populate it
according to this specification yourself.
You can find complete examples of Build Output API directories in vercel/examples.
Known Limitations
Native Dependencies: Please keep in mind that when building locally, your build tools will compile native dependencies targeting your machine’s architecture. This will not necessarily match what runs in production on Vercel.
For projects that depend on native binaries, you should build on a host machine running Linux with a x64 CPU architecture, ideally the same as the platform Build Image.
Build Output Configuration
.vercel/output/config.json
Schema (as TypeScript):
type Config = {
version: 3;
routes?: Route[];
images?: ImagesConfig;
wildcard?: WildcardConfig;
overrides?: OverrideConfig;
cache?: string[];
};
Config Types:
The config.json
file contains configuration information and metadata for a Deployment.
The individual properties are described in greater detail in the sub-sections below.
At a minimum, a config.json
file with a "version"
property is required.
Supported Properties
version
.vercel/output/config.json
The version
property indicates which version of the Build Output API has been implemented.
The version described in this document is version 3
.
Example
"version": 3
routes
.vercel/output/config.json
The routes
property describes the routing rules that will be applied to the Deployment. It uses the same syntax as the routes
property of the vercel.json
file.
Routes may be used to point certain URL paths to others on your Deployment, attach response headers to paths, and various other routing-related use-cases.
type Route = Source | Handler;
Source Route
type Source = {
src: string;
dest?: string;
headers?: Record<string, string>;
methods?: string[];
continue?: boolean;
caseSensitive?: boolean;
check?: boolean;
status?: number;
has?: Array<HostHasField | HeaderHasField | CookieHasField | QueryHasField>;
missing?: Array<
HostHasField | HeaderHasField | CookieHasField | QueryHasField
>;
locale?: Locale;
middlewarePath?: string;
};
Key | Required | Description | |
---|---|---|---|
src | Yes | A PCRE-compatible regular expression that matches each incoming pathname (excluding querystring). | |
dest | No | A destination pathname or full URL, including querystring, with the ability to embed capture groups as $1, $2, or named capture value $name. | |
headers | No | A set of headers to apply for responses. | |
methods | No | A set of HTTP method types. If no method is provided, requests with any HTTP method will be a candidate for the route. | |
continue | No | A boolean to change matching behavior. If true, routing will continue even when the src is matched. | |
caseSensitive | No | Specifies whether or not the route src should match with case sensitivity. | |
check | No | If true , the route triggers handle: 'filesystem' and handle: 'rewrite' | |
status | No | A status code to respond with. Can be used in tandem with Location: header to implement redirects. | |
has | Array<HostHasField | HeaderHasField | CookieHasField | QueryHasField> | No | Conditions of the HTTP request that must exist to apply the route. |
missing | Array<HostHasField | HeaderHasField | CookieHasField | QueryHasField> | No | Conditions of the HTTP request that must NOT exist to match the route. |
locale | Locale | No | Conditions of the Locale of the requester that will redirect the browser to different routes. |
middlewarePath | No | A middleware name that matches an Edge Function path that should be invoked as middleware. |
Source Route: Locale
type Locale = {
redirect?: Record<string, string>;
cookie?: string;
};
Key | Required | Description | |
---|---|---|---|
redirect | Yes | An object of keys that represent locales to check for ( en , fr , etc.) that map to routes to redirect to (/ , /fr , etc.). | |
cookie | No | Cookie name that can override the Accept-Language header for determing the current locale. |
Source Route: HostHasField
type HostHasField = {
type: 'host';
value: string;
};
Key | Required | Description | |
---|---|---|---|
type | "host" | Yes | Determines the HasField type. |
value | Yes | Host name that must match the request URL's host to cause this route to match. |
Source Route: HeaderHasField
type HeaderHasField = {
type: 'header';
key: string;
value?: string;
};
Key | Required | Description | |
---|---|---|---|
type | "header" | Yes | Determines the HasField type. |
key | Yes | Header name that must exist on the request for this route to match. | |
value | No | Header value (or regex) that must match for this route to match. |
Source Route: CookieHasField
type CookieHasField = {
type: 'cookie';
key: string;
value?: string;
};
Key | Required | Description | |
---|---|---|---|
type | "cookie" | Yes | Determines the HasField type. |
key | Yes | Cookie name that must exist on the request for this route to match. | |
value | No | Cookie value (or regex) that must match for this route to match. |
Source Route: QueryHasField
type QueryHasField = {
type: 'query';
key: string;
value?: string;
};
Key | Required | Description | |
---|---|---|---|
type | "query" | Yes | Determines the HasField type. |
key | Yes | Querystring key to look for. | |
value | No | Querystring value (or regex) that must match for this route to match. |
Handler Route
The routing system has multiple phases. The handle
value indicates the start of a phase. All following routes are only checked in that phase.
type HandleValue =
| 'rewrite'
| 'filesystem' // check matches after the filesystem misses
| 'resource'
| 'miss' // check matches after every filesystem miss
| 'hit'
| 'error'; // check matches after error (500, 404, etc.)
type Handler = {
handle: HandleValue;
src?: string;
dest?: string;
status?: number;
};
Key | Required | Description | |
---|---|---|---|
handle | HandleValue | Yes | The phase of routing when all subsequent routes should apply. |
src | No | A PCRE-compatible regular expression that matches each incoming pathname (excluding querystring). | |
dest | No | A destination pathname or full URL, including querystring, with the ability to embed capture groups as $1, $2. | |
status | No | A status code to respond with. Can be used in tandem with Location: header to implement redirects. |
Example
The following example shows a routing rule that will cause the /redirect
path to perform an HTTP redirect to an external URL:
"routes": [
{
"src": "/redirect",
"status": 308,
"headers": { "Location": "https://example.com/" }
}
]
images
.vercel/output/config.json
The images
property describes the image optimization configuration when utilizing Vercel's native Image Optimization feature, which automatically adjusts the size and quality of your images, to make sure they are served to your visitors as quickly as possible.
type ImageFormat = 'image/avif' | 'image/webp';
type ImagesConfig = {
sizes: number[];
domains: string[];
minimumCacheTTL?: number; // seconds
formats?: ImageFormat[];
dangerouslyAllowSVG?: boolean;
contentSecurityPolicy?: string;
};
Key | Required | Description | |
---|---|---|---|
sizes | Yes | Supported image widths. | |
domains | Yes | Allowed external domains that can use Image Optimization. Leave empty for only allowing the deployment domain to use Image Optimization. | |
minimumCacheTTL | No | Cache duration (in seconds) for the optimized images. | |
formats | ImageFormat[] | No | Supported output image formats |
dangerouslyAllowSVG | No | Allow SVG input image URLs. This is disabled by default for security purposes. | |
contentSecurityPolicy | No | Change the Content Security Policy of the optimized images. |
Example
The following example shows an image optimization configuration that specifies allowed image size dimensions, external domains, caching lifetime and file formats:
"images": {
"sizes": [256, 384],
"domains": ["external-site.com"],
"minimumCacheTTL": 60,
"formats": ["image/webp", "image/avif"]
}
wildcard
.vercel/output/config.json
The wildcard
property relates to Vercel's Internationalization feature. The way
it works is the domain names listed in this array are mapped to the $wildcard
routing variable, which can be referenced by the routes
configuration.
Each of the domain names specified in the wildcard
configuration will need to
be assigned as Production Domains in the Project Settings.
type WildCard = {
domain: string;
value: string;
};
type WildcardConfig = Array<WildCard>;
Supported Properties
Objects contained within the wildcard
configuration support the following properties:
Key | Required | Description | |
---|---|---|---|
domain | Yes | The domain name to match for this wildcard configuration. | |
value | Yes | The value of the $wildcard match that will be available for routes to utilize. |
Example
The following example shows a wildcard configuration where the matching domain name will be served the localized version of the blog post HTML file:
"wildcard": [
{
"domain": "example.com",
"value": "en-US"
},
{
"domain": "example.nl",
"value": "nl-NL"
},
{
"domain": "example.fr",
"value": "fr"
}
],
"routes": [
{ "src": "/blog", "dest": "/blog.$wildcard.html" }
]
overrides
.vercel/output/config.json
The overrides
property allows for overriding the output of one or more static files contained
within the .vercel/output/static
directory.
The main use-cases are to override the Content-Type
header that will be served for a static file,
and/or to serve a static file in the Vercel Deployment from a different URL path than how it is stored on the file system.
type Override = {
path?: string;
contentType?: string;
};
type OverrideConfig = Record<string, Override>;
Supported Properties
Objects contained within the overrides
configuration support the following properties:
Key | Required | Description | |
---|---|---|---|
path | No | The URL path where the static file will be accessible from. | |
contentType | No | The value of the Content-Type HTTP response header that will be served with the static file. |
Example
The following example shows an override configuration where an HTML file can be accessed
without the .html
file extension:
"overrides": {
"blog.html": {
"path": "blog"
}
}
cache
.vercel/output/config.json
The cache
property is an array of file paths and/or glob patterns that should be re-populated
within the build sandbox upon subsequent Deployments.
Note that this property is only relevant when Vercel is building a Project from source code, meaning it is not relevant when building locally or when creating a Deployment from "prebuilt" build artifacts.
type Cache = string[];
Example
"cache": [
".cache/**",
"node_modules/**"
]
Full Example
{
"version": 3,
"routes": [
{
"src": "/redirect",
"status": 308,
"headers": { "Location": "https://example.com/" }
},
{
"src": "/blog",
"dest": "/blog.$wildcard.html"
}
],
"images": {
"sizes": [256, 384],
"domains": ["external-site.com"],
"minimumCacheTTL": 60,
"formats": ["image/webp", "image/avif"]
},
"wildcard": [
{
"domain": "example.com",
"value": "en-US"
},
{
"domain": "example.nl",
"value": "nl-NL"
},
{
"domain": "example.fr",
"value": "fr"
}
],
"overrides": {
"blog.html": {
"path": "blog"
}
},
"cache": [".cache/**", "node_modules/**"]
}
Vercel Primitives
The following directories, code files, and configuration files represent all Vercel platform primitives. These primitives are the "building blocks" that make up a Vercel Deployment.
Files outside of these directories are ignored and will not be served to visitors.
Static Files
.vercel/output/static
Static files that are publicly accessible from the Deployment URL should be placed in the .vercel/output/static
directory.
These files are served via the Vercel Edge Network.
Files placed within this directory will be made available at the root (/
) of the Deployment URL and neither their contents, nor their file name or extension will be modified in any way. Sub directories within static
are also retained in the URL, and are appended before the file name.
Configuration
There is no standalone configuration file that relates to static files.
However, certain properties of static files (such as the Content-Type
response header) can be modified by utilizing the overrides
property of the config.json
file.
File System Example
The following example shows static files placed into the .vercel/output/static
directory:
Serverless Functions
.vercel/output/functions
A Serverless Function is represented on the file system as
a directory with a .func
suffix on the name, contained within the .vercel/output/functions
directory.
All files inside of a given .func
directory are included inside the
Serverless Function execution environment. Private files may safely be placed within these directories
because they will not be directly accessible to end-users. However, they can be referenced by code
that will be executed by the Serverless Function.
Additionally, a configuration file named .vc-config.json
must be included within the .func
directory,
which contains information about how Vercel should construct the Serverless Function.
The .func
suffix on the directory name is not included as part of the URL path of Serverless Function on the Deployment.
For example, a directory located at .vercel/output/functions/api/posts.func
will be accessible at the URL path /api/posts
of the Deployment.
Configuration
.vercel/output/functions/<name>.func/.vc-config.json
The .vc-config.json
configuration file contains information related to how the Serverless Function will be created by Vercel.
Base Config
type ServerlessFunctionConfig = {
type: 'Lambda';
handler: string;
runtime: string;
memory?: number;
maxDuration?: number;
environment: Record<string, string>[];
allowQuery?: string[];
regions?: string[];
};
Key | Required | Description | |
---|---|---|---|
runtime | Yes | Specifies which "runtime" will be used to execute the Serverless Function. | |
handler | Yes | Indicates the initial file where code will be executed for the Serverless Function. | |
memory | No | Amount of memory (RAM in MB) that will be allocated to the Serverless Function. | |
maxDuration | No | Maximum execution duration (in seconds) that will be allowed for the Serverless Function. | |
environment | No | Map of additional environment variables that will be available to the Serverless Function, in addition to the env vars specifed in the Project Settings. | |
regions | No | List of Vercel Regions where the Serverless Function will be deployed to. |
Node.js Config
This extends the Base Config for Node.js Serverless Functions.
type NodejsServerlessFunctionConfig = ServerlessFunctionConfig & {
launcherType: 'Nodejs';
shouldAddHelpers?: boolean; // default: false
shouldAddSourceMapSupport?: boolean; // default: false
};
Key | Required | Description | |
---|---|---|---|
launcherType | "Nodejs" | Yes | Specifies which launcher to use. Currently only "Nodejs" is supported. |
shouldAddHelpers | No | Enables request and response helpers methods. | |
shouldAddSourcemapSupport | No | Enables source map generation. | |
awsLambdaHandler | No | AWS Handler Value for when the serverless function uses AWS Lambda syntax. |
Config Example
This is what the .vc-config.json
configuration file could look like in a real scenario:
{
"runtime": "nodejs16.x",
"handler": "serve.js",
"maxDuration": 3,
"launcherType": "Nodejs",
"shouldAddHelpers": true,
"shouldAddSourcemapSupport": true
}
File System Example
The following example shows a directory structure where the Serverless Function will be accessible at the /serverless
URL path of the Deployment:
Edge Functions
.vercel/output/functions
An Edge Function is represented on the file system as
a directory with a .func
suffix on the name, contained within the .vercel/output/functions
directory.
JavaScript source files placed within the .func
directory are bundled at build-time.
A WASM file may also be placed in this directory for an Edge Function to utilize.
Configuration
.vercel/output/functions/<name>.func/.vc-config.json
The .vc-config.json
configuration file contains information related to how the Edge Function will be created by Vercel.
type EdgeFunctionConfig = {
runtime: 'edge';
entrypoint: string;
envVarsInUse?: string[];
};
Key | Required | Description | |
---|---|---|---|
runtime | Yes | The runtime: "edge" property is required to indicate that this directory represents an Edge Function. | |
entrypoint | Yes | Indicates the initial file where code will be executed for the Edge Function. | |
envVarsInUse | No | List of environment variable names that will be available for the Edge Function to utilize. |
Config Example
This is what the .vc-config.json
configuration file could look like in a real scenario:
{
"runtime": "edge",
"entrypoint": "index.js",
"envVarsInUse": ["DATABASE_API_KEY"]
}
File System Example
The following example shows a directory structure where the Edge Function will be accessible at the /edge
URL path of the Deployment:
Prerender Functions
.vercel/output/functions
A Prerender asset is a Serverless Function that will be cached by the Vercel Edge Network in the same way as a static file. This concept is also known as Incremental Static Regeneration.
On the file system, a Prerender is represented in the same way as a Serverless Function, with an additional configuration file that describes the cache invalidation rules for the Prerender asset.
An optional "fallback" static file can also be specified, which will be served when there is no cached version available.
Configuration
.vercel/output/functions/<name>.prerender-config.json
The <name>.prerender-config.json
configuration file contains information related to how the Edge Function will be created by Vercel.
type PrerenderFunctionConfig = {
expiration: number | false;
group?: number;
bypassToken?: string;
fallback?: string;
allowQuery?: string[];
};
Key | Required | Description | |
---|---|---|---|
expiration | Yes | Expiration time (in seconds) before the cached asset will be re-generated by invoking the Serverless Function. Setting the value to false means it will never expire. | |
group | No | Option group number of the asset. Prerender assets with the same group number will all be re-validated at the same time. | |
bypassToken | No | Random token that can be provided in the URL to bypass the cached version of the asset. Useful for Preview Mode. | |
fallback | No | Name of the optional fallback file relative to the configuration file. | |
allowQuery | No | List of query string parameter names that will be cached independently. If an empty array, query values are not considered for caching. If undefined each unique query value is cached independently |
Fallback Static File
.vercel/output/functions/<name>.prerender-fallback.<ext>
A Prerender asset may also include a static "fallback" version that is generated at build-time. The fallback file will be served by Vercel while there is not yet a cached version that was generated during runtime.
When the fallback file is served, the Serverless Function will also be invoked "out-of-band" to re-generate a new version of the asset that will be cached and served for future HTTP requests.
Config Example
This is what an example.prerender-config.json
file could look like in a real scenario:
{
"expiration": 60,
"group": 1,
"bypassToken": "03326da8bea31b919fa3a31c85747ddc",
"fallback": "example.prerender-fallback.html",
"allowQuery": ["id"]
}
File System Example
The following example shows a directory structure where the Prerender will be accessible at the /blog
URL path of the Deployment:
Features
This section describes how to implement common Vercel platform features through the Build Output API through a combination of platform primitives, configuration and helper functions.
High-Level Routing
The vercel.json
file supports an easier-to-use syntax for routing through properties
like rewrites
, headers
, etc. However, the
config.json
"routes" property supports a
lower-level syntax.
The getTransformedRoutes()
function from the @vercel/routing-utils
npm package
can be used to convert this higher-level syntax into the lower-level format that is
supported by the Build Output API. For example:
import { writeFileSync } from 'fs';
import { getTransformedRoutes } from '@vercel/routing-utils';
const { routes } = getTransformedRoutes({
trailingSlash: false,
redirects: [
{ source: '/me', destination: '/profile.html' },
{ source: '/view-source', destination: 'https://github.com/vercel/vercel' },
],
});
const config = {
version: 3,
routes,
};
writeFileSync('.vercel/output/config.json', JSON.stringify(config));
cleanUrls
The cleanUrls: true
routing feature is a special case because, in addition to the routes
generated with the helper function above, it also requires that the static HTML files
have their .html
suffix removed.
This can be achieved by utilizing the "overrides"
property in the config.json
file:
import { writeFileSync } from 'fs';
import { getTransformedRoutes } from '@vercel/routing-utils';
const { routes } = getTransformedRoutes({
cleanUrls: true,
});
const config = {
version: 3,
routes,
overrides: {
'blog.html': {
path: 'blog',
},
},
};
writeFileSync('.vercel/output/config.json', JSON.stringify(config));
Edge Middleware
An Edge Function can act as a "middleware" of the HTTP request lifecycle for a Deployment. Middleware are useful for implementing functionality common to many endpoints in an Project, such as authentication or specialized routing logic, before "passing through" the request to complete the request lifecycle.
An Edge Middleware is represented on the file system as a standard Edge
Function, with an additional routing rule in
the routes
configuration that specifies
the URL path(s) where the edge function should be invoked.
Example
The following example shows adding a routing rule that specifies name of an
Edge Function as the middlewarePath
property. The edge function will be invoked
for any HTTP request under the /api
prefix, before continuing to serve the
underlying asset:
"routes": [
{
"src": "/api/(.*)",
"middlewarePath": "auth",
"continue": true
}
]
Preview Mode
When using Prerender Functions, you may want to implement "Preview Mode" which would allow you to bypass the caching aspect of prerender functions. For example, while writing draft blog posts before they are ready to be published.
To implement this, the bypassToken
of the <name>.prerender-config.json
file should be set to a randomized string that you generate at build-time. This string should not be exposed to users / the client-side, except under authenticated circumstances.
To enable "Preview Mode", a cookie with the name __prerender_bypass
needs to be set (i.e. by a Serverless Function) with the value of the bypassToken
. When the Prerender Function endpoint is accessed while the cookie is set, then "Preview Mode" will be activated, bypassing any caching that Vercel would normally provide when not in preview mode.