mirror of
https://github.com/honojs/hono.git
synced 2024-11-24 11:07:29 +01:00
docs: rename master
to main
and remove README from middlewre directories (#405)
* chore: add conf file to categorize the PRs on release note Inspired by https://github.com/r7kamura/github-label-presets * docs: rename `master` to `main` and remove README from middlewre directories If you want read the document about the middleware, please refer to the website <https://honojs.dev/>
This commit is contained in:
parent
bcc9818395
commit
7738c99062
@ -1,6 +1,6 @@
|
||||
<div align="center">
|
||||
<a href="https://honojs.dev">
|
||||
<img src="https://raw.githubusercontent.com/honojs/hono/master/docs/images/hono-title.png" width="500" height="auto" alt="Hono"/>
|
||||
<img src="https://raw.githubusercontent.com/honojs/hono/main/docs/images/hono-title.png" width="500" height="auto" alt="Hono"/>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@ -14,12 +14,12 @@
|
||||
<hr />
|
||||
|
||||
[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/honojs/hono/ci)](https://github.com/honojs/hono/actions)
|
||||
[![GitHub](https://img.shields.io/github/license/honojs/hono)](https://github.com/honojs/hono/blob/master/LICENSE)
|
||||
[![GitHub](https://img.shields.io/github/license/honojs/hono)](https://github.com/honojs/hono/blob/main/LICENSE)
|
||||
[![npm](https://img.shields.io/npm/v/hono)](https://www.npmjs.com/package/hono)
|
||||
[![npm](https://img.shields.io/npm/dm/hono)](https://www.npmjs.com/package/hono)
|
||||
[![npm type definitions](https://img.shields.io/npm/types/hono)](https://www.npmjs.com/package/hono)
|
||||
[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/honojs/hono)](https://github.com/honojs/hono/pulse)
|
||||
[![GitHub last commit](https://img.shields.io/github/last-commit/honojs/hono)](https://github.com/honojs/hono/commits/master)
|
||||
[![GitHub last commit](https://img.shields.io/github/last-commit/honojs/hono)](https://github.com/honojs/hono/commits/main)
|
||||
[![Deno badge](https://img.shields.io/endpoint?url=https%3A%2F%2Fdeno-visualizer.danopia.net%2Fshields%2Flatest-version%2Fx%2Fhono%2Fmod.ts)](https://doc.deno.land/https/deno.land/x/hono/mod.ts)
|
||||
|
||||
Hono - _**[炎] means flame🔥 in Japanese**_ - is a small, simple, and ultrafast web framework for Cloudflare Workers, Deno, Bun, and others.
|
||||
|
@ -1,47 +0,0 @@
|
||||
# Basic Auth Middleware
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
import { Hono } from 'hono'
|
||||
import { basicAuth } from 'hono/basic-auth'
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
app.use(
|
||||
'/auth/*',
|
||||
basicAuth({
|
||||
username: 'hono',
|
||||
password: 'acoolproject',
|
||||
})
|
||||
)
|
||||
|
||||
app.get('/auth/page', (c) => {
|
||||
return c.text('You are authorized')
|
||||
})
|
||||
|
||||
app.fire()
|
||||
```
|
||||
|
||||
For Fastly Compute@Edge, polyfill `crypto` or use `crypto-js`.
|
||||
|
||||
Install:
|
||||
|
||||
```
|
||||
npm i crypto-js
|
||||
```
|
||||
|
||||
Override `hashFunction`:
|
||||
|
||||
```js
|
||||
import { SHA256 } from 'crypto-js'
|
||||
|
||||
app.use(
|
||||
'/auth/*',
|
||||
basicAuth({
|
||||
username: 'hono',
|
||||
password: 'acoolproject',
|
||||
hashFunction: (d: string) => SHA256(d).toString(), // <---
|
||||
})
|
||||
)
|
||||
```
|
@ -1,34 +0,0 @@
|
||||
# Bearer Auth Middleware
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
import { Hono } from 'hono'
|
||||
import { bearerAuth } from 'hono/bearer-auth'
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
const token = 'honoisacool'
|
||||
|
||||
app.use('/auth/*', bearerAuth({ token }))
|
||||
|
||||
app.get('/auth/page', (c) => {
|
||||
return c.text('You are authorized')
|
||||
})
|
||||
|
||||
app.fire()
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
```ts
|
||||
app.use(
|
||||
'/auth/*',
|
||||
bearerAuth({
|
||||
token: 'honoisacool', // Required
|
||||
realm: 'example.com',
|
||||
prefix: 'Bot'
|
||||
hashFunction: (d: string) => SHA256(d).toString(), // For Fastly Compute@Edge
|
||||
})
|
||||
)
|
||||
```
|
@ -1,29 +0,0 @@
|
||||
# CORS Middleware
|
||||
|
||||
## Usage
|
||||
|
||||
index.js:
|
||||
|
||||
```js
|
||||
const app = new Hono()
|
||||
|
||||
app.use('/api/*', cors())
|
||||
app.use(
|
||||
'/api2/*',
|
||||
cors({
|
||||
origin: 'http://example.com',
|
||||
allowHeaders: ['X-Custom-Header', 'Upgrade-Insecure-Requests'],
|
||||
allowMethods: ['POST', 'GET', 'OPTIONS'],
|
||||
exposeHeaders: ['Content-Length', 'X-Kuma-Revision'],
|
||||
maxAge: 600,
|
||||
credentials: true,
|
||||
})
|
||||
)
|
||||
|
||||
app.all('/api/abc', (c) => {
|
||||
return c.json({ success: true })
|
||||
})
|
||||
app.all('/api2/abc', (c) => {
|
||||
return c.json({ success: true })
|
||||
})
|
||||
```
|
@ -1,16 +0,0 @@
|
||||
# ETag Middleware
|
||||
|
||||
## Usage
|
||||
|
||||
index.js:
|
||||
|
||||
```js
|
||||
const app = new Hono()
|
||||
|
||||
app.use('/etag/*', etag())
|
||||
app.get('/etag/abc', (c) => {
|
||||
return c.text('Hono is cool')
|
||||
})
|
||||
|
||||
app.fire()
|
||||
```
|
@ -1,153 +0,0 @@
|
||||
# html Middleware
|
||||
|
||||
html Middleware provides `html` method for building HTML.
|
||||
|
||||
## Usage
|
||||
|
||||
index.ts:
|
||||
|
||||
```ts
|
||||
import { Hono } from 'hono'
|
||||
import { html } from 'hono/html'
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
app.get('/:username', (c) => {
|
||||
const { username } = c.req.param()
|
||||
return c.html(
|
||||
html`<!DOCTYPE html>
|
||||
<h1>Hello! ${username}!</h1>`
|
||||
)
|
||||
})
|
||||
|
||||
app.fire()
|
||||
```
|
||||
|
||||
### Insert snippet into JSX
|
||||
|
||||
```typescript
|
||||
const snippet = html`
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=MEASUREMENT_ID"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || []
|
||||
function gtag() {
|
||||
dataLayer.push(arguments)
|
||||
}
|
||||
gtag('js', new Date())
|
||||
|
||||
gtag('config', 'MEASUREMENT_ID')
|
||||
</script>
|
||||
`
|
||||
|
||||
app.get('/', (c) => {
|
||||
return c.render(
|
||||
<html>
|
||||
<head>
|
||||
<title>Test Site</title>
|
||||
{snippet}
|
||||
</head>
|
||||
<body>Hello!</body>
|
||||
</html>
|
||||
)
|
||||
})
|
||||
```
|
||||
|
||||
### Insert inline script into JSX
|
||||
|
||||
```typescript
|
||||
app.get('/', (c) => {
|
||||
return c.render(
|
||||
<html>
|
||||
<head>
|
||||
<title>Test Site</title>
|
||||
{html`
|
||||
<script>
|
||||
// No need to use dangerouslySetInnerHTML. If you write it here, it will not be escaped.
|
||||
</script>
|
||||
`}
|
||||
</head>
|
||||
<body>Hello!</body>
|
||||
</html>
|
||||
)
|
||||
})
|
||||
```
|
||||
|
||||
### Act as functional component
|
||||
|
||||
Since `html` returns an HtmlEscapedString, it can act as a fully functional component without using JSX.
|
||||
|
||||
#### Use `html` to speed up the process instead of `memo`
|
||||
|
||||
```typescript
|
||||
const Footer = () => html`
|
||||
<footer>
|
||||
<address>My Address...</address>
|
||||
</footer>
|
||||
`
|
||||
```
|
||||
|
||||
### Receives props and embeds values
|
||||
|
||||
```typescript
|
||||
interface SiteData {
|
||||
title: string
|
||||
description: string
|
||||
image: string
|
||||
children?: any
|
||||
}
|
||||
const Layout = (props: SiteData) => html`
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>${props.title}</title>
|
||||
<meta name="description" content="${props.description}">
|
||||
<head prefix="og: http://ogp.me/ns#">
|
||||
<meta property="og:type" content="article">
|
||||
<!-- More elements slow down JSX, but not template literals. -->
|
||||
<meta property="og:title" content="${props.title}">
|
||||
<meta property="og:image" content="${props.image}">
|
||||
</head>
|
||||
<body>
|
||||
${props.children}
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
const Content = (props: { siteData: SiteData; name: string }) => (
|
||||
<Layout {...props.siteData}>
|
||||
<h1>Hello {props.name}</h1>
|
||||
</Layout>
|
||||
)
|
||||
|
||||
app.get('/', (c) => {
|
||||
const props = {
|
||||
name: 'World',
|
||||
siteData: {
|
||||
title: 'Hello <> World',
|
||||
description: 'This is a description',
|
||||
image: 'https://example.com/image.png',
|
||||
},
|
||||
}
|
||||
return c.render(<Content {...props} />)
|
||||
})
|
||||
```
|
||||
|
||||
## raw
|
||||
|
||||
Using `raw`, the content will be rendered as is. You have to escape these strings by yourself.
|
||||
|
||||
```ts
|
||||
import { html, raw } from 'hono/html'
|
||||
|
||||
app.get('/', (c) => {
|
||||
const name = 'John "Johnny" Smith'
|
||||
return c.html(html`<p>I'm ${raw(name)}.</p>`)
|
||||
})
|
||||
```
|
||||
|
||||
## Tips
|
||||
|
||||
Thanks to these libraries, Visual Studio Code and vim also interprets template literals as HTML, allowing syntax highlighting and formatting to be applied.
|
||||
|
||||
- <https://marketplace.visualstudio.com/items?itemName=bierner.lit-html>
|
||||
- <https://github.com/MaxMEllon/vim-jsx-pretty>
|
@ -1,170 +0,0 @@
|
||||
# JSX Middleware
|
||||
|
||||
JSX Middleware enable rendering HTML with JSX syntax.
|
||||
It's just for Sever-Side-Rendering. No virtual DOM.
|
||||
This middleware is only for writing with TypeScript.
|
||||
|
||||
## Settings
|
||||
|
||||
tsconfig.json:
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"jsx": "react",
|
||||
"jsxFactory": "jsx",
|
||||
"jsxFragmentFactory": "Fragment"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
index.tsx:
|
||||
|
||||
```tsx
|
||||
import { Hono } from 'hono'
|
||||
import { jsx } from 'hono/jsx'
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
const Layout = (props: { children?: string }) => {
|
||||
return (
|
||||
<html>
|
||||
<body>{props.children}</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
|
||||
const Top = (props: { messages: string[] }) => {
|
||||
return (
|
||||
<Layout>
|
||||
<h1>Hello Hono!</h1>
|
||||
<ul>
|
||||
{props.messages.map((message) => {
|
||||
return <li>{message}!!</li>
|
||||
})}
|
||||
</ul>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
app.get('/', (c) => {
|
||||
const messages = ['Good Morning', 'Good Evening', 'Good Night']
|
||||
return c.html(<Top messages={messages} />)
|
||||
})
|
||||
|
||||
app.fire()
|
||||
```
|
||||
|
||||
## dangerouslySetInnerHTML
|
||||
|
||||
`dangerouslySetInnerHTML` allows you to set HTML directly.
|
||||
|
||||
```tsx
|
||||
app.get('/foo', (c) => {
|
||||
const inner = { __html: 'JSX · SSR' }
|
||||
const Div = <div dangerouslySetInnerHTML={inner} />
|
||||
})
|
||||
```
|
||||
|
||||
## memo
|
||||
|
||||
You can memorize calculated strings of the component with `memo`.
|
||||
|
||||
```tsx
|
||||
import { jsx, memo } from 'hono/jsx'
|
||||
|
||||
const Header = memo(() => <header>Welcome to Hono</header>)
|
||||
const Footer = memo(() => <footer>Powered by Hono</footer>)
|
||||
const Layout = (
|
||||
<div>
|
||||
<Header />
|
||||
<p>Hono is cool!</p>
|
||||
<Footer />
|
||||
</div>
|
||||
)
|
||||
```
|
||||
|
||||
## Fragment
|
||||
|
||||
```tsx
|
||||
import { jsx, Fragment } from 'hono/jsx'
|
||||
|
||||
const List = () => (
|
||||
<Fragment>
|
||||
<p>first child</p>
|
||||
<p>second child</p>
|
||||
<p>third child</p>
|
||||
</Fragment>
|
||||
)
|
||||
```
|
||||
|
||||
## With html Middleware
|
||||
|
||||
It's powerful to use JSX middleware with html middleware.
|
||||
For more information, see [html middleware docs](https://github.com/honojs/hono/tree/master/src/middleware/html).
|
||||
|
||||
```tsx
|
||||
import { Hono } from 'hono'
|
||||
import { html } from 'hono/html'
|
||||
import { jsx } from 'hono/jsx'
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
interface SiteData {
|
||||
title: string
|
||||
children?: any
|
||||
}
|
||||
|
||||
const Layout = (props: SiteData) => html`<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>${props.title}</title>
|
||||
</head>
|
||||
<body>
|
||||
${props.children}
|
||||
</body>
|
||||
</html>`
|
||||
|
||||
const Content = (props: { siteData: SiteData; name: string }) => (
|
||||
<Layout {...props.siteData}>
|
||||
<h1>Hello {props.name}</h1>
|
||||
</Layout>
|
||||
)
|
||||
|
||||
app.get('/:name', (c) => {
|
||||
const { name } = c.req.param()
|
||||
const props = {
|
||||
name: name,
|
||||
siteData: {
|
||||
title: 'JSX with html sample',
|
||||
},
|
||||
}
|
||||
return c.html(<Content {...props} />)
|
||||
})
|
||||
|
||||
app.fire()
|
||||
```
|
||||
|
||||
## Tips for Cloudflare Workers
|
||||
|
||||
It's useful to use Miniflare's`live-reload` option for developing.
|
||||
|
||||
package.json:
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"build": "esbuild --bundle --outdir=dist ./src/index.tsx",
|
||||
"dev": "miniflare --live-reload --debug"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
wrangler.toml:
|
||||
|
||||
```toml
|
||||
[build]
|
||||
command = "yarn build"
|
||||
```
|
@ -1,23 +0,0 @@
|
||||
# JWT Middleware
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
import { Hono } from 'hono'
|
||||
import { jwt } from 'hono/jwt'
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
app.use(
|
||||
'/auth/*',
|
||||
jwt({
|
||||
secret: 'it-is-very-secret'
|
||||
})
|
||||
)
|
||||
|
||||
app.get('/auth/page', (c) => {
|
||||
return c.text('You are authorized')
|
||||
})
|
||||
|
||||
app.fire()
|
||||
```
|
@ -1,17 +0,0 @@
|
||||
# Logger Middleware
|
||||
|
||||
## Usage
|
||||
|
||||
index.js:
|
||||
|
||||
```js
|
||||
import { Hono } from 'hono'
|
||||
import { logger } from 'hono/logger'
|
||||
|
||||
export const app = new Hono()
|
||||
|
||||
app.use('*', logger())
|
||||
app.get('/', (c) => c.text('Hello Hono!'))
|
||||
|
||||
app.fire()
|
||||
```
|
@ -1,56 +0,0 @@
|
||||
# Serve Static Middleware
|
||||
|
||||
Serve Static Middleware is available only on Cloudflare Workers.
|
||||
|
||||
## Usage
|
||||
|
||||
index.ts:
|
||||
|
||||
```ts
|
||||
import { Hono } from 'hono'
|
||||
import { serveStatic } from 'hono/serve-static'
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
app.use('/static/*', serveStatic({ root: './' }))
|
||||
app.get('/', (c) => c.text('This is Home! You can access: /static/hello.txt'))
|
||||
app.get('*', serveStatic({ path: './static/fallback.txt' }))
|
||||
|
||||
app.fire()
|
||||
```
|
||||
|
||||
In Module Worker mode:
|
||||
|
||||
```ts
|
||||
import { Hono } from 'hono'
|
||||
import { serveStatic } from 'hono/serve-static.module' // <---
|
||||
|
||||
const app = new Hono()
|
||||
//...
|
||||
|
||||
export default app
|
||||
```
|
||||
|
||||
wrangler.toml:
|
||||
|
||||
```toml
|
||||
[site]
|
||||
bucket = "./assets"
|
||||
```
|
||||
|
||||
Asset files:
|
||||
|
||||
```
|
||||
./assets
|
||||
└── static
|
||||
├── demo
|
||||
│ └── index.html
|
||||
├── hello.txt
|
||||
├── fallback.txt
|
||||
└── images
|
||||
└── dinotocat.png
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
<https://github.com/honojs/examples/tree/master/serve-static>
|
Loading…
Reference in New Issue
Block a user