diff --git a/README.md b/README.md
index 43411bbf4..ada212702 100644
--- a/README.md
+++ b/README.md
@@ -60,7 +60,7 @@ yarn add eslint-plugin-jsx-a11y --dev
**Note:** If you installed ESLint globally (using the `-g` flag in npm, or the `global` prefix in yarn) then you must also install `eslint-plugin-jsx-a11y` globally.
-## Usage
+## Usage (legacy: `.eslintrc`)
Add `jsx-a11y` to the plugins section of your `.eslintrc` configuration file. You can omit the `eslint-plugin-` prefix:
@@ -108,6 +108,125 @@ configuration file by mapping each custom component name to a DOM element type.
}
```
+## Usage (new: `eslint.config.js`)
+
+From [`v8.21.0`](https://github.com/eslint/eslint/releases/tag/v8.21.0), eslint announced a new config system.
+In the new system, `.eslintrc*` is no longer used. `eslint.config.js` would be the default config file name.
+In eslint `v8`, the legacy system (`.eslintrc*`) would still be supported, while in eslint `v9`, only the new system would be supported.
+
+And from [`v8.23.0`](https://github.com/eslint/eslint/releases/tag/v8.23.0), eslint CLI starts to look up `eslint.config.js`.
+**So, if your eslint is `>=8.23.0`, you're 100% ready to use the new config system.**
+
+You might want to check out the official blog posts,
+
+-
+-
+-
+
+and the [official docs](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new).
+
+The default export of `eslint-plugin-jsx-a11y` is a plugin object.
+
+```js
+import jsxA11y from 'eslint-plugin-jsx-a11y';
+
+export default [
+ …
+ {
+ files: ['**/*.{js,mjs,cjs,jsx,ts,tsx}'],
+ plugins: {
+ 'jsx-a11y': jsxA11y,
+ },
+ languageOptions: {
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ },
+ rules: {
+ // ... any rules you want
+ 'jsx-a11y/alt-text': 'error',
+ },
+ // ... others are omitted for brevity
+ },
+ …
+]
+```
+
+There're also 2 shareable configs.
+
+- `eslint-plugin-jsx-a11y/strict`
+- `eslint-plugin-jsx-a11y/recommended`
+
+If your eslint.config.js is ESM, include the `.js` extension (e.g. `eslint-plugin-jsx-a11y/recommended.js`). Note that the next semver-major will require omitting the extension for these imports.
+
+**Note**: These configurations will import `eslint-plugin-jsx-a11y` and enable JSX in [`languageOptions.parserOptions`](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new#configuration-objects).
+
+In the new config system, the `plugin:` protocol(e.g. `plugin:jsx-a11y/recommended`) is no longer valid.
+As eslint does not automatically import the preset config (shareable config), you explicitly do it by yourself.
+
+```js
+import jsxA11y from 'eslint-plugin-jsx-a11y/recommended.js';
+
+export default [
+ …
+ jsxA11y, // This is not a plugin object, but a shareable config object
+ …
+];
+```
+
+You can of course add/override properties.
+
+**Note**: Our shareable configs does not preconfigure `files` or [`languageOptions.globals`](https://eslint.org/docs/latest/user-guide/configuring/configuration-files-new#configuration-objects).
+For most of the cases, you probably want to configure some properties by yourself.
+
+```js
+import jsxA11y from 'eslint-plugin-jsx-a11y/recommended.js';
+import globals from 'globals';
+
+export default [
+ …
+ {
+ ...jsxA11y,
+ files: ['**/*.{js,mjs,cjs,jsx,ts,tsx}'],
+ languageOptions: {
+ ...jsxA11y.languageOptions,
+ globals: {
+ ...globals.serviceworker,
+ ...globals.browser,
+ },
+ },
+ },
+ …
+];
+```
+
+The above example is same as the example below, as the new config system is based on chaining.
+
+```js
+import jsxA11y from 'eslint-plugin-jsx-a11y/recommended.js';
+import globals from 'globals';
+
+export default [
+ …
+ {
+ ...jsxA11y,
+ files: ['**/*.{js,ts,jsx,tsx}'],
+ },
+ {
+ files: ['**/*.{js,ts,jsx,tsx}'],
+ languageOptions: {
+ globals: {
+ ...globals.serviceworker,
+ ...globals.browser,
+ },
+ }
+ },
+ …
+];
+```
+
## Supported Rules
@@ -293,7 +412,7 @@ The following rules have extra options when in _recommended_ mode:
If you are developing new rules for this project, you can use the `create-rule`
script to scaffold the new files.
-```
+```bash
$ ./scripts/create-rule.js my-new-rule
```
diff --git a/recommended.js b/recommended.js
new file mode 100644
index 000000000..c63c42d09
--- /dev/null
+++ b/recommended.js
@@ -0,0 +1,2 @@
+// eslint-disable-next-line import/no-unresolved, import/extensions
+module.exports = require('./lib/configs/recommended');
diff --git a/src/configs/recommended.js b/src/configs/recommended.js
new file mode 100644
index 000000000..e01afaee7
--- /dev/null
+++ b/src/configs/recommended.js
@@ -0,0 +1,17 @@
+import jsxAlly from '..';
+
+const { configs, ...plugin } = jsxAlly;
+
+export default {
+ plugins: {
+ 'jsx-a11y': plugin,
+ },
+ languageOptions: {
+ parserOptions: {
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ },
+ rules: configs.recommended.rules,
+};
diff --git a/src/configs/strict.js b/src/configs/strict.js
new file mode 100644
index 000000000..11b943800
--- /dev/null
+++ b/src/configs/strict.js
@@ -0,0 +1,7 @@
+import jsxAlly from '..';
+import recommended from './recommended';
+
+export default {
+ ...recommended,
+ rules: jsxAlly.configs.strict.rules,
+};
diff --git a/strict.js b/strict.js
new file mode 100644
index 000000000..55356382f
--- /dev/null
+++ b/strict.js
@@ -0,0 +1,2 @@
+// eslint-disable-next-line import/no-unresolved, import/extensions
+module.exports = require('./lib/configs/strict');