Navigated to /docs/core/configuration

Application configuration

Understand what belongs in tavo.config.ts, what belongs in vite.config.ts, and how to extend either file without discarding existing behavior.

Start from the generated configuration

Use Node.js 20.19+ or 22.12+ and run commands from the project root. A generated project already contains both configuration files. Edit those files in place instead of replacing them with an example from another project.

FileRead byResponsibility
tavo.config.tsTavo.jsRoutes, CSS entries, plugins, diagnostics, build policy, and SSR behavior.
vite.config.tsVite through Tavo.jsVite server, resolve, dependency, and bundler settings while preserving Tavo.js's TSX and build plugins.
tsconfig.jsonTypeScriptTypechecking and Tavo.js's automatic TSX runtime configuration.

Configure framework behavior in tavo.config.ts

defineConfig preserves literal types and catches unsupported top-level fields. Paths are relative to the project root. Keep every existing plugin and CSS entry when adding another integration. Tavo.js has one framework configuration file at the project root; imported and computed values are evaluated consistently by development, build, inspection, and production.

TS
tsimport { defineConfig } from "@tavojs/core/config";
import { tavoUi } from "@tavojs/ui/plugin";

export default defineConfig({
  pagesDir: "src/pages",
  cssEntries: ["src/styles.css"],
  diagnostics: {
    devOverlay: true,
    traces: false
  },
  build: {
    prerenderStyles: "inline",
    budgets: {
      firstLoadJs: "150kb",
      routeJs: "40kb"
    }
  },
  ssr: {
    trustedHosts: ["example.com"],
    canonicalOrigin: "https://example.com"
  },
  plugins: [tavoUi()]
});

Top-level TavoConfig reference

These are all accepted top-level TavoConfig properties in tavo.config.ts. defineConfig rejects any other top-level key at typecheck time. Every property is optional, but the file and its default defineConfig export are required.

TS
tsimport { defineConfig } from "@tavojs/core/config";

export default defineConfig({
  pagesDir: "src/pages",
  cssEntries: ["src/styles/app.scss"],
  diagnostics: {
    devOverlay: true,
    traces: false
  },
  ssr: {
    canonicalOrigin: "https://example.com"
  }
});
PropertyAccepted valueDefaultWhat it changes
pagesDirstringsrc/pagesSets the project-root-relative directory scanned for pages, layouts, route groups, and special route modules.
cssEntriesstring[]Existing files among src/styles.css, src/styles.scss, src/app.css, and src/app.scssSets project-root-relative global CSS or Sass entries loaded by development, client build, and SSR.
pluginsPluginUse[] | { use: PluginUse[]; overrides?: PluginOverride[] }No app pluginsInstalls Plugin API v1 integrations. Use the array form for normal installs and the object form only when public overrides are needed.
diagnostics{ devOverlay?: boolean; traces?: boolean }Omitted; generated apps set { devOverlay: true, traces: false }Sets development error-overlay and framework trace preferences.
build{ prerenderStyles?: "inline" | "external"; budgets?: {} }{ prerenderStyles: "inline", budgets: {} }Controls prerendered CSS delivery and JavaScript budget enforcement.
ssrTavo.js SSR optionsRuntime defaults shown belowConfigures page-runtime behavior, Node requests, response caching, the HTML document, and image optimization.

Diagnostics and build properties

PropertyAccepted valueDefaultWhat it changes
diagnostics.devOverlaybooleanGenerated apps: trueEnables or disables the development error-overlay preference.
diagnostics.tracesbooleanGenerated apps: falseEnables or disables detailed framework diagnostic traces.
build.prerenderStyles"inline" | "external"inlineInlines collected route styles into prerendered HTML or writes references to external build assets.
build.budgets.firstLoadJsnumber | byte-size stringNo limitFails the production build when JavaScript needed for a route's first load exceeds this number of bytes.
build.budgets.routeJsnumber | byte-size stringNo limitFails the production build when JavaScript attributed to one route exceeds this number of bytes.

Budget strings accept bytes or the case-insensitive units b, kb, kib, mb, and mib; decimal strings such as 1.5mb are valid. Numeric values are bytes. CLI flags override the file for one build.

BASH
bashnpx tavo build --max-first-load-js 150kb --max-route-js 40kb
npx tavo build --prerender-styles external

SSR and page-runtime properties

The ssr object accepts the following properties. The CLI supplies discovered route modules and compiles top-level plugins, so most applications configure only origin security, rendering, caches, or images here.

