Advanced Convention Control
Canonical client Pages and Routes use positive src/pages/**/page.* anchors;
server request Routes use positive src/apis/**/api.* anchors. In both trees,
the containing directory determines the URL. Middleware comes from
src/middleware.ts plus src/apis/**/middleware.ts.
Use the control on this page only when the application intentionally owns its runtime composition or uses an explicit SPA route tree.
Disable File Conventions
File-convention discovery has one project-wide switch:
// ev.config.ts
import { defineConfig } from "@evjs/ev";
export default defineConfig({
conventions: false,
});
conventions: false disables all framework filesystem discovery together:
- Page and client-route anchors under
src/pages; - server request-route
api.*anchors undersrc/apis; - global
src/middleware.tsand route-scopedsrc/apis/**/middleware.ts.
There are no client-, server-, route-, middleware-, or facet-level disable
switches. Do not combine conventions: false with an explicit client routing
declaration. The server route directory is fixed at src/apis when file
conventions are enabled.
Explicit SPA application.routes configuration, reachable modules marked with
"use server";, and modules emitted by plugin contributions are not file
conventions. They remain available when filesystem discovery is disabled.
Manual browser bootstrap uses the standalone runtime below; it is not a second canonical routing model.
Programmatic Browser Apps
When the browser app owns routing itself, use the standalone client runtime
directly. This entry is owned by the application's standalone bundler; evjs
Framework config does not discover or build a magic src/main.tsx:
// src/main.tsx
import {
createApp,
createAppRootRoute,
createRoute,
Link,
Outlet,
} from "@evjs/client";
const rootRoute = createAppRootRoute({
component: () => (
<main>
<Link to="/">Home</Link>
<Outlet />
</main>
),
});
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: "/",
component: () => <h1>Home</h1>,
});
const app = createApp({
routeTree: rootRoute.addChildren([indexRoute]),
});
declare module "@evjs/client" {
interface Register {
router: typeof app.router;
}
}
app.render("#app");
This path is for applications that intentionally own their browser router and bootstrap. It is independent from the framework Page-and-Route model.
Programmatic Server Apps
Programmatic server apps use @evjs/server directly. They are runtime
primitives, not framework file-route inputs, so evjs will not scan source files
for createRoute() declarations.
// src/server.ts
import { createApp, createRoute } from "@evjs/server";
import { serve } from "@evjs/server/node";
const health = createRoute("/api/health", {
GET: async () => Response.json({ ok: true }),
});
const app = createApp({
routes: [health],
});
serve(app, { port: 3001 });
Run a programmatic server runtime as a normal Node, Fetch, Bun, Deno, or platform entry outside server file-route discovery.