SSR Stream Interception

How to intercept SSR stream to inject content before it is sent to the client.


Additional Content Injection in SSR

In some cases you may want to inject additional content into the SSR stream before it's sent to the client. This can be useful for injecting properties onto the document's root element (e.g., the lang attribute or a class name based on the user's request headers).

This guide is intentionally narrow. Use it when you specifically need to transform the HTML stream. For request-scoped data and regular middleware, see Request Context.

Step 1: Create a custom middleware

Create a new file in src/middleware/. Waku automatically discovers and loads middleware from this directory.

// ./src/middleware/stream-interceptor.ts
import type { MiddlewareHandler } from 'hono';

const getPreferredLanguage = (acceptLanguage: string | undefined) => {
  return acceptLanguage?.split(',')[0]?.trim() || 'en';
};

const streamInterceptor = (): MiddlewareHandler => {
  return async (c, next) => {
    await next();

    const contentType = c.res.headers.get('content-type');
    const isDocument = contentType?.includes('text/html');
    const lang = getPreferredLanguage(c.req.header('accept-language'));

    if (isDocument && c.res.body) {
      const newBody = c.res.body.pipeThrough(
        new TransformStream({
          transform(chunk, controller) {
            const text = new TextDecoder().decode(chunk);
            const newText = text.replace('<html>', `<html lang="${lang}">`);
            controller.enqueue(new TextEncoder().encode(newText));
          },
        }),
      );

      c.res = new Response(newBody, {
        status: c.res.status,
        headers: c.res.headers,
      });
    }
  };
};

export default streamInterceptor;

Step 2: Verify the changes

After restarting the server, inspect the HTML source of your page. You should see the lang attribute on the <html> element.

For more on request-scoped data, see Request Context.

designed bycandycode alternative graphic design web development agency San Diego