Hono Next
Directory Structure
.
├── app
│ ├── api
│ │ └── [...route]
│ │ └── route.ts
│ ├── layout.tsx
│ └── page.tsx
├── package.json
└── tsconfig.json
sh
npm install next@latest react@latest react-dom@latest hono
sh
npm install -D @types/node @types/react typescript
app/api/[...route]/route.ts
ts
import { Hono } from 'hono'
import { hc } from 'hono/client'
import { handle } from 'hono/vercel'
const app = new Hono().basePath('/api')
const api = app.get('/hello', async (c) => {
return c.json({
message: 'Hono🔥 Next',
})
})
type AddType = typeof api
export const client = hc<AddType>('/').api
export const GET = handle(app)
Zod OpenAPI
ts
import { createRoute, OpenAPIHono, z } from '@hono/zod-openapi'
import { swaggerUI } from '@hono/swagger-ui'
import { hc } from 'hono/client'
import { handle } from 'hono/vercel'
const app = new OpenAPIHono().basePath('/api')
export const helloSchema = z.object({
message: z.string().openapi({
example: 'Hono🔥 Next',
}),
})
const route = createRoute({
method: 'get',
path: '/hello',
responses: {
200: {
content: {
'application/json': {
schema: helloSchema,
},
},
description: 'Hono🔥 Next',
},
},
})
const api = app.openapi(route, (c) => {
return c.json({ message: 'Hono🔥 Next' })
})
app.get('/ui', swaggerUI({ url: '/api/doc' }))
app.doc('/doc', {
info: {
title: 'Hono API',
version: 'v1',
},
openapi: '3.1.0',
})
type AddType = typeof api
export const client = hc<AddType>('/').api
export const GET = handle(app)
app/page.tsx
tsx
'use client'
import { useState } from 'react'
import { client } from './api/[...route]/route'
export default function Home() {
const [message, setMessage] = useState('')
const onSubmit = async () => {
const res = await client.hello.$get()
const data = await res.json()
setMessage(data.message)
}
return (
<>
<h1>Hono🔥 Next</h1>
<button type='button' onClick={onSubmit}>
Get Message
</button>
<h1>{message}</h1>
</>
)
}