Routing Basics
Routes are the entry point for all requests to your application. They map a specific URL pattern to a specific file or route handler function.
In Hyperspan, there are 2 built-in types of routes:
- Page routes — for HTML pages
 - API routes — for JSON endpoints and other types of content
 
Both types of routes can live in two main places:
app/routesdirectory (file-based routes)app/server.tsfile (custom route handlers)
File-Based Routing
        Both page routes and
        API routes use file-based routing. This means that you can
        create a file in the app/routes directory and it will be automatically picked
        up by the framework and added to your routing table.
      
        Here are some examples of how files in the app/routes directory map to URL
        patterns:
      
| File Path | URL Pattern | 
|---|---|
app/routes/index.ts | 
            / | 
          
app/routes/about.ts | 
            /about | 
          
app/routes/posts/index.ts | 
            /posts | 
          
app/routes/posts/[id].ts | 
            /posts/:id | 
          
app/routes/auth/[...authPath].ts | 
            /auth/* | 
          
Route and query params can be accessed from the Hono Request object by name.
// File: app/routes/posts/[id].ts
import { createRoute } from '@hyperspan/framework';
import { fetchPostById } from '@/src/entities/posts'; // whatever your data layer is
export default createRoute(async (c) => {
  const id = c.req.param('id');
  const post = await fetchPostById(id);
  return html`<main>
    <h1>${post.title}</h1>
    <div>${post.content}</div>
  </main>`;
});
      Using Plain Functions
You can define a route with a plain function, but you won't have the proper types included by default, or other helpful APIs like limiting the route to a specific HTTP method, adding route-specific middleware, etc.
import { Context } from 'hono';
        
export default function (c: Context) {
  return html`<div>Hello, ${c.req.param('name')}!</div>`;
}
      createRoute.
      Route Parameters
        The createRoute and createAPIRoute functions have a
        Hono Context parameter that can be used to
        access information from the request, like
        parameters from the route path, query string parameters, headers, cookies, etc.
      
import { createRoute } from '@hyperspan/framework';
export default createRoute((c) => {
  return html`<div>Hello, ${c.req.param('name')}!</div>`;
});
      Custom Route Paths
        If you need more flexibility than file-based routing provides, you can import any file-based
        route and make it accessible with any custom path or URL pattern you define. Just import
        createRouteFromModule from @hyperspan/framework and pass in the
        whole imported module.
      
import hyperspanConfig from '../hyperspan.config';
import { createServer, createRouteFromModule } from '@hyperspan/framework';
import PostPageRoute from '@/app/routes/posts/[id].ts';
const app = await createServer(hyperspanConfig);
// Make post page route accessible at:
// /posts/:id      (file-based route via Hyperspan)
// /articles/:id   (custom path defined here)
const postRouteHandlers = createRouteFromModule(PostPageRoute);
app.get('/articles/:id', ...postRouteHandlers);
export default app;
      createRouteFromModule returns an array that includes any
          middleware that was defined in the route. Use the spread operator (...) to
          ensure all route handlers are added for the path.
      Custom Route Handlers
        If you need more control over routing or need to do something that doesn't fit within
        file-based routing, you can create a custom route handler function in
        app/server.ts. The createServer function will return a
        Hono instance that you can use to add custom
        Hono Routes or
        Hono Middleware.
      
import hyperspanConfig from '../hyperspan.config';
import { createServer } from '@hyperspan/framework';
const app = await createServer(hyperspanConfig);
// Custom Hono Route
app.get('/my-custom-route', (c) => c.html('<div>Hello, world!</div>'));
export default app;
      
        If you need to add routes before the file-based routes are processed, you can do so
        by using the beforeRoutesAdded hook in createConfig in your
        hyperspan.config.ts file.
      
import { createConfig } from '@hyperspan/framework';
export default createConfig({
  appDir: './app',
  staticFileRoot: './public',
  beforeRoutesAdded: (app) => {
    app.get('/custom-route-before-file-routes', (c) => c.html('<div>Hello, world!</div>'));
  },
});
      Route-Specific Middleware
        The createRoute function returns an object with a
        middleware() method to define middleware for one specific route. This is useful
        for things like caching that are highly contextual and should only be applied to specific
        routes.
      
The middleware is applied in the order it is defined, and is applied to the route before the route handler is called. Any middleware that is made for Hono can be used here.
import { createRoute } from '@hyperspan/framework';
import { logger } from 'hono/logger';
import { csrf } from 'hono/csrf';
export default createRoute((c) => {
  return html`<div>Hello, ${c.req.param('name')}!</div>`;
}).middleware([
  csrf(),
  logger(),
]);
      Global or Path-Specific Middleware
        You can add custom global or path-specific middleware to the Hono server directly in
        app/server.ts. This is useful for more global or path-specific things like
        authentication, logging, etc.
      
import hyperspanConfig from '../hyperspan.config';
import { createServer } from '@hyperspan/framework';
import { trimTrailingSlash } from 'hono/trailing-slash';
const app = await createServer(hyperspanConfig);
// Custom Hono Middleware
app.use(trimTrailingSlash());
export default app;
      If you are unfamiliar with middleware, you can read more about it in the Hono Middleware documentation.