PropertyAccepted valueDefaultWhat it changes
ssr.canonicalOriginabsolute HTTP(S) origin stringOrigin derived from the request Host over HTTPSets the public origin behind TLS termination. Credentials, paths, queries, and fragments are rejected; its host is also trusted for actions.
ssr.trustedHostsstring[]Localhost variants, plus canonicalOrigin when configuredAllows Host values used to validate Node action and plugin mutation requests. Entries may include a hostname or host with port.
ssr.allowExternalRedirectsbooleanfalseAllows route and middleware redirects to absolute HTTP(S) URLs. Relative same-origin paths remain allowed without it.
ssr.streambooleanfalseStreams the SSR response instead of buffering the completed document.
ssr.maxRequestBodyBytesnumber10 MiBLimits buffered non-GET request bodies in the Node handler. Requests above the limit receive 413.
ssr.maxResolvedCacheEntriesfinite non-negative number1,024Limits the process-local route-resolution data cache. Values are floored; 0 disables reuse.
ssr.staticCacheSsrStaticCacheProcess-local memory cache with 1,024 entriesStores rendered responses for static and revalidated routes. Supply an adapter for shared or durable caching.
ssr.documentRenderDocumentOptionsDocument defaults shown belowSets the shared HTML shell, attributes, serialized initial state, CSP nonce, and style registry.
ssr.imagesImageOptimizerOptionsOptimizer defaults shown belowConfigures /_tavo/image, local and remote sources, transform limits, formats, and memory caching.
ssr.getPageProps() => Record<string, unknown>No extra propsAdds application-owned props to page components on each runtime render.
ssr.notFoundComponent<{ pathname: string }>Discovered src/pages/404 moduleOverrides the application-wide not-found component supplied by file routing.
ssr.csrFallbackChild | ({ pathname, params }) => ChildnullRenders fallback content when a CSR route is resolved by the browser before its route module is ready.
ssr.csrActionsCsrActionsOptionsDisabledMaps browser form submissions for static CSR delivery to an action backend. Nested properties are listed below.
ssr.middlewarePageMiddleware[][]Runs application-wide middleware around every route in addition to discovered layout and page middleware.
ssr.i18nI18nServiceRegistered default i18n service, otherwise noneSupplies locale detection, localized path resolution, and locale state to the pages runtime.
ssr.instrumentation{ emit(event: TavoInstrumentationEvent): void }NoneReceives route resolve, middleware, loader, action, and cache lifecycle events. Listener failures do not interrupt framework work.
ssr.modulesPageModulesGenerated route-module mapOverrides file-discovered modules. This is an advanced manual-runtime hook; normal applications leave it unset.

CSR action properties

Configure ssr.csrActions when a statically hosted CSR application should submit Tavo.js forms to a separate action server. resolveUrl takes precedence over baseUrl.

PropertyAccepted valueDefaultWhat it changes
ssr.csrActions.enabledbooleanfalseIntercepts eligible non-GET forms and enables action URL mapping.
ssr.csrActions.baseUrlstringCurrent origin and route pathResolves the route pathname and query against a separate action-server base URL.
ssr.csrActions.resolveUrl({ pathname, search, form? }) => stringUses baseUrl, then the route pathComputes the complete action request URL for each route or form.
ssr.csrActions.credentialsRequestCredentialsincludeSets the Fetch credentials mode used for intercepted form submissions.
ssr.csrActions.headersHeadersInit | ({ pathname, form }) => HeadersInitNo additional headersAdds fixed or per-form request headers to the action fetch.
TS
tsimport { defineConfig } from "@tavojs/core/config";

export default defineConfig({
  ssr: {
    csrActions: {
      enabled: true,
      baseUrl: "https://actions.example.com",
      credentials: "include",
      headers: ({ pathname }) => ({
        "X-Tavo.js-Route": pathname
      })
    }
  }
});

HTML document properties

ssr.document sets defaults for the server-rendered document shell. Route head exports and Tavo.js SEO components can refine metadata per route.

PropertyAccepted valueDefaultWhat it changes
ssr.document.langstringenSets the escaped html lang attribute.
ssr.document.titlestringNo titleSets the escaped fallback document title. Route SEO metadata takes precedence.
ssr.document.unsafeHeadHtmlstringEmptyAppends trusted raw HTML to head. It is not escaped; prefer TSX metadata for all structured head content.
ssr.document.htmlAttributesRecord<string, string | number | boolean>{}Adds escaped safe-name attributes to html. false omits an attribute and true renders a boolean attribute.
ssr.document.bodyAttributesRecord<string, string | number | boolean>{}Adds escaped attributes to body.
ssr.document.appAttributesRecord<string, string | number | boolean>{}Adds escaped attributes to the application container.
ssr.document.doctypestring<!doctype html>Sets the exact doctype prefix written before the html element.
ssr.document.appContainerIdstringappSets the escaped id of the application container used by hydration.
ssr.document.initialStateunknownOmittedSerializes JSON into a protected application/json script after the app container.
ssr.document.stateScriptIdstring__TAVO_STATE__Sets the escaped id of the serialized initial-state script.
ssr.document.noncestringNoneAdds a CSP nonce to generated state and style elements.
ssr.document.beforeRender() => voidNoneRuns immediately before server rendering. Use only for request-safe setup.
ssr.document.styleRegistryStyleRegistryA new registry for each renderSupplies a custom style collector with add, has, and entries methods.

Image optimizer properties

