Skip to content

Using with Hono ​

Quick Start ​

ESM ​

javascript
import { Hono } from 'hono';
import Router from 'clear-router/hono';

const app = new Hono();

Router.get('/hello', () => {
  return 'Hello World';
});

Router.apply(app);

export default app;

TypeScript ​

typescript
import { Hono } from 'hono';
import Router from 'clear-router/hono';

const app = new Hono();

Router.get('/hello', () => {
  return 'Hello World';
});

Router.apply(app);

export default app;

Usage Examples ​

Basic Route ​

javascript
Router.get('/hello', () => {
  return 'Hello World';
});

Direct Return Values ​

Hono handlers can return response values directly. You can still return Hono responses from helpers such as ctx.text(), ctx.json(), and ctx.body() when you need explicit control.

javascript
Router.get('/hello', () => 'Hello World');
Router.get('/page', () => '<h1>Hello</h1>');
Router.get('/users', () => [{ id: 1, name: 'Ada' }]);
Router.post('/users', (ctx) => ({ id: 1, ...ctx.req.getBody() }));
Router.get('/accepted', () => new Response('Accepted', { status: 202 }));

Direct POST returns default to 201; other methods default to 200. HTML-like strings are sent as text/html, API/XHR string responses as text/plain, and objects/arrays as JSON.

With Middleware ​

javascript
const authMiddleware = async (c, next) => {
  // auth logic
  await next();
};

Router.post('/secure', () => ({ ok: true }), [authMiddleware]);

Method Override ​

clear-router supports HTTP method override for POST requests using body keys or headers.

Default override keys:

  • Body: _method
  • Header: X-HTTP-Method
javascript
Router.put('/users/:id', (ctx) => {
  return { method: ctx.req.method, id: ctx.req.param('id') };
});

// POST /users/12 with body { "_method": "PUT" }

Custom keys are supported:

javascript
Router.configure({
  methodOverride: {
    bodyKeys: ['_method', 'method'],
    headerKeys: ['x-http-method', 'x-method-override'],
  },
});

Disable override behavior:

javascript
Router.configure({ methodOverride: { enabled: false } });

Request Body Access via ctx.req.getBody() ​

clear-router patches Hono requests with ctx.req.getBody() for consistent body access in handlers and controllers.

  • Always available in route handlers.
  • Returns parsed request body when present.
  • Returns {} when the request has no body.
javascript
Router.post('/users', (ctx) => {
  const body = ctx.req.getBody();
  return { hasName: Boolean(body.name) };
});

Router.get('/status', (ctx) => {
  return { body: ctx.req.getBody() }; // {}
});

Controller Binding ​

javascript
class UserController {
  index() {
    return 'User List';
  }
}

Router.get('/users', [UserController, 'index']);

Handler Arguments and ClearRequest ​

Hono handlers are invoked with:

  1. ctx: Hono context
  2. clearRequest: ClearRequest | undefined
javascript
Router.post('/users', (ctx, clearRequest) => {
  return {
    method: ctx.req.method,
    hasClearRequest: Boolean(clearRequest),
  };
});

For controller instance handlers ([ControllerClass, 'method']), router hydration includes:

  • this.body (from ctx.req.getBody())
  • this.query (query params)
  • this.params (route params)
  • this.clearRequest (normalized request wrapper)

API Resource Binding ​

javascript
class UserController {
  index() {
    return [{ name: 'User 1' }, { name: 'User 2' }];
  }
  show() {
    return { name: 'User 1' };
  }
  create() {
    return 'User created';
  }
  update() {
    return 'User updated';
  }
  destroy() {
    return 'User deleted';
  }
}

Router.apiResource('/users', UserController);

Grouped Routes ​

javascript
await Router.group('/admin', () => {
  Router.get('/dashboard', () => 'Admin Panel');
});

File, directory, and mixed source groups are supported:

javascript
await Router.group('/api', [
  'routes/users.ts',
  'routes/posts',
  () => Router.get('/status', () => ({ ok: true })),
]);

await Router
  .group('/secure', 'routes/secure')
  .middleware(authMiddleware)
  .when(() => secureRoutesEnabled);

Global Middleware Scope ​

javascript
Router.middleware([authMiddleware], () => {
  Router.get('/profile', () => 'My Profile');
});

Multiple HTTP Methods ​

javascript
Router.add(['get', 'post'], '/handle', ({ req }) => {
  return `Method: ${req.method}`;
});

Inspecting Routes ​

javascript
Router.get('/hello', () => 'Hello');
Router.post('/world', () => 'World');

const allRoutes = Router.allRoutes();
console.log(allRoutes);

API Reference ​

See API for complete API documentation.

Testing ​

bash
npm test
npm run test:ts

See Testing for detailed testing guide.