new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Hono · all subjects

helpers/ssg

24 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Status code filter plugin example

To filter by status code in SSG generation: const statusFilterPlugin: SSGPlugin = { afterResponseHook: (res) => { if (res.status === 200 || res.status === 500) { return res } return false } }

toSSG main function signature and arguments

toSSG is the main function for generating static sites. It takes three arguments: app (a Hono instance with registered routes), fsModule (a filesystem module implementing FileSystemModule interface with writeFile and mkdir methods), and an optional ToSSGOptions object. It returns a Promise that resolves to ToSSGResult.

FileSystemModule interface specification

FileSystemModule must implement two methods: writeFile(path: string, data: string | Uint8Array): Promise<void> and mkdir(path: string, options: { recursive: boolean }): Promise<void | string>. This interface is compatible with Node.js fs/promises module.

ToSSGOptions interface

ToSSGOptions is an optional configuration object with the following properties: dir (string, default './static') for output destination; concurrency (number, default 2) for concurrent files generated at once; extensionMap (Record<string, string>) mapping Content-Type to file extension; plugins (array of SSGPlugin) for extending functionality.

ToSSGResult return type

toSSG returns a ToSSGResult object containing: success (boolean), files (string array of generated file paths), and an optional error (Error) property.

Route to filename conversion rules

Static file generation follows these rules: '/' converts to './static/index.html', '/path' converts to './static/path.html', '/path/' (with trailing slash) converts to './static/path/index.html'.

File extension determination for SSG

File extension is determined by the Content-Type returned by each route. Responses from c.html() are saved as .html. Paths ending with a slash are always saved as index.ext regardless of the extension, such as './static/html/index.html' for '/html/' returning c.html().

ssgParams middleware for dynamic routes

ssgParams is a middleware that enables an API similar to Next.js generateStaticParams. It takes an async function that returns an array of parameter objects. Example: ssgParams(async () => { const shops = await getShops(); return shops.map((shop) => ({ id: shop.id })) }) generates static pages for '/shops/:id' with each shop id.

isSSGContext helper function

isSSGContext(c) returns true if the current application is running within the SSG context triggered by toSSG. This allows conditional logic to differentiate between static generation and dynamic serving.

disableSSG middleware

Routes wrapped with the disableSSG() middleware are excluded from static file generation by toSSG. Example: app.get('/api', disableSSG(), (c) => c.text('an-api')) prevents the /api route from being generated as a static file.

onlySSG middleware

Routes wrapped with the onlySSG() middleware will be overridden by c.notFound() after toSSG execution completes. This ensures the route only exists as a static file and is not available at runtime. Example: app.get('/static-page', onlySSG(), (c) => c.html(<h1>Welcome to my site</h1>))

defaultPlugin behavior

defaultPlugin is automatically applied by toSSG when no custom plugins are specified. It skips non-200 status responses like redirects, errors, and 404s, preventing file generation for unsuccessful responses.

defaultPlugin with custom plugins

When custom plugins are specified, defaultPlugin is not automatically included. To maintain default behavior while adding custom plugins, explicitly include defaultPlugin in the plugins array: toSSG(app, fs, { plugins: [defaultPlugin, myCustomPlugin] })

redirectPlugin for HTTP redirects

redirectPlugin generates HTML redirect pages for routes returning HTTP redirect responses (status codes 301, 302, 303, 307, 308). The generated HTML includes a <meta http-equiv="refresh"> tag and a canonical link. When used with defaultPlugin, redirectPlugin must be placed before defaultPlugin in the plugins array to prevent defaultPlugin from skipping redirect responses.

SSGPlugin hook types

Plugins can use three hook types: BeforeRequestHook (called before processing each request, returns Request or false), AfterResponseHook (called after receiving each response, returns Response or false), and AfterGenerateHook (called after entire generation process completes, returns void or Promise<void>).

SSGPlugin interface

SSGPlugin interface has three optional properties: beforeRequestHook (BeforeRequestHook or array of BeforeRequestHook), afterResponseHook (AfterResponseHook or array of AfterResponseHook), and afterGenerateHook (AfterGenerateHook or array of AfterGenerateHook).

Deno toSSG adapter

For Deno, import toSSG from 'hono/deno'. The function signature is toSSG(app, options?) where options is typed as ToSSGOptions. The filesystem argument is handled automatically by the adapter.

Bun toSSG adapter

For Bun, import toSSG from 'hono/bun'. The function signature is toSSG(app, options?) where options is typed as ToSSGOptions. The filesystem argument is handled automatically by the adapter.

Vite SSG plugin availability

The @hono/vite-ssg Vite Plugin provides an easy way to handle static site generation in Vite projects. It is available in the honojs/vite-plugins repository at packages/ssg.

Node.js manual build script for SSG

For Node.js, create a build script that imports toSSG from 'hono/ssg' and passes the app and fs module: import { toSSG } from 'hono/ssg'; toSSG(app, fs). The fs module should be imported from 'fs/promises'.

Customize file extensions with extensionMap

Import defaultExtensionMap from 'hono/ssg' and spread it into a custom extensionMap to add or override extensions: toSSG(app, fs, { extensionMap: { 'application/x-html': 'html', ...defaultExtensionMap } }).

GET-only filter plugin example

To filter only GET requests in SSG generation: const getOnlyPlugin: SSGPlugin = { beforeRequestHook: (req) => { if (req.method === 'GET') { return req } return false } }

Log generated files plugin example

To log all generated files after SSG completes: const logFilesPlugin: SSGPlugin = { afterGenerateHook: (result) => { if (result.files) { result.files.forEach((file) => console.log(file)) } } }

Sitemap generation plugin example

Advanced plugin example for generating sitemap.xml. The sitemapPlugin takes a baseURL string and uses the afterGenerateHook to create a sitemap file with all generated URLs. It accesses the output directory from options?.dir ?? DEFAULT_OUTPUT_DIR and writes an XML file with proper formatting.

Give your agent this brain