Skip to main content
0.0.x

Generated web surface

A scaffolded Fresh app contains both editable starter code and modules that are regenerated from route files. A file created by the CLI is not necessarily generator-owned. In particular, ui:add page output has no generated header banner; use the roles below to decide what to edit. All paths below are relative to the Fresh app root, such as apps/dashboard/.

Surface Role and ownership How to change it
routes/catalog/index.tsx App-owned page created by netscript ui:add page catalog. Imports definePage from @app/utils.ts and binds appRoutes['catalog'] from @app/router.ts. Edit the page, metadata, view, and loaders. Move it together with its owned colocated files.
routes/catalog/(_shared)/query-loaders.ts Editable server query loader, created when --island selects a service client. Edit data loading and repair imports after a move.
routes/catalog/(_islands)/CatalogIsland.tsx Editable client island created alongside that loader. Edit the interactive view and its query inputs; keep its loader import in sync.
router.ts Editable app route registry (appRoutes). ui:add page adds createRouteReference('/catalog', { id: 'catalog', kind: 'page' }). Reconcile the literal URL, key, metadata id, and consumers manually after a move/removal. Vite manifest generation does not reconcile this registry.
utils.ts Scaffolded, editable shared define and definePage wiring. Keep app state and builder configuration consistent with page imports.
A sibling *.contract.ts App-owned route contract sidecar, if you author one; not part of the ui:add page triad. Move it with its matching page and reconcile schemas when parameters change.
.generated/manifest.ts Generator-owned routePatterns tree derived from filesystem routes. Refresh through the configured NetScript Vite plugin; do not hand-edit.
.generated/routes.ts Generator-owned routes tree of bound references, using discovered contracts where present. Refresh through the configured NetScript Vite plugin; update consumers when accessor keys change.

The loader/island pair is optional: a page without --island has the page and registration only. (_shared) and (_islands) are co-location groups and do not add URL segments. Renaming component symbols is optional; updating their imports is necessary whenever the move changes relative paths.

Refreshing the route tree

With routeManifest enabled in createNetScriptVitePlugin, the plugin writes the generated route modules on initialization and build, and refreshes them on relevant route changes during a dev server run. Use the app's configured Vite build or dev task after a move. A standalone deno check does not refresh these modules. Run netscript generate routes --app dashboard to refresh them without a Vite build; --project-root <app-root> selects an explicit application.

The plugin also manages route-binding seams for the authoring forms described in Routing and route contracts. That does not make the separate string-literal appRoutes registry track filesystem renames.

Rename safety and manual lifecycle

After regeneration, a removed accessor such as routes.catalog.$route fails type checking at consumers that still reference it. appRoutes['catalog'], however, can keep compiling after a folder move because its pattern is a string literal. Typed href parameters do not prove that a route file exists at that URL.

Use the Renaming or Moving a Route checklist to reconcile the directory, colocated files, router.ts, page binding, navigation, and generated tree. Verify the new URL and loader/island behavior in the running app as well as type checking.

For a move from routes/catalog/ to routes/inventory/, change the router.ts pattern from /catalog to /inventory. The registry key and metadata id are identifiers, not URL segments: you may keep catalog, or rename both to inventory and update the page to .withRoute(appRoutes['inventory']) and every consumer of the old key. Remove obsolete or duplicate registrations. Search for the old URL and generated accessor too; check navigation, redirects, and partial pairings. If parameters change, reconcile path schemas and href inputs. After refreshing the tree, type-check and visit the new URL, including any loader and island. Decide whether the old URL should return 404 or needs an authored redirect for existing links.

There is currently no netscript ui:rename or netscript route rename command. netscript ui:remove <name> removes a copied Fresh UI registry item. Use netscript ui:remove page catalog --dry-run to validate and preview a page removal. Without --dry-run, it deletes only unchanged ui:add page output (page plus optional loader/island), prunes its generated string-literal router registration, and regenerates the derived route modules. It preserves authored siblings, sidecars and unrelated routes. Use --client <service> when the original data client is ambiguous. Formatting with the scaffold’s deno task fmt is accepted: scaffold files are compared after Deno formatting, and wrapped router entries are recognized. Code or comment edits, missing scaffold parts and customized registrations are refused; there is no force override. Remove customized pages manually, prune their registration and consumers, then run netscript generate routes. Idempotent reruns rebuild missing derived modules without deleting authored files and report “Nothing to remove” for an absent page. Empty parent directories are pruned without removing the routes root or authored siblings. Update links and type-check after removal.