# Load all custom rules from a directory
npx htmlhint --rulesdir ./custom-rules/ index.html
```

### Enabling Custom Rules

[Section titled “Enabling Custom Rules”](#enabling-custom-rules)

After loading custom rules, you can enable them in several ways:

#### In Configuration File

[Section titled “In Configuration File”](#in-configuration-file)

```json
{
  "no-div-tags": true,
  "data-attributes-required": true,
  "max-attributes": 3
}
```

#### Via Command Line

[Section titled “Via Command Line”](#via-command-line)

```shell
npx htmlhint --rulesdir ./custom-rules/ --rules no-div-tags,data-attributes-required,max-attributes:3 index.html
```

#### Inline in HTML

[Section titled “Inline in HTML”](#inline-in-html)

```html
<!-- htmlhint no-div-tags:true,data-attributes-required:true -->
<html lang="en">
  <body>
    <div class="component">This will trigger warnings</div>
  </body>
</html>
```

## Parser Events

[Section titled “Parser Events”](#parser-events)

The HTML parser provides several events you can listen to:

* **`tagstart`**: Fired when a start tag is encountered
* **`tagend`**: Fired when an end tag is encountered
* **`text`**: Fired when text content is encountered
* **`comment`**: Fired when a comment is encountered
* **`cdata`**: Fired when CDATA is encountered
* **`doctype`**: Fired when a DOCTYPE declaration is encountered

### Event Object Properties

[Section titled “Event Object Properties”](#event-object-properties)

Event objects typically contain:

* **`tagName`**: The name of the tag
* **`attrs`**: Array of attributes
* **`line`**: Line number where the event occurred
* **`col`**: Column number where the event occurred
* **`raw`**: The raw HTML string for this element

## Reporter Methods

[Section titled “Reporter Methods”](#reporter-methods)

The reporter provides three methods for generating messages:

* **`reporter.warn(message, line, col, rule, raw)`**: Creates a warning message
* **`reporter.error(message, line, col, rule, raw)`**: Creates an error message
* **`reporter.info(message, line, col, rule, raw)`**: Creates an info message

## Best Practices

[Section titled “Best Practices”](#best-practices)

1. **Use arrow functions**: Always use arrow functions for event listeners to preserve the correct `this` context
2. **Use descriptive rule IDs**: Choose clear, descriptive names for your rules
3. **Provide helpful error messages**: Make error messages actionable and informative
4. **Handle options gracefully**: Always provide sensible defaults for rule options
5. **Test your rules**: Create test cases to ensure your rules work correctly
6. **Follow existing patterns**: Look at built-in rules for examples of good practices
7. **Document your rules**: Include clear descriptions and examples

## Directory Structure

[Section titled “Directory Structure”](#directory-structure)

When organizing multiple custom rules, you can use a directory structure:

```plaintext
custom-rules/
├── accessibility/
│   ├── aria-required.js
│   └── semantic-headings.js
├── performance/
│   ├── image-optimization.js
│   └── script-loading.js
└── style/
    ├── class-naming.js
    └── attribute-order.js
```

HTMLHint will recursively find all `.js` files in the specified directory and load them as custom rules.

## Troubleshooting

[Section titled “Troubleshooting”](#troubleshooting)

* **Rule not loading**: Check that your file exports a function and calls `HTMLHint.addRule()`
* **Rule not running**: Ensure the rule is enabled in your configuration
* **Parser errors**: Verify that you’re using the correct event names and object properties
* **Silent failures**: Custom rules that fail to load are silently ignored - check your JavaScript syntax
* **Incorrect rule reporting**: Make sure you’re using arrow functions for event listeners to preserve the `this` context