PropertyAccepted valueDefaultWhat it changes
ssr.images.enabledbooleantrueEnables the /_tavo/image optimization endpoint.
ssr.images.allowRemotebooleanfalseAllows remote HTTP(S) image sources, still subject to remotePatterns and network safety checks.
ssr.images.remotePatternsArray<string | { protocol?, hostname, port?, pathname? }>[]Allowlists remote origins or host/path patterns. A hostname beginning with *. matches subdomains only.
ssr.images.publicDirstringpublicSets the project-root-relative source directory for local images.
ssr.images.qualitynumber75Sets fallback output quality; request values are clamped from 1 through 100.
ssr.images.cacheMaxAgenumber31,536,000 secondsSets the Cache-Control max-age of transformed image responses.
ssr.images.defaultFormat"webp" | "avif" | "jpeg" | "png" | "original"webpSets the output format when the optimization URL does not request one.
ssr.images.sizesnumber[][320, 640, 960, 1280, 1600]Sets the candidate widths and supplies the fallback width for an optimization request.
ssr.images.timeoutMsnumber5,000Limits remote fetch duration.
ssr.images.maxBytesnumber10 MiBRejects local or remote source images larger than this byte limit.
ssr.images.memoryCacheMaxEntriesnumber128Limits transformed images stored in process memory. Values are floored; 0 disables storage.
ssr.images.maxConcurrentTransformsnumber4Limits simultaneous Sharp transforms; values are floored with a minimum of 1.
ssr.images.maxPendingTransformsnumber64Limits queued transforms before the optimizer returns a busy error.
ssr.images.allowInsecureRemotebooleanfalseAllows HTTP remote image URLs. Keep disabled unless the transport risk is explicitly accepted.
ssr.images.resolveHostname(hostname: string) => Promise<Array<{ address: string }>>Node DNS lookupOverrides DNS resolution used by private-network protection. Intended for adapters and controlled tests.
TS
tsimport { defineConfig } from "@tavojs/core/config";

export default defineConfig({
  ssr: {
    images: {
      allowRemote: true,
      remotePatterns: [
        {
          protocol: "https:",
          hostname: "images.example.com",
          pathname: "/products"
        }
      ],
      defaultFormat: "avif",
      quality: 80
    }
  }
});

Server image transforms require the optional sharp dependency in the application that runs SSR. Remote requests are checked against the allowlist, redirects, DNS results, private-network addresses, timeout, and byte limit.

SsrStaticCache adapter

Use the public SsrStaticCache interface from @tavojs/core/server when rendered static and revalidated responses must be shared across processes or persisted outside Node memory. Methods may return values directly or through promises.

TS
tsimport type {
  SsrStaticCache,
  SsrStaticCacheEntry
} from "@tavojs/core/server";

const entries = new Map<string, SsrStaticCacheEntry>();

export const staticCache: SsrStaticCache = {
  get(key) {
    return entries.get(key) ?? null;
  },

  set(key, entry) {
    entries.set(key, entry);
  },

  delete(key) {
    entries.delete(key);
  },

  invalidateTags(tags) {
    const requested = new Set(tags);
    let deleted = 0;

    for (const [key, entry] of entries) {
      if (entry.tags.some((tag) => requested.has(tag))) {
        entries.delete(key);
        deleted += 1;
      }
    }

    return deleted;
  },

  clear() {
    entries.clear();
  }
};

SsrStaticCacheEntry contains the rendered response, an absolute expiresAt timestamp or null, and its cache tags. The built-in createMemoryStaticCache is available from @tavojs/core/server. The Map above illustrates the contract; use a shared cache implementation for multi-process production deployments.

Configuration loading behavior

TS
tsimport { loadTavoConfig } from "@tavojs/core/dev";

const config = await loadTavoConfig(process.cwd(), {
  mode: "development"
});

console.log(config.pagesDir);
ConcernContract
LocationExactly one tavo.config.ts at the project root.
ExportA default export returned by defineConfig({ … }). A plain object is rejected.
EvaluationImported and computed values are supported. The file is evaluated once per project root and process.
Environment.env files are loaded before evaluation. The explicit mode wins, then NODE_ENV, then production.
Mode safetyOne project root cannot be reevaluated in a different mode in the same process.
FailureA failed load is not cached, so the next command or retry can load a corrected file.

Keep Tavo.js's Vite wrapper

defineTavoViteConfig installs Tavo.js's TSX transform, file-route build guards, SVG support, localization splitting, and plugin build contributions. Pass your Vite settings into the wrapper rather than replacing it with Vite's defineConfig.

TS
tsimport { defineTavoViteConfig } from "@tavojs/core/config";

export default defineTavoViteConfig(({ mode }) => ({
  server: {
    port: mode === "development" ? 4174 : undefined
  },
  build: {
    sourcemap: mode !== "production"
  }
}));

Verify the result

BASH
bashnpx tavo info
npx tavo check
npm run build

info shows the resolved pages and CSS configuration, check reports route and project-shape problems, and the production build exercises both client and server configuration. If a plugin was added, run npx tavo inspect plugins as well.

Look up exact public types

Follow linked API names to their canonical TypeScript declarations and package boundaries.