Skip to contentView the source on GitHub

no-set-html

Avoid set:html to prevent cross-site scripting (XSS) vulnerabilities.

Securitywarning by default ESLint rule

astro-doctor/no-set-html

Why it matters

set:html injects raw HTML into the DOM without escaping. Any user-controlled or third-party content rendered this way is an XSS vector. Use Astro's JSX interpolation, which escapes by default. JSON-LD data scripts are accepted when they use type="application/ld+json".

See the difference

Incorrect

Unsanitized HTML injection

astroIncorrect example
---
const userContent = await fetchUserBio()
---
<div set:html={userContent} />

Correct

Escaped interpolation or JSON-LD data

astroCorrect example
---
const structuredData = JSON.stringify({
  '@context': 'https://schema.org',
  '@type': 'WebSite',
  name: 'Example',
}).replace(/</g, '\u003c')
---
{/* Escaped by default */}
<p>{plainTextContent}</p>

{/* Non-executable structured data */}
<script type="application/ld+json" set:html={structuredData}></script>

Configure this check

Override the default severity in your ESLint config:

javascripteslint.config.js
import astroDoctorPlugin from '@santi020k/eslint-plugin-astro-doctor'

export default [
  astroDoctorPlugin.configs.recommended,
  {
    rules: {
      'astro-doctor/no-set-html': 'error',
    },
  },
]

Or set the severity for CLI scans in doctor.config.ts:

typescriptdoctor.config.ts
export default {
  rules: {
    'astro-doctor/no-set-html': 'error',
  },
}

Use 'error', 'warn', or 'off'. The configuration guide covers presets and per-file overrides.

Keep exploring security

Browse every rule and project audit