Skip to content

v-sanitize

Sanitize HTML content to prevent XSS attacks.

Since: 1.1.0

Usage

Basic

vue
<template>
  <div v-sanitize v-html="userContent"></div>
</template>

<script setup>
const userContent = '<p>Safe content</p><script>alert("xss")<\/script>'
</script>

With Allowed Tags

vue
<template>
  <div v-sanitize="{ allowedTags: ['b', 'i', 'p'] }" v-html="userContent"></div>
</template>

Custom Handler

vue
<template>
  <div v-sanitize="{ handler: customSanitizer }" v-html="userContent"></div>
</template>

<script setup>
function customSanitizer(html) {
  // Custom sanitization logic
  return html.replace(/<script.*?>.*?<\/script>/gi, '')
}
</script>

API

Types

typescript
type SanitizeHandler = (value: string) => string

interface SanitizeOptions {
  /** Tags to allow (whitelist) */
  allowedTags?: string[]
  /** Attributes to allow (whitelist) */
  allowedAttributes?: string[]
  /** Allow data URLs */
  allowDataUrls?: boolean
  /** Allow inline styles */
  allowStyles?: boolean
  /** Allow class attribute */
  allowClass?: boolean
  /** Allow id attribute */
  allowId?: boolean
  /** Custom sanitize function */
  handler?: SanitizeHandler
  /** Disable sanitization */
  disabled?: boolean
  /** Sanitize on update */
  sanitizeOnUpdate?: boolean
}

type SanitizeBinding = boolean | SanitizeOptions

Options

OptionTypeDefaultDescription
allowedTagsstring[]['b', 'i', 'u', 'strong', 'em', 'br', 'p', 'span', 'div']Allowed HTML tags
allowedAttributesstring[]['title', 'alt', 'href', 'src']Allowed HTML attributes
allowDataUrlsbooleanfalseAllow data: URLs
allowStylesbooleanfalseAllow style attribute
allowClassbooleanfalseAllow class attribute
allowIdbooleanfalseAllow id attribute
handlerFunction-Custom sanitize function
disabledbooleanfalseDisable sanitization
sanitizeOnUpdatebooleantrueSanitize on update

Examples

Rich Text Editor

vue
<template>
  <div
    v-sanitize="{
      allowedTags: ['p', 'br', 'strong', 'em', 'u', 'a', 'ul', 'ol', 'li'],
      allowedAttributes: ['href'],
      allowClass: true
    }"
    v-html="editorContent"
    class="rich-text"
  ></div>
</template>

User Comments

vue
<template>
  <div v-for="comment in comments" :key="comment.id">
    <div v-sanitize v-html="comment.body"></div>
  </div>
</template>

Blog Post

vue
<template>
  <article v-sanitize="{
    allowedTags: ['h1', 'h2', 'h3', 'p', 'br', 'strong', 'em', 'a', 'img', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code'],
    allowedAttributes: ['href', 'src', 'alt', 'title'],
    allowDataUrls: false,
    allowClass: true
  }" v-html="post.content">
  </article>
</template>

Disable for Trusted Content

vue
<template>
  <div v-sanitize="{ disabled: isTrusted }" v-html="content"></div>
</template>

<script setup>
const isTrusted = true // Only set true for trusted admin content
</script>

Composable API

For programmatic use, you can use the useSanitize composable:

typescript
import { useSanitize } from 'directix'

const { sanitize, bind } = useSanitize({
  allowedTags: ['b', 'i', 'u', 'strong', 'em', 'br', 'p', 'span', 'div'],
  allowedAttributes: ['title', 'alt', 'href', 'src'],
  allowDataUrls: false,
  allowStyles: false,
  allowClass: false,
  allowId: false,
  handler: undefined
})

// Sanitize HTML string
const safeHtml = sanitize(userInput)

// Bind to element
onMounted(() => bind(elementRef.value))

UseSanitizeOptions

OptionTypeDefaultDescription
allowedTagsstring[]['b', 'i', 'u', 'strong', 'em', 'br', 'p', 'span', 'div']Tags to allow (whitelist)
allowedAttributesstring[]['title', 'alt', 'href', 'src']Attributes to allow (whitelist)
allowDataUrlsbooleanfalseAllow data URLs
allowStylesbooleanfalseAllow inline styles
allowClassbooleanfalseAllow class attribute
allowIdbooleanfalseAllow id attribute
handler(html: string) => string-Custom sanitize function

UseSanitizeReturn

PropertyTypeDescription
sanitize(html: string) => stringSanitize HTML string
bind(element: HTMLElement) => () => voidSanitize and set to element

Example

vue
<script setup>
import { ref } from 'vue'
import { useSanitize } from 'directix'

const { sanitize } = useSanitize({
  allowedTags: ['b', 'i', 'p'],
  allowedAttributes: []
})

const safeHtml = sanitize(userInput)
</script>

<template>
  <p>{{ safeHtml }}</p>
</template>

Code Generator

Quick Code Generator
<template>
  <div v-sanitize="{ allowedTags: b,i,a }">
    <!-- Sanitize HTML content to prevent XSS attacks. directive -->
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'

// Configure your options here
const options = { allowedTags: b,i,a }
</script>

Released under the MIT License.