Example Content Build
The relation-graph example detail pages serve both human users and machine readers. To let LLMs fetch an example URL and read the article, file tree, and source code directly from the HTML, the static build injects source snapshots into free example pages.
This page documents the route model, source injection boundary, incremental build behavior, and cache layout for /examples/*.
Route Model
Example detail pages use the platform path as the static HTML variant:
| Route | Meaning |
|---|---|
/examples/<exampleId> |
Legacy entry. It renders the React version and uses a canonical link to /examples/<exampleId>/react. |
/examples/<exampleId>/react |
React example detail page. |
/examples/<exampleId>/vue3 |
Vue 3 example detail page. |
/examples/<exampleId>/vue2 |
Vue 2 example detail page. |
/examples/<exampleId>/svelte |
Svelte example detail page. |
/examples/<exampleId>/web-component |
HTML/Web Component example detail page. |
/zh/examples/<exampleId>/... |
The corresponding Chinese locale page. |
The old ?lang=<platform> query is no longer used as a static HTML variant. When the client sees an old URL such as:
/zh/examples/basic-custom-node-and-minimap?lang=vue3
it redirects to:
/zh/examples/basic-custom-node-and-minimap/vue3
This gives every locale + exampleId + platform combination its own HTML, so a crawler or LLM does not receive React source code from a Vue URL.
Source Injection Boundary
The build injects source snapshots only for free examples. The free-example check is:
!example.meta?.vip && !example.meta?.entVip
Paid examples still get platform pages, but their generated HTML does not include source snapshots. When a user opens the source panel for a paid example, the page still calls the source-code-v2/* APIs, and those APIs perform login and permission checks.
For free examples, the build injects the source snapshot near the end of the generated HTML:
<script id="rg-example-source-snapshot" type="application/json">
...
</script>
The JSON contains:
| Field | Meaning |
|---|---|
exampleId |
The example ID. |
platform |
The platform name, such as vue3. |
sourceRoot |
The source directory. |
mainFile |
The default source file to open. |
filesTree |
The complete file tree. File nodes contain full text source content. |
files |
A compact list of file paths, sizes, and hashes. |
When the source panel opens, the frontend first reads this embedded snapshot. If it matches the current example and platform, file-tree clicks do not call the source APIs. If no matching snapshot is present, the component falls back to the existing API flow.
| Example type | Source in SSR HTML | Source file click behavior |
|---|---|---|
| Free example | Yes | Uses the embedded snapshot first; no source API call is needed. |
| Paid example | No | Calls the API, which enforces permissions. |
| SPA navigation without loading target HTML | Not guaranteed | May fall back to the API; platform switching uses full page navigation to load the target HTML. |
Source Directories
The build reads the local source repositories directly:
| platform | Source directory |
|---|---|
react |
../relation-graph-site-react/src/v3-examples/<exampleId> |
vue3 |
../relation-graph-site-vue3/src/v3-examples/<exampleId> |
vue2 |
../relation-graph-site-vue2/src/v3-examples/<exampleId> |
svelte |
../relation-graph-site-svelte/src/v3-examples/<exampleId> |
web-component |
../relation-graph-site-web-component/src/v3-examples/<exampleId> |
For free examples, a missing or unreadable source directory for any platform fails the build and reports the concrete exampleId + platform + file.
The scanner skips:
| Type | Details |
|---|---|
| Dependency and build directories | node_modules, .nuxt, .output, dist, build, coverage, and similar directories. |
| Lock files | package-lock.json, pnpm-lock.yaml, yarn.lock, bun.lockb. |
| Binary resources | Images, fonts, video/audio files, archives, PDFs, WASM, and similar files. |
Text source files are injected in full and are not truncated. To prevent accidental huge HTML output, the scanner has a per-file and per-snapshot build limit. If a text source exceeds the limit, the build fails instead of producing partial source code.
Build Modes
yarn generate:relation-graph defaults to changed mode:
yarn generate:relation-graph
which is equivalent to:
RG_EXAMPLES_PRERENDER_MODE=changed yarn generate:relation-graph
Supported modes:
| Mode | Behavior | Use case |
|---|---|---|
full |
Regenerates every example detail page and refreshes the cache. | First setup, template changes, cache refresh. |
changed |
Default. Regenerates only changed example detail pages and restores the rest from cache. | Normal builds. |
skip |
Does not generate example detail pages; restores all of them from cache. Fails if the cache is not safe. | Fast builds when /examples/* is known to be unaffected. |
The first run, or any run without a complete cache, should be:
RG_EXAMPLES_PRERENDER_MODE=full yarn generate:relation-graph
Normal daily builds can use:
yarn generate:relation-graph
Fingerprint Rules
changed mode calculates a fingerprint for each example detail route. The fingerprint includes:
| Input | Effect |
|---|---|
locale |
Chinese and English pages are tracked separately. |
exampleId and platform |
Each platform page is tracked separately. |
| Example metadata, title, and description | Example catalog changes trigger rebuilds. |
| The current locale’s example markdown | Article changes rebuild the affected locale. |
| Free example source file paths and content hashes | Source changes rebuild the affected platform pages. |
| Example detail template, source panel, platform utilities, site config | Shared template changes make changed mode fall back to full. |
| Scanner version | Scanner rule changes make changed mode fall back to full. |
Paid examples do not include source hashes in their fingerprints because the static build does not read or inject paid source code.
Cache Layout
The local cache lives at:
.cache/relation-graph-example-prerender/
Main entries:
| Path | Meaning |
|---|---|
manifest.json |
Route fingerprints, template hash, source snapshot hashes, and update times. |
routes/ |
Cached index.html and _payload.json files for each example detail route directory. _payload.json contains Nuxt payload data, including the example article content. |
assets/ |
Cached _nuxt assets referenced by old example HTML. |
work/current-plan.json |
The build plan for the current run. |
work/source-snapshots/ |
Source snapshots generated during the current run. |
changed and skip modes restore unchanged example route index.html and _payload.json files into:
apps/relation-graph-site/.output/public
They also merge cached _nuxt assets back into the output directory. It is expected that .output/public/_nuxt may temporarily contain multiple asset versions, because reused old HTML must keep the hashed assets it references.
Build Flow
yarn generate:relation-graph runs three stages:
1. ai-tools/example-prerender/prepare.mjs
Scans example source, calculates fingerprints, and writes current-plan.json.
2. nuxi generate apps/relation-graph-site
Prerenders only the planned example detail routes plus the rest of the site.
3. ai-tools/example-prerender/finish.mjs
Restores unchanged example HTML and payload files, injects free source snapshots, caches new HTML, payload, and _nuxt assets, and updates manifest.json.
Nuxt prerender still uses crawlLinks, but example detail pages are restricted by an ignore rule: only planned routes without query strings are allowed. Detail URLs with fromGroupId, lang, or other query parameters are not written as static HTML.
Commands
# Normal build: defaults to changed
yarn generate:relation-graph
# Force-refresh every example detail page and cache entry
RG_EXAMPLES_PRERENDER_MODE=full yarn generate:relation-graph
# Skip example detail generation and restore from cache
RG_EXAMPLES_PRERENDER_MODE=skip yarn generate:relation-graph
# Raw Nuxt static build without the example cache flow. Use only for debugging.
yarn generate:relation-graph:nuxt
Troubleshooting
| Problem | Action |
|---|---|
skip mode fails |
The cache is incomplete or the template hash changed. Run full. |
| A free example source directory is missing | Restore the corresponding platform source directory, or remove the example from the catalog. |
| A text source file is too large | Split the source file, or confirm it should be excluded as generated/binary content. |
| Paid example HTML contains source | Treat this as a serious issue. Check the free/paid detection and injection script. |
The article flashes and then becomes Markdown File Not Found |
This usually means the route’s _payload.json was not restored into .output/public. During hydration the browser falls back to /api/example-markdown-content, which does not exist on the static Pages deployment. Refresh the example cache. |
Old _nuxt assets return 404 |
Ensure .cache/relation-graph-example-prerender/assets/ was merged into .output/public/_nuxt. |