Skip to content

Using route parameters

Most adapters natively support route parameters (also called parametric path or path parameters) such as /hello/:name. @universal-middleware/core provides the params helper to universally retrieve those.

We recommend to follow this next example when using route parameters:

ts
import type { UniversalHandler } from "@universal-middleware/core";
import { params } from "@universal-middleware/core";

interface RouteParamOption {
  route?: string;
}

const handler = ((options?) => (request, _context, runtime) => {
  const myParams = params(request, runtime, options?.route);

  if (myParams === null || !myParams.name) {
    // Provide a useful error message to the user
    throw new Error(
      "A route parameter named `:name` is required. " +
        "You can set your server route as `/user/:name`, or use the `route` option of this middleware " +
        "to achieve the same purpose.",
    );
  }

  return new Response(`User name is: ${myParams.name}`);
}) satisfies (options?: RouteParamOption) => UniversalHandler;

export default handler;

NOTE

For servers supporting route parameters (app.get("/user/:name", myHandler())), the parameters are available under runtime.params.

For other adapters (app.get("/user/*", myHandler({ route: "/user/:name" }))), the 3rd argument of params helper must be present and not undefined. Then parameters are extracted with regexparam.

After bundling and publishing this middleware, one can then use this middleware as follows:

ts
import { 
Hono
} from "hono";
import
paramHandler
from "@universal-middleware-examples/tool/params-handler-hono";
const
app
= new
Hono
();
app
.
get
("/user/:name",
paramHandler
());
export default
app
;
ts
import { 
createApp
,
createRouter
} from "h3";
import
paramHandler
from "@universal-middleware-examples/tool/params-handler-h3";
import {
universalOnBeforeResponse
} from "@universal-middleware/h3";
const
app
=
createApp
({
// /!\ This is required for universal-middleware to operate properly
onBeforeResponse
:
universalOnBeforeResponse
,
}); const
router
=
createRouter
();
router
.
get
("/user/:name",
paramHandler
());
app
.
use
(
router
);
export default
app
;
ts
import { 
createRouter
} from "@hattip/router";
import
paramHandler
from "@universal-middleware-examples/tool/params-handler-hattip";
const
app
=
createRouter
();
app
.
get
("/user/:name",
paramHandler
());
const
hattipHandler
=
app
.
buildHandler
();
export default
hattipHandler
;
ts
import 
paramsHandler
from "@universal-middleware-examples/tool/params-handler";
import {
createHandler
} from "@universal-middleware/cloudflare";
import {
pipe
} from "@universal-middleware/core";
const
paramsHandlerInstance
=
paramsHandler
({
// Mandatory when targeting Cloudflare Worker
route
: "/user/:name",
}); // Cloudflare Workers have no native routing support. // We recommend using Hono as it fully supports Cloudflare Worker. const
wrapped
=
pipe
(
(
request
,
ctx
,
runtime
) => {
const
url
= new
URL
(
request
.
url
);
// intercept `/user/*` routes with this handler if (
url
.
pathname
.
startsWith
("/user/")) {
return
paramsHandlerInstance
(
request
,
ctx
,
runtime
);
} }, // Other handlers ); export default
createHandler
(() =>
wrapped
)();
ts
// functions/user/[name].ts

import 
paramHandler
from "@universal-middleware-examples/tool/params-handler-cloudflare-pages";
export const
onRequest
=
paramHandler
();
ts
import 
paramHandler
from "@universal-middleware-examples/tool/params-handler-express";
import
express
from "express";
const
app
=
express
();
app
.
get
("/user/:name",
paramHandler
());
export default
app
;
ts
import 
paramHandler
from "@universal-middleware-examples/tool/params-handler-fastify";
import
fastify
from "fastify";
const
app
=
fastify
();
app
.
get
("/user/:name",
paramHandler
());
export default
app
;
ts
import 
paramHandler
from "@universal-middleware-examples/tool/params-handler-elysia";
import
Elysia
from "elysia";
const
app
= new
Elysia
().
get
("/user/:name",
paramHandler
());
export default
app
;