Skip to content

HTML

@vafast/html 在请求上挂载 req.html,提供 html() / stream(),配合 @kitajs/html 返回 HTML。

不要直接 return HTML 字符串

框架会把普通 string 当成 text/plain。必须 return req.html.html(...)(或自行构造 Content-Type: text/htmlResponse)。

安装

bash
npm install @vafast/html

快速开始

typescript
import { Server, defineRoute, defineRoutes, serve } from 'vafast'
import { html } from '@vafast/html'

type HtmlRequest = Request & {
  html: {
    html: (value: string | JSX.Element) => Response | string | Promise<Response | string>
  }
}

const routes = defineRoutes([
  defineRoute({
    method: 'GET',
    path: '/',
    handler: ({ req }) => {
      return (req as HtmlRequest).html.html(`
        <!doctype html>
        <html>
          <body><h1>Hello</h1></body>
        </html>
      `)
    },
  }),
])

const server = new Server(routes)
server.use(html())
serve({ fetch: server.fetch, port: 3000 })

用法

全局挂载

typescript
server.use(html())
// 路由里仍须调用 req.html.html(...)

路由级挂载

typescript
defineRoute({
  method: 'GET',
  path: '/page',
  middleware: [html()],
  handler: ({ req }) => (req as HtmlRequest).html.html('<html><body>Hi</body></html>'),
})

req.html.html(value)

渲染字符串 / JSX,返回带 content-typeResponse。若 autoDoctype 开启且内容以 <html 开头,会自动加 <!doctype html>

req.html.stream(fn, args)

基于 @kitajs/html/suspense 的流式渲染:

typescript
handler: ({ req }) => {
  return (req as HtmlRequest & {
    html: {
      stream: (
        fn: (arg: { id: number; title: string }) => JSX.Element,
        args: { title: string },
      ) => Response | Promise<Response>
    }
  }).html.stream(
    ({ id, title }) => `<html><body><h1>${title} #${id}</h1></body></html>`,
    { title: 'Stream' },
  )
}

自动检测(autoDetect

默认开启:若下游 Response 已是 text/html,会统一改写为配置的 contentType

不会把 handler 返回的普通字符串魔法转成 HTML。

其它导出

typescript
import {
  html,           // createHtmlPlugin 别名
  createHtmlPlugin,
  Html,           // @kitajs/html
  createElement,
  ErrorBoundary,
  isHtml,
} from '@vafast/html'

API完整参数

html(options?) / createHtmlPlugin(options?)

typescript
html(options?: HtmlOptions): Middleware

HtmlOptions

参数类型默认说明
contentTypestring'text/html; charset=utf8'HTML 响应 Content-Type
autoDetectbooleantrue下游已是 HTML Response 时统一 content-type
autoDoctypeboolean | 'full'true对经 html() / stream() 渲染、且以 <html 开头的内容前置 doctype
isHtml(value: string) => boolean内置 isHtml字符串是否像 HTML(长度≥7、以 < 开头、以 > 结尾)

req.html 方法

方法说明
html(value)value: 字符串 / Readable / JSX;返回 HTML Response
stream(fn, args)fn 接收 args & { id },流式渲染

最佳实践

  • 一律 return req.html.html(...),不要 return '<html>...'
  • SSR / 大页面优先考虑 stream
  • JSX 项目配合 @kitajs/html 与 TypeScript JSX 配置
  • 全局 server.use(html()) 一次即可,避免重复挂载

注意事项

  • 字符串返回值 = text/plain,这是框架行为,不是 bug
  • autoDoctype: 'full' 在类型注释里表示「无插件返回也加 doctype」,当前中间件主路径对普通 string 返回不会自动转换;请始终走 req.html.html()
  • autoDetect 只处理已是 HTML 的 Response,不改变 plain text
  • 中间件把对象挂到 (req as any).html;TypeScript 侧建议自建 HtmlRequest 类型

相关链接