Hono
This guide shows how to add Zero Ad Network to an existing Hono application. If you haven't installed the package yet, start with the Node.js setup guide.
Add the middleware
Create a typed middleware that injects the partner header and stores tokenContext in Hono's context variables:
src/middleware/zeroad.ts
import { createMiddleware } from "hono/factory"
import { Site, FEATURE } from "@zeroad.network/token"
const site = Site({
clientId: "YOUR_CLIENT_ID", // from zeroad.network/publisher/sites
features: [FEATURE.CLEAN_WEB], // or FEATURE.ONE_PASS, or both
})
export type TokenContext = ReturnType<typeof site.parseClientToken>
export const zeroad = createMiddleware<{ Variables: { tokenContext: TokenContext } }>(
async (c, next) => {
c.header(site.SERVER_HEADER_NAME, site.SERVER_HEADER_VALUE)
c.set("tokenContext", site.parseClientToken(c.req.header(site.CLIENT_HEADER_NAME)))
await next()
}
)
src/app.ts
import { Hono } from "hono"
import { zeroad, TokenContext } from "./middleware/zeroad.js"
const app = new Hono<{ Variables: { tokenContext: TokenContext } }>()
app.use(zeroad)
Use the feature flags
c.get("tokenContext") is available in every route handler. Use the flags to tailor the response - non-subscribers get false for all flags and see the site as normal.
app.get("/article/:slug", async (c) => {
const article = await db.getArticle(c.req.param("slug"))
const { DISABLE_CONTENT_PAYWALL, HIDE_ADVERTISEMENTS } = c.get("tokenContext")
return c.json({
title: article.title,
content: DISABLE_CONTENT_PAYWALL ? article.fullContent : article.excerpt,
isPaywalled: !DISABLE_CONTENT_PAYWALL,
showAds: !HIDE_ADVERTISEMENTS,
})
})
Full working example
A minimal Hono app (running on Bun) with the integration wired up end-to-end:
src/app.ts
import { Hono } from "hono"
import { Site, FEATURE } from "@zeroad.network/token"
const site = Site({
clientId: "YOUR_CLIENT_ID",
features: [FEATURE.CLEAN_WEB, FEATURE.ONE_PASS],
})
type TokenContext = ReturnType<typeof site.parseClientToken>
const app = new Hono<{ Variables: { tokenContext: TokenContext } }>()
app.use(async (c, next) => {
c.header(site.SERVER_HEADER_NAME, site.SERVER_HEADER_VALUE)
c.set("tokenContext", site.parseClientToken(c.req.header(site.CLIENT_HEADER_NAME)))
await next()
})
app.get("/", (c) => {
const { HIDE_ADVERTISEMENTS, DISABLE_CONTENT_PAYWALL } = c.get("tokenContext")
return c.json({ HIDE_ADVERTISEMENTS, DISABLE_CONTENT_PAYWALL })
})
Bun.serve({ fetch: app.fetch, port: 3000 })
Full runnable examples for Hono and other frameworks are in the GitHub examples directory.
What the flags mean
See the tokenContext reference for the full flag list and when each one is true.