Skip to content
rshono
Documentation menu

Reference

API reference

Every export of @rshono/core, @rshono/core/server and @rshono/core/client, in one place.

Three entry points, and which one an import comes from tells you where the code runs. That is most of what there is to know about the surface.

Import Runs Holds
@rshono/core build time, server route and config declaration, and the types pages are written against
@rshono/core/server per request, server only the request context, redirect / notFound, error reporting
@rshono/core/client browser, from 'use client' modules the navigation hook and the boundaries

@rshono/core pulls in no runtime machinery — importing it from server code is free. @rshono/core/server from a 'use client' module is a mistake: those run in the browser, where no request is bound. Read what you need on the server and pass it down as props.

These three are the whole public surface — the package's exports map lists only them, so there is no deeper path to import. Everything else is framework plumbing.

@rshono/core

Functions

Signature What it does
defineRoutes(config): RouteConfig Declares the app's route table in src/routes.ts. Also accepts a bare Route[] as shorthand. Cross-checks every page's props against its own path.
defineConfig(config): RshonoConfig Types rshono.config.ts. Identity function — it exists for the autocomplete.

See Routing and Configuration.

Types

Type What it describes
PageProps<Path, E> What every page receives: url, params, ctx. Pass the route's path to type params key-by-key.
PageComponent<P> A page: a server component returning ReactNode or Promise<ReactNode>.
PathParams<P> The params record a path pattern implies — '/users/:id'{ id: string }. PageProps applies it for you.
PageRoute A path rendered by a server component: path, component, and optional render / staticPaths.
EndpointRoute A path served by a Hono handler: type: 'endpoint', path, server, optional method.
EndpointServerModule What an endpoint's module must export — a single named handler.
Route PageRoute | EndpointRoute.
RouteConfig<TRoutes> The object defineRoutes takes: routes, plus optional notFound and error.
FallbackPage The notFound / error page shape — a component with no path of its own.
ErrorPageProps<E> PageProps plus error, for the page declared as error.
ErrorPageInfo { message, stack? }. Redacted in production: a generic message, no stack.
HTTPMethod 'get' | 'post' | 'put' | 'patch' | 'delete' | 'head' | 'options' | 'all'.
RshonoConfig Every field of rshono.config.ts. All optional.
RspackHookContext { isServer, isDev }, handed to the rspack config hook.
DeployTarget 'node' | 'cloudflare' | 'vercel' | 'aws-lambda'.

@rshono/core/server

Server-only, and request-scoped. See Pages and Server actions.

Functions

Signature What it does
getRequestContext<E>(): RequestContext<E> The current request's context. Memoised per request. Throws at module load, and while prerendering a render: 'static' route.
redirect(location, status?): never Throws a control signal the framework turns into a redirect. status defaults to 303.
notFound(): never Aborts the render with a 404 and the app's not-found page.
onServerError(handler): void Registers one handler for every error the framework catches. Call it once, at the top level of src/server.ts.

redirect and notFound never return, so TypeScript narrows away the code after them and you don't need to return the call. Don't wrap either in a try/catch that swallows the signal.

import { getRequestContext, redirect } from '@rshono/core/server';

export default async function Dashboard() {
  const session = getRequestContext().cookies.get('session');
  if (!session) redirect('/login');
  return <Layout>Signed in as {session}</Layout>; // session is defined here
}

RequestContext

What getRequestContext() returns, and the very same object a page gets as its ctx prop. Exported as a type only — one instance exists per request and application code never constructs it.

Member What it is
url The browser-facing URL, proxy-header aware. Parsed once and cached.
env Process env merged with runtime bindings (bindings win). See Environment.
var Typed variables a middleware set with c.set(…).
raw The underlying Hono Context — the escape hatch for everything not above.
cookies.get(name) One cookie, or undefined.
cookies.all() Every cookie as { name: value }.
cookies.set(name, value, options?) Sets a cookie on the response.
cookies.delete(name, options?) Clears one. Pass the path/domain it was set with.

That is the whole wrapper. What it adds over Hono's own Context is a proxy-aware cached URL, an env that merges runtime bindings over process env, and cookies without a second import. Anything else is ctx.rawctx.raw.req for the parsed request, ctx.raw.header(name, value) to set a response header. Route params come to a page as its params prop.

ctx cannot be handed to a 'use client' component — it wraps the live request. Reading it on a render: 'static' page throws, because there is no request at build time.

Types

Type What it describes
RequestContext<E> The request context above. E is the app's Hono Env, which types var and env.
EnvVars<E> What ctx.env resolves to: Bindings merged with Record<string, string | undefined>.
RedirectStatus 301 | 302 | 303 | 307 | 308.
ServerErrorHandler (error, context) => void — what onServerError takes.
ServerErrorContext { source, request }, the second argument to that handler.
ServerErrorSource 'action' | 'render' | 'ssr' | 'request' — which stage produced the error.

An 'action' error is the one worth wiring up: React sends the client an opaque marker with no message in production, so a handler is the only place the real error is visible.

@rshono/core/client

Every export is itself a 'use client' module, so a server component can render AsyncBoundary directly. The hook needs a client component.

Hook

Signature What it returns
useNavigation(): NavigationState { url, params, router } — the current location, and the router.

url and params are computed on the server and travel in the flight payload, so they are right during SSR and update on every navigation. In a server component, read the same data from getRequestContext().

'use client';
import { useNavigation } from '@rshono/core/client';

export function NextPage() {
  const { url, router } = useNavigation();
  const page = Number(url.searchParams.get('page') ?? '1');
  return (
    <button disabled={router.pending} onClick={() => router.push(`${url.pathname}?page=${page + 1}`)}>
      Next
    </button>
  );
}

router holds push(href), replace(href), refresh() and the pending flag. All three are soft navigations: the new page's flight payload is fetched and applied in place, so client state outside the changed subtree survives. Off-site hrefs fall back to a full load. History traversal is history.back() and history.forward() — the router wrapped them once and added nothing, so it no longer does.

Components

Component Props What it does
<AsyncBoundary> loading, error, onError, resetKeys A Suspense fallback and an error fallback in one wrapper — the common case for an async section.
<CatchBoundary> fallback, onError, resetKeys Error boundary alone. Omit fallback to report and re-throw to the next boundary out.

loading on AsyncBoundary is required — a loading state is the reason to reach for it over CatchBoundary, so showing nothing while loading is an explicit loading={null}. error is optional: omit it and throws propagate to the next boundary out or the global error page. A redirect() is never absorbed by either boundary — it's navigation, not failure.

Types

Type What it describes
NavigationState { url, params, router } — what useNavigation() returns.
NavigationRouter The imperative actions plus pending.
AsyncBoundaryProps Props of <AsyncBoundary>.
CatchBoundaryProps Props of <CatchBoundary>.
ErrorFallback ReactNode, or (error, reset) => ReactNode. The function form only works from a 'use client' module.