Nitro logoNitro

Custom Renderer

View Source
Build a custom HTML renderer in Nitro with server-side data fetching.

Create a custom renderer that generates HTML responses with data from API routes. Use Nitro's internal fetch to call routes without network overhead.

├── api/
│   └── hello.ts
├── nitro.config.ts
├── package.json
├── README.md
├── renderer.ts
├── tsconfig.json
└── vite.config.ts

Renderer

renderer.ts
import { fetch } from "nitro";

export default async function renderer({ url }: { req: Request; url: URL }) {
  const apiRes = await fetch("/api/hello").then((res) => res.text());
  return new Response(
    /* html */ `<!DOCTYPE html>
    <html>
    <head>
      <title>Custom Renderer</title>
    </head>
    <body>
      <h1>Hello from custom renderer!</h1>
      <p>Current path: ${url.pathname}</p>
      <p>API says: ${apiRes}</p>
    </body>
    </html>`,
    { headers: { "content-type": "text/html; charset=utf-8" } }
  );
}

Nitro auto-detects renderer.ts in your project root and uses it for all non-API routes. The renderer function receives the request URL and returns a Response.

Use fetch from nitro to call API routes without network overhead—these requests stay in-process.

API Route

hello.ts
import { defineHandler } from "nitro/h3";

export default defineHandler(() => "Nitro is amazing!");

Define API routes in the api/ directory. When the renderer calls fetch("/api/hello"), this handler runs and returns its response.

Learn More