@setu-ts/view-plugin — render HTML from components
Add it: setu add view adds it and inserts ViewPlugin() into setu.config.ts. It provides
CAPABILITIES.VIEW (IViewEngine); the default authoring mode is hono-jsx.
Render a page from a module route
A fixed template with a numeric prop needs no JSX compiler setup:
import type { IRouterApi } from '@setu-ts/common';
import { renderView } from '@setu-ts/view-plugin';
const receipt = (props: { count: number }) => `<p>Items: ${Number(props.count)}</p>`;
export function registerReceiptRoutes(router: IRouterApi): void {
router.get('/receipt', {
handler: (ctx) => renderView(ctx, receipt, { count: 3 }),
});
}
Replace the renderer
Put the returned plugin in the config’s plugin list:
import type { IViewEngine } from '@setu-ts/common';
import { ViewPlugin } from '@setu-ts/view-plugin';
export function views(view: IViewEngine) {
return ViewPlugin({ engine: 'custom', view });
}
Behaviour the types do not show
renderViewresolves the engine per request and returnstext/html; charset=utf-8.- Rendering buffers the complete result; it does not stream.
- Plain string components are returned unchanged. Escape dynamic text in the producer; the numeric conversion above is deliberate. JSX and the template runtime perform their own escaping.
null,false,trueand an empty string render empty;undefinedthrowsViewRenderError.- A pending suspense boundary throws
UnresolvedSuspenseErrorinstead of serving a permanent fallback.
Other options
engine: 'hono-html'selects template authoring in plain TypeScript; both built-in modes use one engine.engine: 'hono-jsx'selects JSX authoring; configure the application’s JSX runtime accordingly.- Compose layouts as components receiving children; there is no plugin-level layout option.