Skip to content

Commit 8f7def1

Browse files
committed
docs: add dedicated frontend docs section
1 parent b33e1b1 commit 8f7def1

51 files changed

Lines changed: 2497 additions & 3868 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ Production builds also write `dist/client/deploy-manifest.json` for CDN or stati
274274

275275
For React hydration performance budgets, set fields such as `frontend.build.budgets.maxInitialJsBrotliBytes`, `maxRouteInitialJsBrotliBytes`, or `maxAppOwnedInitialJsBrotliBytes`. The default frontend i18n mode uses `frontend.i18n.clientLoad: "current"` so the browser loads only the SSR locale during hydration; use `"all"` only when a page needs no-reload locale switching. Advanced React CDN/import-map usage remains opt-in through `frontend.build.client.external` plus `externalRuntime`; React-related externals must provide runtime mappings.
276276

277-
For the frontend user guide, start with [Frontend Overview](https://vextjs.github.io/frontend/overview), then continue through project structure, pages, data/API calls, layouts, styles/assets, i18n, error pages, configuration, build/deploy, and troubleshooting from the Frontend menu.
277+
For the frontend user guide, start with [Frontend Overview](https://vextjs.github.io/frontend/overview). The Frontend section has its own navigation for getting started, routing/pages, SSR, hydration, CSR fallback, render data cache, Fast Refresh, code splitting, static assets/CDN, performance budgets, configuration, and troubleshooting.
278278

279279
When `frontend.apiClient` is enabled, Vext also emits `client-contract.json` and `api.generated.ts` next to the frontend output for tooling or advanced external frontend integrations. Normal page code does not need to hand-write route contracts; for first-screen data, prepare services in the route handler and pass props through `res.render()`.
280280

changelogs/unreleased.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## 2026-06-23
44

55
- **Config profile selection** Added `--config <name>` and `VEXT_CONFIG=<name>` as the official way to select `src/config/{profile}.ts` for `vext start`, `vext dev`, `vext build`, and `vext deploy assets`; `vext start` now forces production runtime `NODE_ENV` while keeping legacy custom `NODE_ENV` profile fallback with a migration warning.
6+
- **Frontend documentation** Added the dedicated frontend documentation space with frontend-only navigation and updated the overview/status wording to describe current built-in frontend capabilities instead of an in-development target.
67

78
## 2026-06-22
89

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# API Client and Contracts
2+
3+
Vext pages do not need a generated API client for first-screen data. Use route handlers and `res.render()` for that.
4+
5+
## Primary Data Path
6+
7+
```text
8+
route handler -> app.services -> res.render(page, props)
9+
```
10+
11+
This path keeps service calls server-side and produces SSR HTML with hydration data.
12+
13+
## Generated Artifacts
14+
15+
When `frontend.apiClient` is enabled, Vext can emit:
16+
17+
```text
18+
client-contract.json
19+
api.generated.ts
20+
```
21+
22+
These artifacts are useful for:
23+
24+
- external frontend adapters
25+
- type probes
26+
- client-side API calls after hydration
27+
- documentation or tooling
28+
29+
## Public Entry
30+
31+
The frontend public entry exposes contract helpers:
32+
33+
```ts
34+
import {
35+
createVextApiClient,
36+
createVextFetchAdapter,
37+
} from "vextjs/frontend";
38+
```
39+
40+
Use them when you need a typed client boundary. Do not add them to simple pages just to read first-screen data.
41+
42+
## Plain Fetch Is Fine
43+
44+
For small client interactions after hydration:
45+
46+
```ts
47+
await fetch("/api/preferences", {
48+
method: "POST",
49+
headers: { "content-type": "application/json" },
50+
body: JSON.stringify(payload),
51+
});
52+
```
53+
54+
Make sure client requests send the right `Accept` header so API calls are not treated as HTML navigation inside a SPA fallback scope.
55+
56+
## Boundary Rule
57+
58+
Generated client artifacts describe HTTP contracts. They do not make `src/services/**` browser-safe. Service modules remain server-only.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Boundaries and Roadmap
2+
3+
This page separates current frontend targets from future capability tracks.
4+
5+
## Current Target
6+
7+
The current Vext frontend direction is:
8+
9+
- `src/frontend/**` as the user frontend source root
10+
- `src/routes/**` as URL and server data entry
11+
- `res.render(page, props?, options?)`
12+
- React 19 SSR plus hydration
13+
- nested layout chain
14+
- default error pages and `renderError()`
15+
- Vext JSCSS plus CSS/CSS Modules
16+
- frontend i18n with `useVextI18n(locale?)`
17+
- Fast Refresh and render refresh in development
18+
- esbuild-powered production build
19+
- route assets, code splitting, size reports, budgets, deploy manifest, SRI, and incremental static upload
20+
21+
## Version Boundary
22+
23+
This section documents the current frontend capability in the Vext documentation set. For an installed package version, use that version's release notes and changelog to check exactly which frontend features are available.
24+
25+
## API-only Projects
26+
27+
API-only projects remain first-class:
28+
29+
```bash
30+
npx vextjs create my-api --template api --frontend none
31+
```
32+
33+
Or disable frontend in config:
34+
35+
```ts
36+
export default {
37+
frontend: false,
38+
};
39+
```
40+
41+
## External Frontend Adapters
42+
43+
Vext can expose contracts for external frontend frameworks through `vextjs/frontend`, generated API artifacts, and stable HTTP boundaries. The default integrated experience remains Vext-owned full-stack React.
44+
45+
## Future Tracks
46+
47+
These are not first-phase commitments, but can be evaluated later:
48+
49+
- React Server Components
50+
- Server Actions
51+
- streaming SSR
52+
- persistent client layout navigation
53+
- built-in image/font optimization components
54+
- deeper external framework adapters
55+
56+
Each track needs separate requirements, performance evidence, and compatibility review before becoming default behavior.
57+
58+
## Current Non-goals
59+
60+
- hiding server imports in browser bundles
61+
- making page files create routes automatically
62+
- treating global SPA fallback as the default
63+
- uploading SSR HTML as a static asset by default
64+
- adding cloud-provider SDKs to core for asset upload
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Build and Deploy
2+
3+
`vext build` compiles server output and frontend output in one command.
4+
5+
## Output
6+
7+
When frontend is enabled, production output includes:
8+
9+
```text
10+
dist/
11+
server/
12+
client/
13+
index.html
14+
manifest.json
15+
render-manifest.json
16+
deploy-manifest.json
17+
size-report.json
18+
assets/
19+
```
20+
21+
`vext start` serves the built client assets and uses `render-manifest.json` for SSR.
22+
23+
## Build Command
24+
25+
```bash
26+
vext build
27+
```
28+
29+
To upload static assets after build:
30+
31+
```bash
32+
vext build --upload-assets
33+
```
34+
35+
Or run upload separately:
36+
37+
```bash
38+
vext deploy assets --dry-run
39+
vext deploy assets
40+
```
41+
42+
## Deploy Manifest
43+
44+
`deploy-manifest.json` records static assets that can be uploaded:
45+
46+
- JS and CSS assets
47+
- imported images/fonts/media
48+
- copied `public/**` files
49+
- content type
50+
- sha256
51+
- SRI for eligible assets
52+
- upload key and public URL
53+
54+
HTML is not uploaded by default because SSR still belongs to the server runtime.
55+
56+
## Incremental Upload
57+
58+
The upload state file stores known sha256 values. Unchanged assets are skipped, so images and fonts are not uploaded again on every release.
59+
60+
Keep `stateFile` outside the frontend outDir because build output is normally cleaned.
61+
62+
## Configuration
63+
64+
```ts
65+
frontend: {
66+
deploy: {
67+
assetBaseUrl: "https://cdn.example.com/my-app/",
68+
integrity: true,
69+
upload: {
70+
enabled: true,
71+
adapter: "filesystem",
72+
targetDir: ".vext/frontend-cdn",
73+
publicBaseUrl: "https://cdn.example.com/my-app/",
74+
prefix: "my-app",
75+
stateFile: ".vext/deploy/frontend-assets-state.json",
76+
exclude: ["**/*.map"],
77+
},
78+
},
79+
}
80+
```

0 commit comments

Comments
 (0)