Raw
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";
<IntrinsicElements[string]: anydiv>{function raw(value: string): RawHtmlraw("<em>hello</em>")}</IntrinsicElements[string]: anydiv>;
// → <div><em>hello</em></div>
Without raw(), the same string would be escaped:
<IntrinsicElements[string]: anydiv>{"<em>hello</em>"}</IntrinsicElements[string]: anydiv>
// → <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: IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>> & {
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;
... 4 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<Record<string, unknown>, Record<never, never>>Dropdown = const ilha: IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>> & {
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;
... 4 more ...;
onUncaughtError: typeof onUncaughtError;
}
ilha
.IlhaBuilder<Record<string, unknown>, Record<never, never>, Record<never, never>>.render(fn: (ctx: RenderContext<Record<string, unknown>, Record<never, never>, Record<never, never>>) => string | RawHtml): Island<Record<string, unknown>, Record<never, never>>render(() => <IntrinsicElements[string]: anybutton>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)}</IntrinsicElements[string]: anybutton>);
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>`;
<IntrinsicElements[string]: anyarticle>{function raw(value: string): RawHtmlraw(const renderedMarkdown: "<h1>Title</h1><p>Body text.</p>"renderedMarkdown)}</IntrinsicElements[string]: anyarticle>;
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>`;
<IntrinsicElements[string]: anyp>{function raw(value: string): RawHtmlraw(const userComment: "<script>alert(1)</script>"userComment)}</IntrinsicElements[string]: anyp>;
// ✅ Do this instead — JSX escapes it automatically
<IntrinsicElements[string]: anyp>{const userComment: "<script>alert(1)</script>"userComment}</IntrinsicElements[string]: anyp>;
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 = <IntrinsicElements[string]: anyspan class?: string | unknown[] | Record<string, boolean> | undefinedclass="badge">New</IntrinsicElements[string]: anyspan>;
<IntrinsicElements[string]: anydiv>{const badge: JSX.Elementbadge}</IntrinsicElements[string]: anydiv>;
// Plain string with markup — raw() required
const const iconStr: "<svg>…</svg>"iconStr = `<svg>…</svg>`;
<IntrinsicElements[string]: anydiv>{function raw(value: string): RawHtmlraw(const iconStr: "<svg>…</svg>"iconStr)}</IntrinsicElements[string]: anydiv>;
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>"];
<IntrinsicElements[string]: anyul>
{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) => (
<IntrinsicElements[string]: anyli>{function raw(value: string): RawHtmlraw(icon: stringicon)}</IntrinsicElements[string]: anyli>
))}
</IntrinsicElements[string]: anyul>;
Notes
raw() only has an effect when rendered by ilha JSX or html. Elsewhere it simply wraps the string in a RawHtml object 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 to raw().