> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/honojs/hono/llms.txt
> Use this file to discover all available pages before exploring further.

# HTML Helper

> Helper functions for creating HTML content with automatic escaping

The HTML Helper provides a tagged template literal for creating HTML strings with automatic XSS protection through HTML escaping.

## Import

```typescript theme={null}
import { html, raw } from 'hono/html'
```

## Functions

### html()

Creates an HTML string with automatic escaping of interpolated values.

```typescript theme={null}
function html(
  strings: TemplateStringsArray,
  ...values: unknown[]
): HtmlEscapedString | Promise<HtmlEscapedString>
```

<ParamField path="strings" type="TemplateStringsArray" required>
  The template string array
</ParamField>

<ParamField path="values" type="unknown[]" required>
  Values to interpolate into the template. All values are automatically HTML-escaped except those wrapped with `raw()`.
</ParamField>

<ResponseField name="return" type="HtmlEscapedString | Promise<HtmlEscapedString>">
  An HTML-escaped string. Returns a Promise if any interpolated value is a Promise.
</ResponseField>

**Example**

```typescript theme={null}
import { html } from 'hono/html'

app.get('/', (c) => {
  const name = 'John <script>alert("xss")</script>'
  
  // Values are automatically escaped
  const content = html`
    <html>
      <body>
        <h1>Hello ${name}!</h1>
      </body>
    </html>
  `
  // Output: <h1>Hello John &lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;!</h1>
  
  return c.html(content)
})
```

### Escaping Behavior

The `html` helper automatically escapes the following:

* **Strings**: HTML special characters are escaped (`<`, `>`, `&`, `"`, `'`)
* **Numbers**: Rendered as-is
* **Booleans, null, undefined**: Ignored (rendered as empty string)
* **Arrays**: Flattened with `Array.flat(Infinity)` and each element is processed
* **Promises**: Awaited and then processed
* **Objects**: Converted to string via `.toString()` and escaped

```typescript theme={null}
app.get('/demo', (c) => {
  const values = [
    'Name: John',
    ['<b>Bold</b>', undefined, null],
    ' Contact:',
    [html`<a href="/">Link</a>`]
  ]
  
  return c.html(html`<div>${values}</div>`)
  // Output: <div>Name: John&lt;b&gt;Bold&lt;/b&gt; Contact:<a href="/">Link</a></div>
})
```

### Async Support

When interpolating Promises, the `html` function returns a Promise:

```typescript theme={null}
app.get('/async', async (c) => {
  const fetchUserName = async () => {
    // Fetch from database
    return 'John Doe'
  }
  
  const content = html`
    <html>
      <body>
        <h1>User: ${fetchUserName()}</h1>
      </body>
    </html>
  `
  
  // content is a Promise, so await it
  return c.html(await content)
})
```

### raw()

Marks a string as safe HTML that should not be escaped.

```typescript theme={null}
function raw(value: string): HtmlEscapedString
```

<ParamField path="value" type="string" required>
  The HTML string that should not be escaped
</ParamField>

<ResponseField name="return" type="HtmlEscapedString">
  An HTML string marked as safe (not escaped)
</ResponseField>

**Example**

```typescript theme={null}
import { html, raw } from 'hono/html'

app.get('/with-raw', (c) => {
  const userInput = '<script>alert("xss")</script>'
  const safeHTML = '<strong>Important</strong>'
  
  return c.html(html`
    <div>
      <!-- This will be escaped -->
      <p>${userInput}</p>
      
      <!-- This will NOT be escaped -->
      <p>${raw(safeHTML)}</p>
    </div>
  `)
})
```

**Output:**

```html theme={null}
<div>
  <!-- Escaped -->
  <p>&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;</p>
  
  <!-- Not escaped -->
  <p><strong>Important</strong></p>
</div>
```

## Use Cases

### Building Components

```typescript theme={null}
const Layout = (props: { title: string; children: any }) => html`
  <!DOCTYPE html>
  <html>
    <head>
      <title>${props.title}</title>
    </head>
    <body>
      ${props.children}
    </body>
  </html>
`

const Content = () => html`
  <div>
    <h1>Welcome</h1>
    <p>This is content</p>
  </div>
`

app.get('/', (c) => {
  return c.html(
    Layout({
      title: 'My Site',
      children: Content()
    })
  )
})
```

### Conditional Rendering

```typescript theme={null}
app.get('/user/:id', (c) => {
  const user = getUser(c.req.param('id'))
  
  return c.html(html`
    <div>
      ${user
        ? html`<h1>Hello ${user.name}</h1>`
        : html`<p>User not found</p>`
      }
    </div>
  `)
})
```

### Lists

```typescript theme={null}
app.get('/items', (c) => {
  const items = ['Apple', 'Banana', 'Cherry']
  
  return c.html(html`
    <ul>
      ${items.map(item => html`<li>${item}</li>`)}
    </ul>
  `)
})
```

## Security

The `html` helper provides automatic XSS protection by escaping all interpolated values by default. Only use `raw()` when you are certain the content is safe.

```typescript theme={null}
// ✅ SAFE: User input is escaped
html`<div>${userInput}</div>`

// ⚠️ DANGEROUS: User input is not escaped
html`<div>${raw(userInput)}</div>`

// ✅ SAFE: Sanitized content
html`<div>${raw(sanitizeHTML(userInput))}</div>`
```

## Types

```typescript theme={null}
interface HtmlEscapedString {
  isEscaped: true
  callbacks?: HtmlEscapedCallback[]
}

interface HtmlEscaped {
  isEscaped: true
}
```
