DEV Community

Tao Wen
Tao Wen

Posted on

Use jsx as server side html template

source code: https://github.com/taowen/incremental-html/tree/main/packages/jsx-to-html

// filename: newsletter.tsx
import { jsxToHtml } from '@incremental-html/jsx-to-html'

// server is an express router
server.get('/newsletter', async (req, resp) => {
    const html: string = await jsxToHtml(<div>hello</div>);
    resp.status(200).set({ 'Content-Type': 'text/html' }).end(html);
})
Enter fullscreen mode Exit fullscreen mode

The tsconfig.json should configure like this to translate *.tsx using jsxToHtml

{
    "compilerOptions": {
//...
        "jsx": "react",
        "jsxFactory": "jsxToHtml.createElement",
        "jsxFragmentFactory": "jsxToHtml.Fragment",
//...
}
Enter fullscreen mode Exit fullscreen mode

async context

We can use jsxToHtml as an alterantive to node.js async_hooks.
There is no runtime trick, works in any environment (including deno, cloudflare workers, etc)

test('component with context', async () => {
    const C1 = async (props: {}, ctx: { msg: string }) => {
        await new Promise<void>(resolve => resolve());
        return <div>{ctx.msg}</div>
    }
    const result = <context msg="hello"><C1 /></context>
    expect(await jsxToHtml(result, { msg: 'original msg' })).toBe('<div>\nhello\n</div>');
})
Enter fullscreen mode Exit fullscreen mode

The context will be automatically passed down the tree.
<context> is a built-in component to alter the context in the middle.

Discussion (0)