Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
"nodownload",
"nofullscreen",
"controlslist",
"describedby"
"describedby",
"eslinthtml",

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type: Suggestion

1. Suggestion

I suggest using file names like eslint-html and eslint-js instead of eslinthtml and eslintjs, respectively.

2. The reason for the suggested changes

File names like eslintjs and eslinthtml are anti-patterns for spell checkers. Spell checkers don’t recognize two different words in eslintjs and eslinthtml, and users need to add eslintjs and eslinthtml to the list of exceptions. On the other hand, good spell checkers like CSpell should recognize two different words in eslint-html, eslint_html, and eslintHtml.

Thanks.

"eslintjs"
]
}
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ If you’d like to support html-eslint, please consider starring it on GitHub or
- [Configuration](https://html-eslint.org/docs/getting-started#configuration)
- [Editor Configuration](https://html-eslint.org/docs/getting-started#editor-configuration)
- [Integrating Template Engine](https://html-eslint.org/docs/integrating-template-engine)
- [Using with Other Plugins](https://html-eslint.org/docs/using-with-other-plugins)
1. [Rules](https://html-eslint.org/docs/rules)
1. [Playground](https://html-eslint.org/playground)
1. [Developer Guide](https://html-eslint.org/developer-guide.md)
Expand All @@ -48,6 +49,8 @@ If you’d like to support html-eslint, please consider starring it on GitHub or

This ESLint plugin supports linting HTML syntax and does not provide JavaScript syntax linting. To lint JavaScript in HTML, such as inline scripts, you can use [eslint-plugin-html](https://github.com/BenoitZugmeyer/eslint-plugin-html).

For detailed instructions on how to configure HTML ESLint alongside eslint-plugin-html, see the [Using with Other Plugins](https://html-eslint.org/docs/using-with-other-plugins) guide.

## License

Distributed under the MIT License. See [LICENSE](./LICENSE) for more information.
6 changes: 6 additions & 0 deletions docs/faq.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# FAQs

## How to use HTML ESLint with other plugins like eslint-plugin-html?

When using HTML ESLint alongside other plugins that process HTML files (such as `eslint-plugin-html` for linting JavaScript inside HTML), you need to use separate configuration files. This is because different parsers and processing approaches conflict when applied to the same files.

See the [Using HTML ESLint with Other Plugins](./using-with-other-plugins.md) guide for detailed instructions and examples.

## Problem when using typescript-eslint typed linting.

```
Expand Down
236 changes: 236 additions & 0 deletions docs/using-with-other-plugins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,236 @@
# Using HTML ESLint with Other Plugins

## Overview

HTML ESLint focuses on linting HTML syntax and structure. However, you may also want to lint JavaScript code within HTML files (such as inline `<script>` tags) or use other ESLint plugins that process HTML files. This guide explains how to configure HTML ESLint alongside other plugins.

## Linting JavaScript Inside HTML

HTML ESLint does not lint JavaScript code within HTML files. To lint JavaScript in HTML (such as inline scripts), you can use [eslint-plugin-html](https://github.com/BenoitZugmeyer/eslint-plugin-html).

### Why Separate Configuration Files?

When using both HTML ESLint and eslint-plugin-html, **you need separate configuration files**. This is because:

1. HTML ESLint uses a custom parser (`@html-eslint/parser`) that understands HTML syntax
2. eslint-plugin-html uses a different approach to extract and lint JavaScript from HTML
3. When both are configured for the same `*.html` files in a single config, ESLint may try to apply JavaScript rules to HTML syntax, causing errors

This limitation is due to how ESLint's parser system works and is not specific to HTML ESLint. For more context, see:

- [ESLint Discussion #18808](https://github.com/eslint/eslint/discussions/18808)
- [ESLint Issue #14286](https://github.com/eslint/eslint/issues/14286)
- [ESLint Issue #17655](https://github.com/eslint/eslint/issues/17655)

### Configuration Example

#### Step 1: Create a Configuration for HTML ESLint

Create `eslinthtml.config.mjs` for HTML syntax linting:

```js
import html from "@html-eslint/eslint-plugin";

export default [
{
files: ["**/*.html"],
plugins: {
html,
},
extends: ["html/recommended"],
language: "html/html",
rules: {
// Customize HTML linting rules
"html/indent": ["error", 2],
},
},
];
```

#### Step 2: Create a Configuration for JavaScript in HTML

Create `eslintjs.config.mjs` for JavaScript linting within HTML:

```js
import js from "@eslint/js";
import htmlPlugin from "eslint-plugin-html";

export default [
{
files: ["**/*.html"],
plugins: {
html: htmlPlugin,
},
rules: {
...js.configs.recommended.rules,
// Customize JavaScript rules for inline scripts
"no-unused-vars": "error",
"prefer-const": "error",
},
},
];
```

#### Step 3: Run ESLint with Each Configuration

Run ESLint separately with each configuration file:

```bash
# Lint HTML syntax
npx eslint --config eslinthtml.config.mjs "**/*.html"

# Lint JavaScript in HTML
npx eslint --config eslintjs.config.mjs "**/*.html"
```

### Using npm Scripts

You can simplify this workflow by adding scripts to your `package.json`:

```json
{
"scripts": {
"lint:html": "eslint --config eslinthtml.config.mjs \"**/*.html\"",
"lint:js-in-html": "eslint --config eslintjs.config.mjs \"**/*.html\"",
"lint": "npm run lint:html && npm run lint:js-in-html"
}
}
```

Then run:

```bash
npm run lint
```

## Complete Working Example

Here's a complete example with all necessary files:

### Installation

```bash
npm install --save-dev eslint @html-eslint/eslint-plugin @html-eslint/parser eslint-plugin-html @eslint/js
```

### HTML File (`example.html`)

```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Example</title>
<script>
let message = "Hello World";
console.log(message);
</script>
</head>
<body>
<p>Welcome!</p>
</body>
</html>
```

### HTML ESLint Configuration (`eslinthtml.config.mjs`)

```js
import html from "@html-eslint/eslint-plugin";

export default [
{
files: ["**/*.html"],
plugins: {
html,
},
extends: ["html/recommended"],
language: "html/html",
rules: {
"html/require-doctype": "error",
"html/no-duplicate-id": "error",
},
},
];
```

### JavaScript in HTML Configuration (`eslintjs.config.mjs`)

```js
import js from "@eslint/js";
import htmlPlugin from "eslint-plugin-html";

export default [
{
files: ["**/*.html"],
plugins: {
html: htmlPlugin,
},
rules: {
...js.configs.recommended.rules,
"no-unused-vars": "error",
"prefer-const": "error",
},
},
];
```

### Package.json Scripts

```json
{
"scripts": {
"lint:html": "eslint --config eslinthtml.config.mjs \"**/*.html\"",
"lint:js": "eslint --config eslintjs.config.mjs \"**/*.html\"",
"lint": "npm run lint:html && npm run lint:js"
}
}
```

## Alternative Approaches

### Separate HTML and JS Files

If possible, consider separating your JavaScript into `.js` files and referencing them in HTML:

```html
<script src="script.js"></script>
```

This allows you to:

- Use a single ESLint configuration
- Lint `.html` files with HTML ESLint
- Lint `.js` files with standard JavaScript rules

### CI/CD Integration

When integrating with CI/CD, run both linting commands:

```yaml
# Example GitHub Actions workflow
- name: Lint HTML syntax
run: npx eslint --config eslinthtml.config.mjs "**/*.html"

- name: Lint JavaScript in HTML
run: npx eslint --config eslintjs.config.mjs "**/*.html"
```

## Troubleshooting

### Error: "Cannot read properties of undefined"

If you see errors like `Cannot read properties of undefined (reading 'ignorePatternRegExp')` when trying to use both plugins in one config, this confirms you need separate configuration files.

### JavaScript Rules Applied to HTML

If you see JavaScript linting errors on HTML tags, ensure:

1. You're using the correct config file for each purpose
2. The `files` pattern matches appropriately
3. You haven't mixed both parsers in the same configuration object

## Related Documentation

- [Getting Started](./getting-started.md)
- [FAQ](./faq.md)
- [Integrating Template Engines](./integrating-template-engine.md)
20 changes: 20 additions & 0 deletions packages/website/src/components/nav.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,26 @@
>
</a>
</li>
<li>
<a href="~/src/docs/using-with-other-plugins.html" class="w-full flex items-center">
<div class="w-[28px] h-[28px] rounded-[6px] p-[6px] border-[1px] border-gray-300 drop-shadow-[4px_0_2px_#E8EBEF] mr-[12px]">
<img
src="~/src/assets/icon-code.svg"
alt=""
width="14"
height="14"
>
</div>
<span class="title5">Using with Other Plugins</span>
<img
src="~/src/assets/icon-chevron-right.svg"
alt=""
class="ml-auto"
width="20"
height="20"
>
</a>
</li>
<li>
<a href="~/src/docs/developer-guide.html" class="w-full flex items-center">
<div class="w-[28px] h-[28px] rounded-[6px] p-[6px] border-[1px] border-gray-300 drop-shadow-[4px_0_2px_#E8EBEF] mr-[12px]">
Expand Down