Fastify HTML/HTMX plugin
Generate html in the most natural Fastify way, using template tags,
layouts and the plugin system.
Template expressions are escaped by default unless they are prefixed with !.
``bash`
npm i fastify fastify-html
`js
import fastify from 'fastify'
import fastifyHtml from 'fastify-html'
const app = fastify()
await app.register(fastifyHtml)
app.addLayout(function (inner, reply) {
return app.html
}, { skipOnHeader: 'hx-request' })app.get('/', async (req, reply) => {
const name = req.query.name || 'World'
return reply.html
})app.get('/complex-response/:page', async (req, reply) => {
const name = req.query.name || 'World'
const userInfo = await getUserInfo(name) || {}
const demand = req.query.demand
return reply.html
User information:
!${Object.keys(userInfo).map(
(key) => app.html
${key}: ${userInfo[key]}
)}
!${ Your demand: ${demand}
demand
? app.html
: ""
}
})await app.listen({ port: 3000 })
async function getUserInfo(name) {
return { age: 25, location: "Earth" };
}
`Async Mode Usage
`js
import fastify from 'fastify'
import fastifyHtml from 'fastify-html'
import { createReadStream } from 'node:fs'const app = fastify()
await app.register(fastifyHtml, { async: true })
app.addLayout(function (inner, reply) {
return app.html
}, { skipOnHeader: 'hx-request' })app.get('/:name', async (req, reply) => {
return reply.html
User information:
!${getUserInfoPromise(req.params.name)}
})await app.listen({ port: 3000 })
async function getUserInfoPromise(name) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ age: 25, location: "Earth" });
}, 1000);
});
}
`$3
Encapsulation is supported and respected for layouts, meaning that
addLayout
calls will be not exposed to the parent plugin, like the following:`js
import fastify from 'fastify'
import fastifyHtml from 'fastify-html'const app = fastify()
await app.register(fastifyHtml)
app.addLayout(function (inner, reply) {
return app.html
})app.get('/', async (req, reply) => {
const name = req.query.name || 'World'
strictEqual(reply.html
, reply)
return reply
})app.register(async function (app) {
app.addLayout(function (inner) {
return app.html
}) app.get('/nested', async (req, reply) => {
const name = req.query.name || 'World'
return reply.html
})
})await app.listen({ port: 3000 })
`Options
-
async`: Enables async mode for handling asynchronous template expressions. Set this option to true when registering the fastify-html plugin to take advantage of features like promise resolution, stream handling, and async generator support.MIT