next-a11y 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,7 +13,7 @@ next-a11y writes the fix.
13
13
 
14
14
  95% of websites fail WCAG 2.2 AA. The same 6 error types. Every year. For 5 years straight. ([WebAIM Million 2025](https://webaim.org/projects/million/))
15
15
 
16
- next-a11y fixes 4 of those 6 automatically — and catches the rest.
16
+ next-a11y fixes 5 of those 6 automatically: **missing alt text**, **missing form labels**, **empty links**, **empty buttons**, **missing lang**. The 6th low contrast — requires runtime color analysis and isn't detectable from source. We also catch the rest (heading order, skip nav, etc.).
17
17
 
18
18
  ## Quick start
19
19
 
@@ -23,33 +23,68 @@ npx next-a11y scan ./src # see what's broken
23
23
  npx next-a11y scan ./src --fix # fix it
24
24
  ```
25
25
 
26
- ### Before
26
+ ### Before (report only)
27
27
 
28
28
  ```
29
- ╭──────────────────────────────────────╮
30
- Accessibility Score: 34 / 100 🔴 │
31
- ╰──────────────────────────────────────╯
32
-
33
- 🖼️ 12 images missing alt text -24 pts
34
- 🔘 4 icon buttons without aria-label -8 pts
35
- 🔗 2 icon links without aria-label -4 pts
36
- 📝 3 inputs without label -9 pts
37
- 🌐 1 missing lang on <html> -5 pts
38
- ...and 21 more issues
39
-
29
+ next-a11y v0.1.9
30
+ Scanned 13 files
31
+
32
+ Heuristic score: 34 / 100 Poor
33
+
34
+ [AI] fixes available:
35
+ [img] 12 images missing alt text -24 pts
36
+ src/components/Hero.tsx:7 Image is missing alt text
37
+ src/components/ProductCard.tsx:8 Image has meaningless alt text: "IMG_123.jpg"
38
+ [btn] 4 buttons without accessible name -8 pts
39
+ src/components/Navbar.tsx:12 — Button has no accessible name
40
+ [lnk] 2 links without accessible name -4 pts
41
+ [inp] 3 inputs without label -9 pts
42
+ Auto fixes available:
43
+ [lng] 1 missing lang on <html> -5 pts
44
+ Warnings (manual review needed):
45
+ [img] 2 next/image without sizes -2 pts
46
+ [nav] 1 missing skip navigation link -3 pts
47
+ [hdg] 1 heading hierarchy violations -1 pts
48
+ [div] 1 div used as interactive element -1 pts
49
+
50
+ ----------------------------------------
40
51
  38 fixable · 4 warnings · Run --fix to apply
41
52
  ```
42
53
 
43
- ### After
54
+ ### After (with --fix)
44
55
 
45
56
  ```
46
- ╭──────────────────────────────────────╮
47
- │ Accessibility Score: 97 / 100 🟢 │
48
- ╰──────────────────────────────────────╯
57
+ Generating text using openai/gpt-4o-mini
58
+
59
+ [AI] resolved 1/18 → "Hero image with welcome message"
60
+ [AI] resolved 2/18 → "Add to cart"
61
+ [AI] resolved 3/18 → "Visit Twitter"
62
+ ...
63
+ Total tokens used: 2,450
64
+
65
+ Fixes applied:
49
66
 
50
- All auto-fixable issues resolved
67
+ [FIXED] src/components/Hero.tsx:7 added alt text "Hero image with welcome message"
68
+ [FIXED] src/components/Navbar.tsx:12 added aria-label "Add to cart"
69
+ [FIXED] src/components/Footer.tsx:7 added rel="noopener noreferrer"
70
+ [FIXED] src/app/layout.tsx:11 added lang "en"
71
+ [FIXED] src/app/page.tsx:1 added metadata.title "Home"
72
+ ...
51
73
 
52
- 0 fixable · 4 warnings · Score: 34 → 97 (+63 pts)
74
+ next-a11y v0.1.9
75
+ Scanned 13 files
76
+
77
+ Heuristic score: 97 / 100 Good
78
+
79
+ Warnings (manual review needed):
80
+ [img] 2 next/image without sizes -2 pts
81
+ [nav] 1 missing skip navigation link -3 pts
82
+ [hdg] 1 heading hierarchy violations -1 pts
83
+ [div] 1 div used as interactive element -1 pts
84
+
85
+ ----------------------------------------
86
+ [FIXED] 31 · 4 warnings
87
+ Score: 34 -> 97 (+63 pts)
53
88
  ```
54
89
 
55
90
  ## What it fixes
@@ -86,29 +121,41 @@ npx next-a11y scan ./src --fix # fix it
86
121
 
87
122
  | Rule | What it does |
88
123
  | -------------------- | -------------------------------------------------------- |
89
- | `heading-order` | Flags `h1` → `h3` skips |
124
+ | `heading-order` | Flags `h1` → `h3` skips (shows heading text in message) |
90
125
  | `no-div-interactive` | Flags `<div onClick>` without `role` or keyboard handler |
91
126
 
127
+ ## Locale support
128
+
129
+ Generated labels (aria-labels, alt text, page titles) follow the target locale:
130
+
131
+ ```bash
132
+ npx next-a11y scan ./src --fix --locale pl
133
+ ```
134
+
135
+ Supported: `en`, `pl`, `de`, `es`, `fr`. Known icons (Twitter, GitHub, Cart, etc.) use locale-aware heuristics; others are generated by AI in the requested language.
136
+
92
137
  ## No AI? No problem.
93
138
 
94
139
  ```bash
95
- npx next-a11y scan ./src --fix --no-ai
140
+ npx next-a11y scan ./src --fix --no-ai # not recommended for best results
96
141
  ```
97
142
 
98
- 9 deterministic rules work without any API key or AI setup.
143
+ 9 deterministic rules work without any API key or AI setup. Not recommended for best results — AI fixes handle alt text, labels, and page titles more accurately.
99
144
 
100
145
  ## AI providers
101
146
 
102
147
  Works with any major provider through [Vercel AI SDK](https://sdk.vercel.ai/):
103
148
 
104
149
  ```bash
105
- npm install @ai-sdk/google # free tier: 1500 req/day
150
+ npm install -D @ai-sdk/google # free tier: 1500 req/day
151
+ # or
152
+ npm install -D @ai-sdk/openai # gpt-4o-mini ~$0.001/fix
106
153
  # or
107
- npm install @ai-sdk/openai # gpt-4.1-nano ~$0.001/fix
154
+ npm install -D @ai-sdk/anthropic # claude-haiku ~$0.001/fix
108
155
  # or
109
- npm install @ai-sdk/anthropic # claude-haiku ~$0.001/fix
156
+ npm install -D @openrouter/ai-sdk-provider # 200+ models via one API
110
157
  # or
111
- npm install ollama-ai-provider # local, $0
158
+ npm install -D ollama-ai-provider # local, $0
112
159
  ```
113
160
 
114
161
  ## Config
@@ -135,6 +182,45 @@ export default defineConfig({
135
182
  });
136
183
  ```
137
184
 
185
+ ## CLI reference
186
+
187
+ ### scan
188
+
189
+ ```bash
190
+ npx next-a11y scan <path> [options]
191
+ ```
192
+
193
+ | Option | Description |
194
+ | --------------------- | -------------------------------------------------------------------- |
195
+ | `--fix` | Auto-fix issues |
196
+ | `-i, --interactive` | Review each fix interactively |
197
+ | `--no-ai` | Skip AI-powered fixes (deterministic only, not recommended) |
198
+ | `--provider <name>` | Override AI provider (openai, anthropic, google, ollama, openrouter) |
199
+ | `--model <name>` | Override AI model |
200
+ | `--fill-alt` | Replace empty `alt=""` with AI-generated text |
201
+ | `--locale <locale>` | Locale for generated content (e.g. en, pl, de) |
202
+ | `--min-score <score>` | Exit code 1 if heuristic score below threshold |
203
+ | `-q, --quiet` | Minimal output (no progress, one-line report) |
204
+
205
+ ### init
206
+
207
+ ```bash
208
+ npx next-a11y init
209
+ ```
210
+
211
+ Creates `a11y.config.ts`, optionally installs AI SDK package, adds `.a11y-cache` to `.gitignore`.
212
+
213
+ ### cache
214
+
215
+ ```bash
216
+ npx next-a11y cache stats # Show cache statistics
217
+ npx next-a11y cache clear # Clear the cache
218
+ ```
219
+
220
+ ## Scoring
221
+
222
+ The 0–100 score is a **heuristic** — it does not certify WCAG compliance. It's a weighted count of detected violations (e.g. missing alt −2 pts, missing lang −5 pts). Use it to track progress and gate CI; don't treat 97/100 as "WCAG AA compliant."
223
+
138
224
  ## CI
139
225
 
140
226
  ```yaml
@@ -157,7 +243,7 @@ npx next-a11y scan . --fix
157
243
 
158
244
  ## How it works
159
245
 
160
- Static analysis codemod. Parses your source with [ts-morph](https://github.com/dsherret/ts-morph), runs 15 rules against the AST, generates fixes (AI or pattern-based), writes them back to your files. No browser. No runtime. Ships zero code to production.
246
+ Static analysis codemod. Parses your source with [ts-morph](https://github.com/dsherret/ts-morph), runs 15 rules against the AST, generates fixes (AI or pattern-based), writes them back to your files. Fixes are applied concurrently per file. Cache keys include locale so `--locale pl` and `--locale en` don't overwrite each other. Use `--quiet` / `-q` for minimal output (CI-friendly). No browser. No runtime. Ships zero code to production.
161
247
 
162
248
  ## License
163
249
 
@@ -7,16 +7,18 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
7
7
 
8
8
  // src/config/schema.ts
9
9
  var PROVIDER_DEFAULTS = {
10
- openai: "gpt-4.1-nano",
10
+ openai: "gpt-4o-mini",
11
11
  anthropic: "claude-haiku-4-5-20251001",
12
12
  google: "gemini-2.0-flash-lite",
13
- ollama: "llava"
13
+ ollama: "llava",
14
+ openrouter: "openai/gpt-4o-mini"
14
15
  };
15
16
  var PROVIDER_ENV = {
16
17
  openai: "OPENAI_API_KEY",
17
18
  anthropic: "ANTHROPIC_API_KEY",
18
19
  google: "GOOGLE_GENERATIVE_AI_API_KEY",
19
- ollama: null
20
+ ollama: null,
21
+ openrouter: "OPENROUTER_API_KEY"
20
22
  };
21
23
  var DEFAULT_RULES = {
22
24
  "img-alt": "fix",