@k8ordo/server

Options and files

The options of framework(), the files src/routes/ may hold, and what each entry of @k8ordo/server exports. How to use each is covered in the guides.

On this page

Four entries

@k8ordo/server splits its entries by where the code runs. A deployed application loads only runtime and serve, and neither loads Vite.

  • @k8ordo/server: framework(), the plugin for vite.config.ts. It loads Vite.
  • @k8ordo/server/runtime: what code inside the handler imports. It uses nothing only Node.js has, so it runs wherever the handler does.
  • @k8ordo/server/serve: serve(), which runs the build on Node.js.
  • @k8ordo/server/vercel: vercel(), the plugin that writes Vercel’s output.

framework

Import from @k8ordo/server

The Vite plugin that makes the application run on a server. It returns an array that includes React’s plugin and the RSC pipeline; put it in plugins as it is.

ts
framework(options?: ServerOptions): PluginOption[]

Parameters

options.routesDirstring
The route directory, relative to the project root; src/routes by default. The generated files still go to .k8ordo/.

Returns

PluginOption[] — An array of Vite plugins.

vite.config.ts
import { framework } from '@k8ordo/server';
import { defineConfig } from 'vite';

export default defineConfig({ plugins: [framework()] });

Route files

The files a directory under src/routes/ may hold, what each exports and what it receives. Anything else goes under a directory whose name starts with _.

page.tsx

  • Default export: the page component that answers its directory’s URL. It receives params and pathname.
  • In this mode it also receives request: the request’s headers and cookies.
  • paramsSchema: a schema that validates the parameters, anything implementing Standard Schema. Optional.
  • search: the url schema the page reads. A page that declares it receives that slot as search.

layout.tsx

  • Default export: a component that wraps what renders below it, received as children. It also receives params and pathname, with params typed as strings.
  • In this mode it also receives request: the request’s headers and cookies.
  • paramsSchema: runs for every page below, before the page’s own.

not-found.tsx

  • Default export: a component that answers any URL below its directory that no route matched. It receives params and pathname, and the params are unvalidated strings.
  • In this mode it also receives request: the request’s headers and cookies.
  • In this mode it answers under a 404, and each directory may hold its own.

error.tsx

  • A 'use client' file.
  • Default export: a component receiving error and reset, rendered in place of what is below it when that throws. It receives no params.

loading.tsx

  • Default export: a component with no props, rendered as the <Suspense> fallback while the page below it loads.

redirect.ts

  • Default export: the target as a string, or { to, permanent }. to is a pattern of the route table, filled with the matched parameters.
  • In this mode it answers GET and HEAD with a 307, or a 308 when permanent.

route.ts

  • Exports named after methods, such as GET and POST: functions that receive { request, params } and return a Response.
  • paramsSchema: validates the parameters, as a page’s does.
  • In this mode any of the seven methods may be exported. Without a HEAD, it answers with the GET response, body left off.

guard.ts

  • Default export: a function that receives { request, params }. Returning a Response ends the request there; returning nothing lets it through. It runs before anything below its directory answers.

What route files use from @k8ordo/router

The types and functions route files use come from @k8ordo/router, not from the mode package, so a page reads the same under either mode.

  • PageProps<pattern>: the props a page receives.
  • LayoutProps<pattern>: the props a layout receives.
  • ErrorProps: the props an error.tsx receives.
  • RouteContext<pattern>: what a route.ts function receives.
  • notFound(): thrown from a page, it has the nearest not-found.tsx answer under a 404.
  • href(): builds a URL typed against the route table.
  • usePathname() and useMatch(): hooks that read the current URL in the browser.
  • usePendingPathname(): a hook that reads where a navigation under way is going.

cookies

Import from @k8ordo/server/runtime

Reads and writes the request’s cookies, from a guard.ts, a route.ts or a Server Action.

ts
cookies(): Cookies

Fields

get(name: string) => string | undefined
Reads a value by name; undefined when there is none.
has(name: string) => boolean
Whether a cookie of that name is there.
set(name: string, value: string, options?: CookieOptions) => void
Writes a value, with the attributes of CookieOptions as the third argument.
delete(name: string, scope?: { path?: string; domain?: string }) => void
Deletes a cookie. Pass the path and domain it was written with.

Caveats

  • A read sees the cookies the request carried, with what was written earlier in the same request on top.
  • Every write reaches the browser as a Set-Cookie on the answer, whatever the answer is.
  • It throws when called while a page renders; a page reads request.cookies.
ts
cookies().get('session');
cookies().set('session', token, { maxAge: 60 * 60 * 24 });
cookies().delete('session');

Import from @k8ordo/server/runtime

The attributes passed to cookies().set() as its third argument. Leave them out, and they are what a session wants.

