Skip to main content

Import

import { trimTrailingSlash, appendTrailingSlash } from 'hono/trailing-slash'

trimTrailingSlash

Usage

const app = new Hono()

app.use(trimTrailingSlash())

app.get('/about/me/', (c) => c.text('With Trailing Slash'))

// Request to /about/me/ redirects to /about/me

Options

alwaysRedirect
boolean
default:false
If true, the middleware will always redirect requests with a trailing slash before executing handlers. This is useful for routes with wildcards (*).If false (default), it will only redirect when the route is not found (404).

Signature

trimTrailingSlash(options?: TrimTrailingSlashOptions): MiddlewareHandler

interface TrimTrailingSlashOptions {
  alwaysRedirect?: boolean
}

Examples

Basic usage

const app = new Hono()

app.use(trimTrailingSlash())

app.get('/about/me/', (c) => c.text('About Me'))

// GET /about/me/ -> redirects to /about/me (301)

With wildcard routes

const app = new Hono()

app.use(trimTrailingSlash({ alwaysRedirect: true }))

app.get('/my-path/*', (c) => c.text('Wildcard route'))

// GET /my-path/foo/ -> redirects to /my-path/foo (301)

Preserve query strings

app.use(trimTrailingSlash())

app.get('/search/', (c) => c.text('Search'))

// GET /search/?q=hono -> redirects to /search?q=hono (301)

Behavior

  • Only affects GET and HEAD requests
  • Root path / is never redirected
  • Returns 301 Permanent Redirect
  • Preserves query strings and hash fragments
  • Default mode: redirects only on 404 (route not found)
  • alwaysRedirect mode: redirects before handler execution

appendTrailingSlash

Usage

const app = new Hono()

app.use(appendTrailingSlash())

app.get('/about/me/', (c) => c.text('About Me'))

// Request to /about/me redirects to /about/me/

Options

alwaysRedirect
boolean
default:false
If true, the middleware will always redirect requests without a trailing slash before executing handlers. This is useful for routes with wildcards (*).If false (default), it will only redirect when the route is not found (404).

Signature

appendTrailingSlash(options?: AppendTrailingSlashOptions): MiddlewareHandler

interface AppendTrailingSlashOptions {
  alwaysRedirect?: boolean
}

Examples

Basic usage

const app = new Hono()

app.use(appendTrailingSlash())

app.get('/about/me/', (c) => c.text('About Me'))

// GET /about/me -> redirects to /about/me/ (301)

With wildcard routes

const app = new Hono()

app.use(appendTrailingSlash({ alwaysRedirect: true }))

app.get('/my-path/*', (c) => c.text('Wildcard route'))

// GET /my-path/foo -> redirects to /my-path/foo/ (301)

Preserve query strings

app.use(appendTrailingSlash())

app.get('/search/', (c) => c.text('Search'))

// GET /search?q=hono -> redirects to /search/?q=hono (301)

Behavior

  • Only affects GET and HEAD requests
  • Returns 301 Permanent Redirect
  • Preserves query strings and hash fragments
  • Default mode: redirects only on 404 (route not found)
  • alwaysRedirect mode: redirects before handler execution

Usage Notes

  • Do not use both trimTrailingSlash and appendTrailingSlash together
  • Middleware should be applied before route definitions
  • For wildcard routes, use alwaysRedirect: true option
  • Both preserve full URL including query parameters

Build docs developers (and LLMs) love