@setu-ts/static-plugin — files and single-page applications
Add it: setu add static adds it and prints StaticPlugin({ root }); put that registration in
setu.config.ts. It provides CAPABILITIES.STATIC_FILES (IStaticFiles).
Serve built assets beside API routes
import { StaticPlugin } from '@setu-ts/static-plugin';
export const assets = StaticPlugin({
root: './public',
urlPrefix: '/assets',
cacheControl: 'public, max-age=3600',
});
Serve a single-page application
Use this instead of the asset-only registration when the client owns root routing:
import { StaticPlugin } from '@setu-ts/static-plugin';
export const frontend = StaticPlugin({
root: './build/client',
fallback: 'index.html',
cacheControl: (path) => path.endsWith('.html') ? 'no-cache' : 'public, max-age=3600',
});
Behaviour the types do not show
urlPrefixdefaults to/,indextoindex.html; an emptyindexdisables index lookup.- The plugin mounts both GET and HEAD. A root wildcard cannot share its method and path with an SSR catch-all; mount assets at their own prefix.
fallbackis used only for a missing path whose Accept header includestext/html.- The
cacheControlcallback receives the full request path, includingurlPrefix. etag,rangesandcompresseddefault totrue; compression negotiates.br/.gzsidecars.maxBufferBytesdefaults to 1048576 bytes; larger files stream when the filesystem supports it. Without a filesystem, no routes are mounted and the health indicator reports up withdata.fs: false.
Other options
- Omit
cacheControlfor immutable caching of content-hashed names and revalidation otherwise. rootselects the filesystem directory;urlPrefixselects the public mount.createStaticHandlerbuilds a handler separately;StaticFilesServiceoffers the service directly.