Remix
Remix

remix/middleware/render

Request-scoped renderer middleware for Remix. It stores a renderer in fetch-router request context so route actions can render responses without passing request-specific rendering details through every action.

Features

  • Generic renderers - Render any input type to a Response
  • Request-scoped setup - Create renderers from the current RequestContext
  • Typed context - Typed context.render (or context.get(Renderer))
  • Small runtime - The package only stores a renderer in request context

Installation

npm i remix

Usage

Use renderWith() to add a renderer to context.render and context.get(Renderer).

import { createRouter, type MiddlewareContext } from 'remix/router'
import { renderWith } from 'remix/middleware/render'

const render = renderWith(
  (context) =>
    function render(value: string, init?: ResponseInit) {
      return new Response(`${context.url.pathname}: ${value}`, init)
    },
)

type AppContext = MiddlewareContext<[typeof render]>

const router = createRouter<AppContext>({
  middleware: [render],
})

router.get('/hello', (context) => {
  return context.render('Hello')
})

Use context.render(...) (or context.get(Renderer)(...)).

Renderers may render any value type, not just UI nodes.

import { renderWith } from 'remix/middleware/render'

const json = renderWith(
  () =>
    function render(data: unknown, init?: ResponseInit) {
      return Response.json(data, init)
    },
)

router.get('/api', (context) => {
  return context.render({ ok: true })
})

For Remix UI, create a renderer that owns frame resolution and response creation.

import { createHtmlResponse } from 'remix/response/html'
import { renderWith } from 'remix/middleware/render'
import type { RemixNode } from 'remix/ui'
import { renderToStream } from 'remix/ui/server'

const render = renderWith(
  ({ router, url }) =>
    function render(node: RemixNode, init?: ResponseInit) {
      let stream = renderToStream(node, {
        async resolveFrame(src) {
          let response = await router.fetch(new URL(src, url))

          if (!response.ok) {
            return `<pre>Frame error: ${response.status}</pre>`
          }

          return response.body ?? response.text()
        },
      })

      return createHtmlResponse(stream, init)
    },
)

Related Packages

License

See LICENSE