Same output on the server
The server renderer applies the same rules and adds protections for untrusted values.
The server renderer applies the same rules and adds protections for untrusted values. Class values are clsx-resolved, style names are validated, and a style value that could end its own declaration is dropped:
src/server-style.tsxtsx
import { renderToString } from "@shadow-js/web/server";
export function Box(props: { hostile: string }) {
return (
<div
class={["a", false, { b: false, c: true }]}
style={{ color: "red", "--gap": "4px", marginTop: 2, background: props.hostile }}
/>
);
}
console.log(renderToString(() => <Box hostile="red; position: fixed" />).replace(/ data-hk="[^"]*"/, ""));
console.log(renderToString(() => <div style={{ color: "red", width: "1px}body{x:y" }} />).replace(/ data-hk="[^"]*"/, ""));
<div class=The first call shows the camelCase-to-kebab conversion, custom properties and a number given a pixel unit; the
value red; position: fixed is not in the output because it contains a ; outside quotes and
parentheses. The second drops } for the same reason. An invalid property name throws a
TypeError (INVALID_STYLE_PROPERTY). On the client a value is written through
CSSStyleDeclaration.setProperty, which cannot add a second declaration.