ts
type CookieOptions = {
  path?: string;
  domain?: string;
  maxAge?: number;
  expires?: Date;
  httpOnly?: boolean;
  secure?: boolean;
  sameSite?: 'strict' | 'lax' | 'none';
};

Fields

pathstring
/ by default.
domainstring
Not set by default.
maxAgenumber
How long it lasts, in seconds. 0 expires it at once.
expiresDate
When it expires, as a Date.
httpOnlyboolean
true by default: a page’s script cannot read it.
secureboolean
true by default: sent over HTTPS only. For a request over plain HTTP to this machine (localhost and the like), the default is false.
sameSite'strict' | 'lax' | 'none'
'lax' by default. 'none' only goes with secure.

responseHeaders

Import from @k8ordo/server/runtime

Returns the Headers the final response will carry. What is set here goes on the answer, whether a page, its payload or a Response a guard returned.

ts
responseHeaders(): Headers

Caveats

  • A header the answer already carries is replaced.
  • It throws outside a guard.ts, a route.ts or a Server Action.

requestHeaders

Import from @k8ordo/server/runtime

Returns the headers the request arrived with — for a Server Action, which receives its arguments rather than the request.

ts
requestHeaders(): Headers

Caveats

  • It throws outside a guard.ts, a route.ts or a Server Action.

redirect

Import from @k8ordo/server/runtime

Ends a Server Action and sends the visitor to another URL.

ts
redirect(to: string): never

Parameters

tostring
Where to go. It is sent as written, so build it with href().

Returns

never — It never returns; it throws.

Caveats

  • It ends by throwing, so do not call it inside a try.
  • A form posted before JavaScript arrived is answered with a 303; a call from the client runtime with a payload telling the router where to go.

nonce

Import from @k8ordo/server/runtime

Returns the nonce this answer’s inline scripts carry, new for every request.

ts
nonce(): string

Caveats

  • It returns the same value anywhere the request is being answered, the render included.
  • It throws outside a request.

Guard

Import from @k8ordo/server/runtime

The type of what a guard.ts default-exports, given its directory’s pattern.

ts
type Guard<P extends string = string> = (context: {
  request: Request;
  params: ParamsOf<P>;
}) => Response | void | Promise<Response | void>;

Fields

requestRequest
The Request as it arrived.
paramsParamsOf<P>
The parameters of its directory’s pattern, as the URL’s strings: a guard runs before any schema.

RouteRequest

Import from @k8ordo/server/runtime

The type of the request a page, a layout and a not-found.tsx receive. Both fields are read-only.

ts
type RouteRequest = {
  headers: Headers;
  cookies: ReadonlyMap<string, string>;
};

Fields

headersHeaders
The request’s headers.
cookiesReadonlyMap<string, string>
The Cookie header read by name. When a name appears twice, the first wins.

RedirectTarget

Import from @k8ordo/server/runtime

The type of what a redirect.ts default-exports. Write satisfies RedirectTarget to check the shape where it is written.

ts
type RedirectTarget =
  | string
  | { to: string; permanent?: boolean };

serve

Import from @k8ordo/server/serve

Runs the build on a Node.js HTTP server. Once it is listening, it returns where it listens and how to stop it.

ts
serve(options?: ServeOptions): Promise<Server>

Parameters

options.diststring
The build output directory; dist by default, resolved from the working directory.
options.portnumber
The port to listen on; 3000 by default. 0 lets the system pick a free one.
options.hoststring
The host to listen on. The default, localhost, is reachable from the same machine only; pass 0.0.0.0 inside a container and the like.

Returns

Promise<Server> — The server, once it is listening.

Fields

portnumber
The port it actually listens on.
urlstring
Its URL, http://<host>:<port>.
close() => Promise<void>
Stops the server, returning a promise that settles once it has stopped.

Caveats

  • A GET or HEAD naming a file in dist/client/ gets that file; everything else goes to the handler.
  • When the handler throws, it answers a 500 with the body internal error, and logs what was thrown.
serve.js
import { serve } from '@k8ordo/server/serve';

const server = await serve({ port: 3000 });
console.log(server.url);

vercel

Import from @k8ordo/server/vercel

A plugin that has vite build also write .vercel/output/ in the shape of Vercel’s Build Output API (v3). Put it beside framework().

ts
vercel(): Plugin

Returns

Plugin — A Vite plugin.

Caveats

  • The handler is bundled with every dependency, so one that ships a native binary, or reads its own files by path, does not work.
vite.config.ts
import { framework } from '@k8ordo/server';
import { vercel } from '@k8ordo/server/vercel';
import { defineConfig } from 'vite';

export default defineConfig({ plugins: [framework(), vercel()] });
k8ordo

React libraries that use Baseline features without holding back.

© 2026 k8o — MIT License

Typeset in Noto Sans JP & M PLUS 2