Skip to content

HTML & JSX

Val Town supports server-rendered JSX. This lets you use JSX syntax to construct your HTML string. It does not include any client-side JSX framework features, such as re-rendering on the client, but you can string that together yourself by writing client-side vals.

To use JSX, you’ll need to insert what TypeScript calls a “per-file pragma” - a comment that uses @jsxImportSource to specify where the JSX methods are going to come from. For example, if you’re implementing JSX with Preact, the pragma will look like this at the top of your val:

/** @jsxImportSource https://esm.sh/preact */

Preact

A good default is Preact, which provides a nice preact-render-to-string module that lets you quickly turn that JSX object into a string that you can use for a response.

Preact example
/** @jsxImportSource https://esm.sh/preact */
import { render } from "npm:preact-render-to-string";
export const preactExample = () =>
new Response(render(<div>Test {1 + 1}</div>), {
headers: {
"Content-Type": "text/html",
},
});

React

React example
/** @jsxImportSource https://esm.sh/react */
import { renderToString } from "npm:react-dom/server";
export const reactExample = () =>
new Response(renderToString(<div>Test {1 + 1}</div>), {
headers: {
"Content-Type": "text/html",
},
});

Vue

Vue example
/** @jsxImportSource https://esm.sh/vue */
import { renderToString } from "npm:vue/server-renderer";
export const vueExample = async () =>
new Response(await renderToString(<div>Test {1 + 1}</div>), {
headers: {
"Content-Type": "text/html",
},
});

Solid

Solid example
/** @jsxImportSource https://esm.sh/solid-jsx */
import { renderToString } from "npm:solid-js/web";
export const solidExample = async () =>
new Response(await renderToString(() => <div>Test {1 + 1}</div>), {
headers: {
"Content-Type": "text/html",
},
});

Hono

Hono example
/** @jsxImportSource npm:hono@3/jsx */
export const honoExample = () => {
const jsx = <div>Test {1 + 1}</div>;
return new Response(jsx.toString(), {
headers: {
"Content-Type": "text/html",
},
});
};