Documentation Index
Fetch the complete documentation index at: https://mintlify.com/honojs/hono/llms.txt
Use this file to discover all available pages before exploring further.
Parts of the SSG Helper are experimental. The API may change in future versions.
The SSG (Static Site Generation) Helper enables pre-rendering of Hono applications to static files, allowing you to generate static HTML, CSS, JSON, and other assets at build time.
Import
import { toSSG, fetchRoutesContent, saveContentToFile } from 'hono/ssg'
import { ssgParams, isSSGContext, disableSSG, onlySSG } from 'hono/ssg'
import type { ToSSGOptions, ToSSGResult } from 'hono/ssg'
Functions
toSSG()
Generates static files from a Hono application.
function toSSG(
app: Hono<any, any, any>,
fsModule: FileSystemModule,
options?: ToSSGOptions
): Promise<ToSSGResult>
The Hono application instance to generate static files from
File system module with writeFile and mkdir methods (e.g., Node.js fs/promises)
Configuration options for static generation
Result object containing:
success: boolean indicating if generation succeeded
files: array of generated file paths
error: Error object if generation failed
Example
import { Hono } from 'hono'
import { toSSG } from 'hono/ssg'
import fs from 'fs/promises'
const app = new Hono()
app.get('/', (c) => c.html('<h1>Home</h1>'))
app.get('/about', (c) => c.html('<h1>About</h1>'))
app.get('/api/data', (c) => c.json({ message: 'Hello' }))
// Generate static files
const result = await toSSG(app, fs, {
dir: './dist'
})
if (result.success) {
console.log(`Generated ${result.files.length} files`)
result.files.forEach(file => console.log(file))
} else {
console.error('Generation failed:', result.error)
}
ssgParams()
Middleware to define parameters for dynamic routes during SSG.
function ssgParams<E extends Env = Env>(
params: SSGParams
): MiddlewareHandler<E>
function ssgParams<E extends Env = Env>(
generateParams: (c: Context<E>) => SSGParams | Promise<SSGParams>
): MiddlewareHandler<E>
params
SSGParams | Function
required
Either an array of parameter objects or a function that returns them
Middleware that provides parameters for static generation
Example
import { ssgParams } from 'hono/ssg'
app.get(
'/posts/:id',
ssgParams(async (c) => {
// Generate pages for these post IDs
return [
{ id: '1' },
{ id: '2' },
{ id: '3' }
]
}),
(c) => {
const id = c.req.param('id')
return c.html(`<h1>Post ${id}</h1>`)
}
)
// Static array
app.get(
'/users/:userId',
ssgParams([
{ userId: 'alice' },
{ userId: 'bob' }
]),
(c) => {
const userId = c.req.param('userId')
return c.html(`<h1>User: ${userId}</h1>`)
}
)
isSSGContext()
Checks if the current request is running in SSG context.
function isSSGContext(c: Context): boolean
true if running in SSG context, false otherwise
Example
import { isSSGContext } from 'hono/ssg'
app.get('/page', (c) => {
if (isSSGContext(c)) {
// Render static version
return c.html('<h1>Static Page</h1>')
} else {
// Render dynamic version with live data
return c.html(`<h1>Dynamic Page - ${new Date()}</h1>`)
}
})
disableSSG()
Middleware to prevent a route from being statically generated.
function disableSSG(): MiddlewareHandler
Middleware that disables SSG for the route
Example
import { disableSSG } from 'hono/ssg'
// This route will not be statically generated
app.get('/admin', disableSSG(), (c) => {
return c.html('<h1>Admin Panel</h1>')
})
// Dynamic API route
app.get('/api/current-time', disableSSG(), (c) => {
return c.json({ time: new Date().toISOString() })
})
onlySSG()
Middleware to make a route only available during SSG (returns 404 at runtime).
function onlySSG(): MiddlewareHandler
Middleware that makes the route SSG-only
Example
import { onlySSG } from 'hono/ssg'
// This route only exists in static builds
app.get('/sitemap.xml', onlySSG(), (c) => {
const sitemap = generateSitemap()
return c.text(sitemap, 200, {
'Content-Type': 'application/xml'
})
})
fetchRoutesContent()
Generator function that fetches content for all routes.
function* fetchRoutesContent<E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'>(
app: Hono<E, S, BasePath>,
beforeRequestHook?: BeforeRequestHook,
afterResponseHook?: AfterResponseHook,
concurrency?: number
): Generator<Promise<...>>
The Hono application instance
Hook called before each request
Hook called after each response
Number of concurrent requests (default: 2)
Generator yielding Promises that resolve to route content
saveContentToFile()
Saves content to a file.
function saveContentToFile(
data: Promise<{ routePath: string; content: string | ArrayBuffer; mimeType: string } | undefined>,
fsModule: FileSystemModule,
outDir: string,
extensionMap?: Record<string, string>
): Promise<string | undefined>
Promise resolving to content data
Custom MIME type to file extension mapping
return
Promise<string | undefined>
Path to the saved file, or undefined if save was skipped
Types
ToSSGOptions
interface ToSSGOptions {
dir?: string // Output directory (default: './static')
concurrency?: number // Concurrent requests (default: 2)
extensionMap?: Record<string, string> // MIME type to extension mapping
plugins?: SSGPlugin[] // SSG plugins
}
ToSSGResult
interface ToSSGResult {
success: boolean
files: string[]
error?: Error
}
SSGParams
type SSGParams = Array<Record<string, string>>
// Example:
const params: SSGParams = [
{ id: '1', slug: 'first' },
{ id: '2', slug: 'second' }
]
FileSystemModule
interface FileSystemModule {
writeFile(path: string, data: string | Uint8Array): Promise<void>
mkdir(path: string, options: { recursive: boolean }): Promise<void | string>
}
Advanced Usage
Custom Extension Mapping
import { toSSG } from 'hono/ssg'
import fs from 'fs/promises'
const result = await toSSG(app, fs, {
dir: './dist',
extensionMap: {
'text/html': 'html',
'application/json': 'json',
'text/xml': 'xml',
'application/rss+xml': 'rss'
}
})
Build Script Example
// build.ts
import { Hono } from 'hono'
import { toSSG } from 'hono/ssg'
import fs from 'fs/promises'
const app = new Hono()
// Define your routes
app.get('/', (c) => c.html('<h1>Home</h1>'))
app.get('/about', (c) => c.html('<h1>About</h1>'))
// Generate static site
async function build() {
console.log('Generating static site...')
const result = await toSSG(app, fs, {
dir: './dist',
concurrency: 4
})
if (result.success) {
console.log(`✓ Generated ${result.files.length} files`)
} else {
console.error('✗ Build failed:', result.error)
process.exit(1)
}
}
build()
Dynamic Routes with Database
import { ssgParams } from 'hono/ssg'
app.get(
'/blog/:slug',
ssgParams(async () => {
// Fetch all blog post slugs from database
const posts = await db.posts.findAll()
return posts.map(post => ({ slug: post.slug }))
}),
async (c) => {
const slug = c.req.param('slug')
const post = await db.posts.findBySlug(slug)
return c.html(`
<article>
<h1>${post.title}</h1>
<div>${post.content}</div>
</article>
`)
}
)
File Output
Generated files follow these patterns:
/ → /index.html
/about → /about.html
/about/ → /about/index.html
/api/data → /api/data.json (for JSON responses)
/feed.xml → /feed.xml