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.
The Netlify adapter provides utilities for running Hono applications on Netlify Functions and Netlify Edge Functions.
Import
import { handle, getConnInfo } from 'hono/netlify'
Functions
handle()
Converts a Hono application into a Netlify function handler.
function handle(
app: Hono
): (req: Request, context: any) => Response | Promise<Response>
Parameters
app - The Hono application instance
Returns
A request handler function that receives both the request and Netlify context.
Example
import { Hono } from 'hono'
import { handle } from 'hono/netlify'
const app = new Hono()
app.get('/', (c) => {
return c.text('Hello from Netlify!')
})
app.get('/api/users/:id', (c) => {
const id = c.req.param('id')
return c.json({ id, name: 'John Doe' })
})
app.post('/api/form', async (c) => {
const body = await c.req.parseBody()
return c.json({ success: true, data: body })
})
export default handle(app)
getConnInfo()
Extracts connection information from the Netlify context.
function getConnInfo(c: Context): ConnInfo
Returns
interface ConnInfo {
remote: {
address?: string // Client IP from Netlify context
}
}
Example
import { Hono } from 'hono'
import { handle, getConnInfo } from 'hono/netlify'
const app = new Hono()
app.get('/', (c) => {
const info = getConnInfo(c)
return c.text(`Your IP: ${info.remote.address}`)
})
export default handle(app)
Accessing Netlify Context
The Netlify context is available through c.env.context and provides access to geolocation data and other Netlify-specific features.
Context Interface
interface NetlifyContext {
ip?: string
geo?: {
city?: string
country?: {
code?: string // e.g., "US"
name?: string // e.g., "United States"
}
subdivision?: {
code?: string // e.g., "CA"
name?: string // e.g., "California"
}
latitude?: number
longitude?: number
timezone?: string
postalCode?: string
}
requestId?: string
}
Example with Geolocation
import { Hono } from 'hono'
import { handle, getConnInfo } from 'hono/netlify'
type Bindings = {
context: {
ip?: string
geo?: {
city?: string
country?: { code?: string; name?: string }
latitude?: number
longitude?: number
}
}
}
const app = new Hono<{ Bindings: Bindings }>()
app.get('/api/location', (c) => {
const info = getConnInfo(c)
const { geo } = c.env.context
return c.json({
ip: info.remote.address,
city: geo?.city,
country: geo?.country?.name,
countryCode: geo?.country?.code,
coordinates: {
lat: geo?.latitude,
lon: geo?.longitude
}
})
})
app.get('/personalized', (c) => {
const { geo } = c.env.context
const country = geo?.country?.code || 'US'
return c.json({
message: `Content personalized for ${country}`,
currency: country === 'US' ? 'USD' : 'EUR'
})
})
export default handle(app)
Netlify Functions vs Edge Functions
Netlify supports two types of functions:
- Netlify Functions: Traditional serverless functions running on AWS Lambda
- Netlify Edge Functions: Run on Deno at the edge, closer to users
The adapter works with both types.
Netlify Functions
Create functions in the netlify/functions/ directory:
project/
├── netlify/
│ └── functions/
│ ├── api.ts
│ └── hello.ts
└── netlify.toml
Netlify Edge Functions
Create edge functions in the netlify/edge-functions/ directory:
project/
├── netlify/
│ └── edge-functions/
│ └── api.ts
└── netlify.toml
File-Based Routing
// netlify/functions/api.ts
import { Hono } from 'hono'
import { handle } from 'hono/netlify'
const app = new Hono()
app.get('/api/*', (c) => {
return c.json({ path: c.req.path })
})
export default handle(app)
Environment Variables
Access Netlify environment variables:
import { Hono } from 'hono'
import { handle } from 'hono/netlify'
const app = new Hono()
app.get('/api/config', (c) => {
return c.json({
context: Netlify.env.get('CONTEXT'), // 'production', 'deploy-preview', or 'branch-deploy'
siteUrl: Netlify.env.get('URL'),
deployUrl: Netlify.env.get('DEPLOY_URL'),
})
})
export default handle(app)
Request Context
The Netlify context provides additional functionality:
import { Hono } from 'hono'
import { handle } from 'hono/netlify'
const app = new Hono()
app.get('/api/request-info', (c) => {
const netlifyContext = c.env.context
return c.json({
requestId: netlifyContext.requestId,
ip: netlifyContext.ip,
geo: netlifyContext.geo
})
})
export default handle(app)
Configuration
netlify.toml
[build]
command = "npm run build"
publish = "dist"
functions = "netlify/functions"
[functions]
directory = "netlify/functions"
node_bundler = "esbuild"
[[edge_functions]]
function = "api"
path = "/api/*"
[[redirects]]
from = "/api/*"
to = "/.netlify/functions/api/:splat"
status = 200
Function Configuration
For Netlify Functions, you can add configuration:
// netlify/functions/api.ts
import { Hono } from 'hono'
import { handle } from 'hono/netlify'
import type { Config } from '@netlify/functions'
const app = new Hono()
app.get('/*', (c) => c.json({ message: 'Hello' }))
export default handle(app)
export const config: Config = {
path: "/api/*",
schedule: "@hourly" // For scheduled functions
}
Deployment
Using Netlify CLI
# Install Netlify CLI
npm install -g netlify-cli
# Login
netlify login
# Deploy
netlify deploy
# Deploy to production
netlify deploy --prod
Using Git Integration
- Connect your repository at app.netlify.com
- Configure build settings
- Deploy automatically on every push
Build Settings
- Build command:
npm run build
- Publish directory:
dist
- Functions directory:
netlify/functions
Complete Example
// netlify/functions/api.ts
import { Hono } from 'hono'
import { handle, getConnInfo } from 'hono/netlify'
import { cors } from 'hono/cors'
import { logger } from 'hono/logger'
type Bindings = {
context: {
ip?: string
geo?: {
city?: string
country?: { code?: string; name?: string }
}
requestId?: string
}
}
const app = new Hono<{ Bindings: Bindings }>()
app.use('*', cors())
app.use('*', logger())
app.get('/', (c) => {
return c.json({ message: 'Hello from Netlify!' })
})
app.get('/api/location', (c) => {
const info = getConnInfo(c)
const { geo } = c.env.context
return c.json({
ip: info.remote.address,
city: geo?.city,
country: geo?.country?.name
})
})
app.get('/api/users/:id', (c) => {
const id = c.req.param('id')
return c.json({ id, name: `User ${id}` })
})
app.post('/api/echo', async (c) => {
const body = await c.req.json()
return c.json(body)
})
app.notFound((c) => {
return c.json({ error: 'Not Found' }, 404)
})
app.onError((err, c) => {
console.error(err)
return c.json({ error: 'Internal Server Error' }, 500)
})
export default handle(app)
See Also