Frontend Configuration

Table of Contents

Minimal Config

export default {
  frontend: true,
};

Use false to disable frontend completely:

export default {
  frontend: false,
};

Complete Example

export default {
  frontend: {
    enabled: true,
    framework: "react",
    root: "src/frontend",
    publicDir: "public",
    publicPath: "/",
    styles: {
      jscss: { enabled: true },
    },
    dev: {
      hot: true,
      fastRefresh: true,
      renderRefresh: "prompt",
    },
    build: {
      target: "es2022",
      minify: true,
      sourcemap: false,
      client: {
        external: [],
        externalRuntime: {},
      },
      vendorChunks: {
        enabled: true,
        packages: ["react", "react-dom", "react-dom/client"],
      },
      assets: {
        inlineLimit: 0,
      },
      css: {
        modules: true,
      },
      budgets: {
        maxInitialJsBrotliBytes: 60_000,
        maxRouteInitialJsBrotliBytes: 80_000,
        maxAppOwnedInitialJsBrotliBytes: 40_000,
      },
      diagnostics: {
        leakScan: true,
        performanceReport: true,
      },
    },
    deploy: {
      assetBaseUrl: "https://cdn.example.com/my-app/",
      crossOrigin: "anonymous",
      integrity: true,
      upload: {
        enabled: true,
        adapter: "filesystem",
        targetDir: ".vext/frontend-cdn",
        publicBaseUrl: "https://cdn.example.com/my-app/",
        prefix: "my-app",
        stateFile: ".vext/deploy/frontend-assets-state.json",
        exclude: ["**/*.map"],
      },
    },
    i18n: {
      enabled: true,
      defaultLocale: "en-US",
      clientLoad: "current",
    },
    spaFallback: {
      scopes: [],
    },
    apiClient: true,
  },
};

Core Fields

FieldDefaultMeaning
frontend.enabledfalseEnable built-in frontend pipeline
frontend.framework"react"Framework label for built-in React support
frontend.root"src/frontend"User frontend source root
frontend.indexHtmlsrc/frontend/pages/_document.htmlDocument template
frontend.outDir.vext/client in dev, dist/client in buildFrontend output directory
frontend.publicDir"public"Static public directory
frontend.publicPath"/"Public asset URL prefix

Style Fields

FieldDefaultMeaning
frontend.styles.entrystyles/index.cssGlobal CSS entry resolved from frontend.root
frontend.styles.jscss.enabledtrueEnable Vext JSCSS extraction
frontend.styles.jscss.files**/*.style.ts, **/*.style.js, **/*.css.tsJSCSS source globs
frontend.styles.jscss.runtimeAdaptercss-variablesEmit dynamic variables as CSS custom properties; none/false uses fallback values
frontend.styles.jscss.dynamicVarstrueEmit custom property declarations and var(...) references
frontend.styles.jscss.recipestrueEmit recipe variant classes and rules

Build Fields

FieldDefaultMeaning
frontend.build.target"es2022"Browser target passed to esbuild
frontend.build.minifyproduction trueMinify browser output
frontend.build.sourcemapdev trueEmit source maps
frontend.build.client.assetsDir"assets"Browser bundle asset subdirectory
frontend.build.client.splittingtrueEnable browser code splitting
frontend.build.client.external[]Browser external modules
frontend.build.client.externalRuntime{}Import-map URLs for browser externals
frontend.build.server.outFileserver/renderer.cjsSSR renderer bundle file under frontend.outDir
frontend.build.vendorChunksenabledShared runtime chunk strategy
frontend.build.assets.inlineLimit0Inline imported assets below this byte size
frontend.build.css.modulestrueEnable CSS Modules
frontend.build.diagnostics.leakScantrueBlock server-only imports from browser graph
frontend.build.diagnostics.sizeReporttrueWrite size-report.json
frontend.build.diagnostics.performanceReporttrueInclude route-level performance metrics

React-related browser externals must define externalRuntime mappings. Otherwise the build fails with a friendly diagnostic.

Browser output is directory-based and uses frontend.outDir; frontend.build.client.outFile is not supported. Vext always emits the frontend manifest family required by SSR, preload, deploy, and verification, so build.client.manifest / build.server.manifest are not configuration fields.

Deploy Fields

FieldDefaultMeaning
frontend.deploy.assetBaseUrlnoneCDN/public base URL for assets
frontend.deploy.crossOriginnonecrossorigin value for generated tags
frontend.deploy.integrityfalseAdd SRI integrity for generated JS/CSS
frontend.deploy.upload.enabledfalseEnable vext build --upload-assets / vext deploy assets upload
frontend.deploy.upload.adapternonefilesystem, mock, or custom adapter
frontend.deploy.upload.stateFile.vext/deploy/...Incremental upload state
frontend.deploy.upload.exclude["**/*.map"]Files excluded from upload

I18n Fields

FieldDefaultMeaning
frontend.i18n.enabledtrueScan and bundle frontend page copy
frontend.i18n.defaultLocalebackend default localeFallback frontend locale
frontend.i18n.clientLoad"current"Browser locale loading mode
frontend.i18n.htmlLangtrueWrite request-aware {vext.lang} / <html lang>

Dev Fields

FieldDefaultMeaning
frontend.dev.hottrueEnable frontend dev events
frontend.dev.fastRefreshtrueEnable React Fast Refresh when possible
frontend.dev.overlaytrueShow browser UI for frontend rebuild errors and render refresh prompts
frontend.dev.renderRefresh"prompt"Browser behavior after render-data backend reload

frontend.dev.overlay only controls frontend browser development UI. Backend exception HTML overlays are configured separately through top-level dev.errorOverlay.

SPA Fallback Fields

FieldDefaultMeaning
frontend.spaFallback.scopes[]Explicit client-router sub-app fallback scopes
frontend.spaFallback.exclude["/api/**", "/openapi.json", "/docs/**", "/_vext/docs/**"]Global paths that fallback never captures
scopes[].basePathrequiredURL prefix handled by the shell
scopes[].pagerequiredShell page id from src/frontend/pages/**
scopes[].ssrfalseWhether the shell should be SSR-rendered
scopes[].exclude[]Paths that must not be handled by fallback
scopes[].status200HTTP status for matched fallback