Static Assets

How to serve static assets

Encore.ts has built-in support for serving static assets (such as images, HTML and CSS files, and JavaScript files).

This is particularly useful when you want to serve a static website or a single-page application (SPA) that has been pre-compiled into static files.

Related example
Example of how to use api.static in to serve static files.
$ encore app create --example=ts/static-files

API Reference

Serving static files in Encore.ts works similarly to regular API endpoints, but using the api.static function instead.

import { api } from "encore.dev/api"; export const assets = api.static( { expose: true, path: "/frontend/*path", dir: "./assets" }, );

This will serve all files in the ./assets directory under the /frontend path prefix.

Encore automatically serves index.html files at the root of a directory. In the case above, that means that requesting the URL /frontend will serve the file ./assets/index.html, and /frontend/hello will serve the file ./assets/hello or ./assets/hello/index.html (whichever exists).

Serving static files at the root

By default, Encore requires that API endpoint paths don't conflict with other API endpoints. This can cause problems when you want to serve static files at the root of your domain (such as by setting path: "/*path"), since that would conflict with all other paths.

To support this use case, Encore allows defining a route as a "fallback route", that gets called only when no other API endpoint matches.

Fallback routes use the syntax !path instead of *path.

It looks like this:

import { api } from "encore.dev/api"; export const assets = api.static( { expose: true, path: "/!path", dir: "./assets" }, );

Configuring the 404 response

When a file matching the request isn't found, Encore automatically serves a 404 Not Found response.

You can customize the response by setting the notFound option to specify a file that should be served instead:

import { api } from "encore.dev/api"; export const assets = api.static( { expose: true, path: "/!path", dir: "./assets", notFound: "./not_found.html" }, );

Performance

When defining static files, the files are served directly from the Encore.ts Rust Runtime. This means that zero JavaScript code is executed to serve the files, freeing up the Node.js runtime to focus on executing business logic.

This dramatically speeds up both the static file serving, as well as improving the latency of your API endpoints.