# `PhoenixKit.Utils.HtmlSanitizer`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v2.55.1/lib/phoenix_kit/utils/html_sanitizer.ex#L1)

HTML sanitization for user-supplied rich text.

Backed by `MDEx.safe_html/2` — an ammonia-based **parsed allowlist**. It
builds a real DOM, keeps only known-good tags and attributes, validates
URL schemes per attribute, and re-serializes. It does not pattern-match
on markup, which is why it holds up where the previous regex
implementation did not (see `sanitize_html/1`).

## What survives

Ordinary rich text: block elements (p, div, hr, h1-h6, blockquote, pre,
code), inline elements (span, strong, em, u, s, a, sub, sup), lists,
tables, and img. Relative, absolute, anchor, `mailto:` and `tel:` URLs
are preserved, as are `class` on any tag and `target` on links.

## What is removed

Script and style elements, event-handler attributes, dangerous URL
schemes (`javascript:`, `data:`, …) **including entity-encoded
spellings** such as `jav&#x61;script:`, and embedding elements
(iframe, object, embed, svg, math).

Attributes outside the allowlist go too, and the allowlist is narrower
than the one this module shipped before the rewrite. Most notably **`id`
is dropped from every tag**, so `href="#..."` can only reach an anchor
the application itself rendered, not one stored in the content. Also
gone: `rel` (re-stamped as `noopener noreferrer` on every link),
`<input>` — so Markdown task-list checkboxes vanish — and `<tfoot>`.
`sanitize_html/1` carries the reasoning and the knobs.

## Output is normalised

Because the result is re-serialized from a parse tree, it is valid HTML
rather than a lightly-edited copy of the input: attribute values come
back quoted, void elements lose a self-closing slash (`<br/>` →
`<br>`), `<table>` gains an implicit `<tbody>`, and links gain
`rel="noopener noreferrer"`. Compare rendered meaning, not exact
strings, when asserting on sanitized output.

## Usage

    PhoenixKit.Utils.HtmlSanitizer.sanitize("<p>Hello</p><script>alert('xss')</script>")
    #=> "<p>Hello</p>"

    PhoenixKit.Utils.HtmlSanitizer.sanitize(~s|<a href="javascript:alert(1)">Click</a>|)
    #=> "<a rel=\"noopener noreferrer\">Click</a>"

# `sanitize`

Sanitizes HTML content by removing dangerous elements and attributes.

Returns sanitized HTML string that is safe to render.

## Parameters

- `html` - The HTML string to sanitize

## Examples

    iex> PhoenixKit.Utils.HtmlSanitizer.sanitize("<p onclick="alert('xss')">Hello</p>")
    "<p>Hello</p>"

# `sanitize_rich_text_fields`

Sanitizes all rich_text fields in an entity data map.

Takes entity field definitions and data, returns data with all
rich_text fields sanitized.

## Parameters

- `fields_definition` - List of field definition maps
- `data` - Map of field key => value

## Examples

    iex> fields = [%{"type" => "rich_text", "key" => "content"}]
    iex> data = %{"content" => "<script>alert('xss')</script><p>Hello</p>"}
    iex> PhoenixKit.Utils.HtmlSanitizer.sanitize_rich_text_fields(fields, data)
    %{"content" => "<p>Hello</p>"}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
