hono-jsx-router v1.5.0
JSXRouter
JSXRouter is a file-based router for Hono.js with the JSX middleware.
Table of Contents
Installation
npm i --save hono-jsx-routerUsage
import { Hono } from 'hono';
import { JSXRouter } from 'hono-jsx-router';
const jsxRouter: JSXRouter<any> = new JSXRouter({
config: {
// JSXRouter config
}
});
const app = new Hono({
router: jsxRouter
});
jsxRouter.applyRoutes();Config
package.json:
{
//...
"scripts": {
"build": "npx jsx-combine"
},
"dependencies": {
"hono": "^3.2.0",
"hono-jsx-router": "^1.3.0"
},
"jsxRouter": {
"path": "src/routes"
}
}index.ts:
import { Hono } from 'hono';
import { JSXRouter } from 'hono-jsx-router';
const jsxRouter: JSXRouter<any> = new JSXRouter({
config: {
layout: {
// layout config
props: {
// props that can be passed to layouts
}
},
page: {
// page config
props: {
// props that can be passed to pages
}
}
}
});
const app = new Hono({
router: jsxRouter
});
jsxRouter.applyRoutes();The props object can take strings or functions as values. If the value is a function, the Context object is passed to it.
Pages
In the directory configured as path in your package.json, place JSX files (.tsx). If you configure path to be ./src/routes, then JSXRouter will serve the files found there, The names should reflect the desired route. For example, if you have a file called about.tsx, and you are using JSXRouter at / of your site, this file will be served at /about.
Subfolders
You can have multiple folders as needed, for when you need multiple subpages under /about, you can create an about folder and put as many subpages there that you need.
Wildcards
You can also add files that has a wildcard in its name to catch all routes that aren't handled by sibling files. So you can have a directory structure like:
src/routes/about/
./index.tsx
./other_page.tsx
./*.tsxYou will end up with routes to /about/, /about/other_page/, and /about/*. The wildcard does not override the other two routes here.
Layout
You can provide a common layout in a file called _layout.tsx. This will be used to wrap every page in the directory. Here is an example layout:
import { html } from 'hono/html';
export default (props: { children?: any }) => {
return html`<!DOCTYPE html>
<html lang="EN-US">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width" />
<meta name="theme-color" media="(prefers-color-scheme: light)" content="lightgray" />
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="gray" />
<title>Example Site</title>
<link rel="icon" href="/favicon.svg" sizes="any" type="image/svg+xml" />
</head>
<body>${props.children}</body>
</html>`;
};It is recommended to create a components directory alongside your routes directory, placing JSX files there to be imported into your pages. For example, say you have src/components/Header.tsx, it could contain something like this:
export default (props: { children?: any }) => {
return (
<header>
<a href="/">Home</a>
<a href="/about">About</a>
<a href="/blog">Blog</a>
</header>
)
}Then you can use it in a page, like src/routes/index.tsx:
import Header from '../components/Header';
export default (props: {}) => {
return (<>
<Header />
<h1>Home</h1>
<p>Hello world!</p>
</>)
};Context
Each page has access to Hono's Context object via props. Declare it like this to use it:
import type { Context } from 'hono';
export default (props: { c: Context }) => {
// ...
};Fallback Routers
When using the basic import of JSXRouter, it will use Hono's LinearRouter to handle routes not found in the file structure. You can pick a different router depending on your use case by importing from one of the presets:
- LinearRouter:
import { JSXRouter } from 'hono-jsx-router/linear'; - PatternRouter:
import { JSXRouter } from 'hono-jsx-router/pattern'; - RegExpRouter:
import { JSXRouter } from 'hono-jsx-router/reg-exp'; - SmartRouter*:
import { JSXRouter } from 'hono-jsx-router/smart'; - TrieRouter:
import { JSXRouter } from 'hono-jsx-router/trie';
*When using the SmartRouter, you will need to specify the routers it should pick from:
import { Hono } from 'hono';
import { JSXRouter } from 'hono-jsx-router/smart';
const jsxRouter: JSXRouter<any> = new JSXRouter({
config: {
// JSXRouter config
},
routers: [
new RegExpRouter(),
new TrieRouter()
]
});Query Parameters
A JSX page can receive query parameters. To access them, add params to your props argument, like below:
export default (props: { params:? Record<string, string[]> }) => {
//...
};Then you can access the query parameters anywhere in the page. For example, if a user browses to /?foo=bar&abc=xyz, you can access these query parameters like so:
export default (props: { params:? Record<string, string[]> }) => {
return (<>
<h1>Home</h1>
<p>Hello world!</p>
<p>You query for foo is {props.params.foo[0]} and your query for abc is {props.params.abc[0]}.</p>
</>)
};This will result in the following HTML:
<h1>Home</h1>
<p>Hello world!</p>
<p>You query for foo is bar and your query for abc is xyz.</p>Since the params are string arrays (string[]), if there are multiple instances of a key in a query, all of the values can be accessed in order by index. Internally, this uses HonoRequest.queries().
Known Issues
- Need to add a way to set per page
<head>attributes. - Subfolder layouts are not currently supported, but is a planned feature.
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago