Skip to content
Vincle

Loading…

    raw()

    Marks a string as trusted: every check is turned off for it.

    Signature#

    raw(value: string): RawString

    Usage#

    Use it for HTML from a trusted source (a Markdown renderer, a sanitizer, your own templates), never for user input:

    import { raw } from "@vincle/core";
    <div>{raw(await renderMarkdown(post.body))}</div>;
    <div>{raw(DOMPurify.sanitize(userInput))}</div>;
    // ❌ XSS if userInput contains <script>alert(1)</script>
    <div>{raw(userInput)}</div>;
    // ✅ Vincle escapes by default
    <div>{userInput}</div>;

    In an attribute#

    In an attribute, raw() is a trusted value, not markup: it is emitted as written, a URL included (no scheme check), except ", so it can never end its attribute. The escaped " decodes back before CSS, JS or the DOM reads it, so the value still means what it says.

    <a href={raw("javascript:go()")}>x</a>; // href="javascript:go()"
    <a title={raw('" onmouseover="alert(1)')}>x</a>; // title="&quot; onmouseover=&quot;…"

    A sanitizer's output is markup: it belongs in content, not in an attribute.

    dangerouslySetInnerHTML#

    The same promise as raw(), for React compatibility:

    <div dangerouslySetInnerHTML={{ __html: "<b>bold</b>" }} />

    rawUrl(): a narrower trust boundary#

    rawUrl() is a separate function for URLs. It skips only the scheme check: the value is still escaped, so unlike raw() it cannot end its attribute, and in content position it is text like any other.

    import { rawUrl } from "@vincle/core";
    <a href={rawUrl("phpstorm://open?file=src/app.ts")}>open in the IDE</a>;

    raw() vs rawUrl()#

    Function In content In attribute Grep target
    raw() Emitted as verbatim markup Escaped as a value, trust for scheme raw(
    rawUrl() N/A (type error) Trust for scheme only, still escaped rawUrl(

    A RawString is markup — it bypasses escaping entirely. A RawUrl is a URL — it bypasses only the scheme filter. The distinction is enforced at both the type level (RawString and RawUrl are nominally distinct) and runtime (instanceof checks treat them differently). An audit should list every raw() call and verify the value originates from a trusted source (sanitizer output, template engine, hardcoded markup), never from user input.

    See also#