Marks a string as trusted HTML, bypassing escaping when rendered in JSX or interpolated inside html. Use it when you need to inject markup you fully control — icons, pre-rendered fragments, or server-sanitized content.
Basic usage
import { const raw: (value: string) => RawHtmlraw } from "ilha";
<"div": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLDivElement>>div>{function raw(value: string): RawHtmlraw("<em>hello</em>")}</"div": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLDivElement>>div>;
// → <div><em>hello</em></div>Without raw(), the same string would be escaped:
<"div": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLDivElement>>div>{"<em>hello</em>"}</"div": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLDivElement>>div>
// → <div><em>hello</em></div>When to use it
raw() is appropriate when the markup comes from a source you fully control:
import const ilha: RootBuilder & DirectIslandFactory & {
html: (strings: TemplateStringsArray, ...values: unknown[]) => RawHtml;
raw: (value: string) => RawHtml;
mount: (registry: IslandRegistry, options?: MountOptions) => MountResult;
from: <TInput, TStateMap extends Record<string, unknown>>(selector: string | Element, island: Island<TInput, TStateMap>, props?: Partial<TInput>) => (() => void) | null;
... 5 more ...;
onUncaughtError: typeof onUncaughtError;
}
ilha, { const raw: (value: string) => RawHtmlraw } from "ilha";
// SVG icons defined in your codebase
const const chevron: "<svg viewBox=\"0 0 16 16\">\n <path d=\"M4 6l4 4 4-4\"/>\n</svg>"chevron = `<svg viewBox="0 0 16 16">
<path d="M4 6l4 4 4-4"/>
</svg>`;
const const Dropdown: Island<RootInput, RootState>Dropdown = ilha<RootInput>(fn: (ctx: RenderContext<RootInput, RootState, RootDerived, RootActions>) => string | RawHtml): Island<RootInput, RootState>ilha(() => (
<"button": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLButtonElement> & ButtonAttributes & {
popovertarget?: string;
popoverTarget?: string;
popovertargetaction?: "hide" | "show" | "toggle";
popoverTargetAction?: "hide" | "show" | "toggle";
}>
button>Options {function raw(value: string): RawHtmlraw(const chevron: "<svg viewBox=\"0 0 16 16\">\n <path d=\"M4 6l4 4 4-4\"/>\n</svg>"chevron)}</"button": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLButtonElement> & ButtonAttributes & {
popovertarget?: string;
popoverTarget?: string;
popovertargetaction?: "hide" | "show" | "toggle";
popoverTargetAction?: "hide" | "show" | "toggle";
}>
button>
));import { const raw: (value: string) => RawHtmlraw } from "ilha";
// Pre-rendered HTML from a trusted server-side renderer
const const renderedMarkdown: "<h1>Title</h1><p>Body text.</p>"renderedMarkdown = `<h1>Title</h1><p>Body text.</p>`;
<"article": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLElement>>article>{function raw(value: string): RawHtmlraw(const renderedMarkdown: "<h1>Title</h1><p>Body text.</p>"renderedMarkdown)}</"article": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLElement>>article>;When not to use it
Never pass user input to raw(). It disables all escaping, so any unescaped string becomes a potential XSS vector:
import { const raw: (value: string) => RawHtmlraw } from "ilha";
// ❌ Never do this
const const userComment: "<script>alert(1)</script>"userComment = `<script>alert(1)</script>`;
<"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>p>{function raw(value: string): RawHtmlraw(const userComment: "<script>alert(1)</script>"userComment)}</"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>p>;
// ✅ Do this instead — JSX escapes it automatically
<"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>p>{const userComment: "<script>alert(1)</script>"userComment}</"p": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLParagraphElement>>p>;Composing with JSX
JSX results are already treated as safe and pass through unescaped without needing raw(). Reserve raw() for plain strings that contain trusted markup:
import { const raw: (value: string) => RawHtmlraw } from "ilha";
// JSX result — no raw() needed
const const badge: JSX.Elementbadge = <"span": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLSpanElement>>span class?: RawHtml | ClassValue | undefinedclass="badge">New</"span": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLSpanElement>>span>;
<"div": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLDivElement>>div>{const badge: JSX.Elementbadge}</"div": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLDivElement>>div>;
// Plain string with markup — raw() required
const const iconStr: "<svg>…</svg>"iconStr = `<svg>…</svg>`;
<"div": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLDivElement>>div>{function raw(value: string): RawHtmlraw(const iconStr: "<svg>…</svg>"iconStr)}</"div": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLDivElement>>div>;Return type
raw() returns a RawHtml object. This means raw values compose freely with JSX and arrays:
import { const raw: (value: string) => RawHtmlraw } from "ilha";
const const icons: string[]icons = ["<svg>…</svg>", "<svg>…</svg>"];
<"ul": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLUListElement>>ul>
{const icons: string[]icons.Array<string>.map<JSX.Element>(callbackfn: (value: string, index: number, array: string[]) => JSX.Element, thisArg?: any): JSX.Element[]Calls a defined callback function on each element of an array, and returns an array that contains the results.map((icon: stringicon) => (
<"li": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLLIElement> & {
value?: number;
}>
li>{function raw(value: string): RawHtmlraw(icon: stringicon)}</"li": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLLIElement> & {
value?: number;
}>
li>
))}
</"ul": WithRawHtmlAttributeValues<JSX.HTMLAttributes<HTMLUListElement>>ul>;Notes
raw()only has an effect when rendered by ilha JSX orhtml. Elsewhere it simply wraps the string in aRawHtmlobject with no other transformation.- There is no runtime sanitization inside
raw(). If you need to accept user-generated HTML, sanitize it with a dedicated library such as DOMPurify before passing it toraw().