Frontend integration
Vext includes a first-party frontend path for projects that want API routes, a browser app, development rebuilds, production builds, and static serving in one Vext project. The default scaffold uses React 19. Browser-side API helpers are imported from vextjs/frontend, while the backend runtime contract stays framework-independent.
The current release is the P0 frontend foundation. It supports one browser entry, plain CSS, static assets, HTML template injection, SPA fallback, and a Vext API client helper. It is not a complete application-level frontend framework yet, so it does not automatically scan src/client/pages/** for page routes, and it does not include nested layouts, loaders/actions, SSR, RSC, or Server Actions.
Table of Contents
- 1. When to use Vext Frontend
- 2. Create and run a full-stack project
- 3. Understand the generated files
- 4. Change the home page
- 5. Add page files
- 6. Add components
- 7. Add styles
- 8. Add images and static assets
- 9. Call Vext APIs
- 10. Configure frontend
- 11. HTML template
- 12. Develop, build, and start
- 13. Disable frontend for API-only projects
- 14. Current boundaries and next stage
- 15. Troubleshooting
- 16. Maintainer reference
1. When to use Vext Frontend
Use the default frontend integration when:
- You want one Vext project to provide both API routes and browser pages.
- You want
vext devto run the backend and frontend together. - You only need one React browser entry and can organize pages inside
App.tsx. - You want
vext buildto output both server code anddist/client/frontend assets. - You want
vext startto serve static assets and SPA fallback in production.
Do not treat the current built-in path as the finished solution when:
- You need file routing, nested routes, layouts, loaders/actions, or route-level splits.
- You need SSR, React Server Components, or Server Actions.
- You expect Sass, CSS Modules, Tailwind, or similar tools to be built into Vext by default.
Those capabilities belong to a later P1 application layer. Today you can add a userland router or styling tool yourself, but the official default path only promises the features documented here.
2. Create and run a full-stack project
Create the default full-stack React project:
The default port is 3000. After the dev server is ready, open:
The default page calls /api/hello from the browser. That API is defined in src/routes/index.ts, and the page itself lives in src/client/App.tsx.
If you created the project with --skip-install, run:
3. Understand the generated files
The default TypeScript full-stack project creates these frontend-related files:
Do not edit files inside .vext/client/ or dist/client/ by hand. They are generated by Vext during dev/build.
4. Change the home page
The simplest home page entry is src/client/App.tsx. For example:
After saving the file, vext dev rebuilds the frontend for default src/client/** changes. Component-level HMR is not promised today; refresh the browser manually if needed.
5. Add page files
P0 does not automatically scan src/client/pages/** and turn those files into routes. You can use pages as a React page component directory, then import and render those components from App.tsx.
Create page files:
Wire them in App.tsx:
When a browser visits /about, Vext's SPA fallback returns the same index.html. The browser-side App.tsx decides which page to show. Creating src/client/pages/About.tsx alone does not create an automatic route in the current release.
If you need fuller client routing, you may add a userland router such as React Router. Vext does not install one by default.
6. Add components
Put reusable UI in src/client/components/:
Use it from a page:
components is a recommended convention, not a framework-scanned directory. You can also organize by feature, such as src/client/features/users/ or src/client/features/orders/.
7. Add styles
The default scaffold uses plain CSS. Global styles are imported from main.tsx:
Page or component styles can live next to the component:
CSS is bundled by esbuild and emitted as a production CSS asset. Vext injects the generated CSS link into HTML.
The default P0 path only promises plain CSS. Sass, CSS Modules, Tailwind, and CSS-in-JS are not built into Vext by default. You can add them in your application, but the official guide does not document them as built-in support.
8. Add images and static assets
Vext recommends two asset locations:
public/ example:
src/client/assets/ example:
If TypeScript reports missing image module types, add a declaration file in your app:
Do not edit generated output directories by hand: development output is .vext/client/, and production output is dist/client/.
9. Call Vext APIs
The default backend template provides:
Use vextjs/frontend in browser code:
createVextApiClient() supports:
GET,POST,PUT,PATCH, andDELETEshortcut methods.request(method, path, options)for other HTTP methods.paramsreplacement for path parameters such as/api/users/:id.query, JSONbody, requestheaders,signal, customfetch, andbaseUrl.- Non-2xx responses as
VextApiError, checked withisVextApiError(). - Automatic unwrap of Vext's
{ code: 0, data }response shape.
The template keeps a small handwritten contract in App.tsx so the example is self-contained. Builds also emit client-contract.json and api.generated.ts, but generated contracts currently keep request and response schema references as unknown; rich TypeScript inference from runtime schema definitions is not implemented yet.
10. Configure frontend
Minimal configuration
The default full-stack React template uses an object config. You can also enable defaults with:
Common configuration
Configuration reference
For a sub-path deployment such as /app/:
publicPath changes generated script, style, and asset URLs.
11. HTML template
The default template is src/client/index.html:
Current placeholders:
After vext build, rendered tags may look like:
A later P1 requirement plans to migrate official tokens to a %vext.*% style. Use %VEXT_STYLES% and %VEXT_ENTRY% in the current release.
12. Develop, build, and start
Develop:
Development frontend output is written to .vext/client/. Default src/client/** and public/** changes trigger a frontend rebuild instead of a backend cold restart. Backend API, config, route, service, middleware, plugin, locale, and preload changes keep their existing backend reload behavior.
Build:
Production frontend output is written to dist/client/:
Start production:
vext start only serves existing production frontend output. When frontend is enabled but dist/client/index.html is missing, startup fails fast and tells you to run vext build first.
SPA fallback only handles GET / HEAD browser navigation requests that accept HTML. It excludes /api/**, /openapi.json, and /docs/** by default, so API and docs paths still reach the backend runtime.
13. Disable frontend for API-only projects
Create a new API-only project:
Disable frontend in an existing project:
Or:
When disabled, Vext does not build, watch, or serve src/client/** / public/** frontend assets.
14. Current boundaries and next stage
Supported today:
- One browser entry:
src/client/main.tsx. - React 19 default scaffold.
- Plain CSS imports and CSS bundling.
- Common image, font, and SVG asset imports.
public/static asset copying.- HTML template injection with
%VEXT_STYLES%/%VEXT_ENTRY%. .vext/client/development output anddist/client/production output.- Static serving, cache headers, and SPA fallback.
vextjs/frontendAPI client helper.
Not supported yet:
- Automatic page file routing.
- Nested layouts, route groups, dynamic routes, and not-found routes.
- Route loaders/actions, route-level splits, and prefetching.
- Route-level head/meta/script/style management.
- SSR, streaming, React Server Components, and Server Actions.
- Built-in Sass, CSS Modules, or Tailwind.
The current workaround is to organize pages inside App.tsx, or add your own client router and styling tools. P1 should design application-level frontend routing, layouts, loaders/actions, type generation, splitting, and diagnostics as a separate layer.
15. Troubleshooting
16. Maintainer reference
Regular users do not need these internals to use frontend integration. Maintainers can locate behavior through these sources of truth:
Next, review Configuration, Build, and CLI Commands.