@nuasite/checks 0.17.1 → 0.17.2

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.
Files changed (2) hide show
  1. package/README.md +174 -0
  2. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,174 @@
1
+ # @nuasite/checks
2
+
3
+ `@nuasite/checks` is an [Astro](https://astro.build/) integration that validates
4
+ your site for SEO, GEO (generative-engine optimization), performance, and
5
+ accessibility issues at build time. It runs after `astro build`, scans every
6
+ rendered HTML page, and reports problems before they reach production.
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ bun add -d @nuasite/checks
12
+ ```
13
+
14
+ The package expects `typescript@^5` as a peer dependency.
15
+
16
+ ## Quick start
17
+
18
+ Add the integration to your Astro config:
19
+
20
+ ```ts
21
+ import { defineConfig } from 'astro/config'
22
+ import checks from '@nuasite/checks'
23
+
24
+ export default defineConfig({
25
+ integrations: [checks()],
26
+ })
27
+ ```
28
+
29
+ All check domains (SEO, GEO, performance, accessibility) are enabled by default.
30
+ The build will fail if any errors are found.
31
+
32
+ ## Configuration
33
+
34
+ Pass an options object to customise behaviour:
35
+
36
+ ```ts
37
+ checks({
38
+ mode: 'essential', // 'auto' | 'full' | 'essential'
39
+ seo: { titleMaxLength: 70 },
40
+ geo: { minContentLength: 500 },
41
+ performance: { maxHtmlSize: 200_000 },
42
+ accessibility: true,
43
+ ai: false, // AI-powered checks (requires API key)
44
+ failOnError: true,
45
+ failOnWarning: false,
46
+ reportJson: true, // writes checks-report.json to dist
47
+ overrides: {
48
+ 'seo/title-missing': 'warning', // downgrade to warning
49
+ 'seo/noindex-detected': false, // disable entirely
50
+ },
51
+ })
52
+ ```
53
+
54
+ ### Disabling a domain
55
+
56
+ Set any domain to `false` to skip it entirely:
57
+
58
+ ```ts
59
+ checks({ performance: false })
60
+ ```
61
+
62
+ ### Check modes
63
+
64
+ | Mode | Behaviour |
65
+ | ----------- | ------------------------------------------------ |
66
+ | `auto` | Runs `essential` locally, `full` in CI |
67
+ | `essential` | Only checks marked as essential |
68
+ | `full` | Runs every registered check |
69
+
70
+ ## Built-in checks
71
+
72
+ ### SEO
73
+
74
+ | Check | Description |
75
+ | ----- | ----------- |
76
+ | `seo/title-missing` | Page has no `<title>` tag |
77
+ | `seo/title-empty` | `<title>` is empty |
78
+ | `seo/title-length` | Title exceeds max length |
79
+ | `seo/description-missing` | No meta description |
80
+ | `seo/description-length` | Description outside min/max range |
81
+ | `seo/canonical-missing` | No canonical link |
82
+ | `seo/canonical-invalid` | Canonical URL is malformed |
83
+ | `seo/canonical-mismatch` | Canonical doesn't match page URL |
84
+ | `seo/json-ld-invalid` | Invalid JSON-LD structured data |
85
+ | `seo/multiple-h1` | More than one `<h1>` on a page |
86
+ | `seo/no-h1` | No `<h1>` on a page |
87
+ | `seo/heading-skip` | Heading levels are skipped (e.g. h2 → h4) |
88
+ | `seo/og-title` | Missing Open Graph title |
89
+ | `seo/og-description` | Missing Open Graph description |
90
+ | `seo/og-image` | Missing Open Graph image |
91
+ | `seo/image-alt-missing` | Image without alt attribute |
92
+ | `seo/image-alt-quality` | Alt text is generic or unhelpful |
93
+ | `seo/meta-duplicate` | Duplicate meta tags |
94
+ | `seo/viewport-missing` | No viewport meta tag |
95
+ | `seo/noindex-detected` | Page has a noindex directive |
96
+ | `seo/twitter-card` | Missing Twitter Card meta tags |
97
+ | `seo/robots-txt` | Missing or invalid robots.txt (site-level) |
98
+ | `seo/sitemap-xml` | Missing sitemap.xml (site-level) |
99
+ | `seo/broken-internal-links` | Internal links that point to non-existent pages (site-level) |
100
+
101
+ ### GEO
102
+
103
+ | Check | Description |
104
+ | ----- | ----------- |
105
+ | `geo/content-too-short` | Page body text below minimum length |
106
+ | `geo/insufficient-headings` | Too few headings for content length |
107
+ | `geo/llms-txt` | Missing llms.txt file (site-level) |
108
+
109
+ ### Performance
110
+
111
+ | Check | Description |
112
+ | ----- | ----------- |
113
+ | `perf/html-size` | HTML document exceeds size limit |
114
+ | `perf/image-format` | Images not using modern formats (WebP/AVIF) |
115
+ | `perf/image-size` | Image files exceed size limit |
116
+ | `perf/lazy-loading` | Above-the-fold images missing lazy loading |
117
+ | `perf/render-blocking-script` | Render-blocking scripts without async/defer |
118
+ | `perf/inline-size` | Inline scripts/styles exceed size limit |
119
+ | `perf/total-requests` | Too many external resource requests |
120
+
121
+ ### Accessibility
122
+
123
+ | Check | Description |
124
+ | ----- | ----------- |
125
+ | `a11y/lang-attribute` | Missing `lang` attribute on `<html>` |
126
+ | `a11y/form-label` | Form inputs without associated labels |
127
+ | `a11y/aria-landmarks` | Missing ARIA landmark regions |
128
+ | `a11y/link-text` | Links with non-descriptive text ("click here") |
129
+ | `a11y/tabindex` | Positive tabindex values that break tab order |
130
+
131
+ ## Custom checks
132
+
133
+ Register your own checks alongside the built-ins:
134
+
135
+ ```ts
136
+ import type { Check } from '@nuasite/checks'
137
+
138
+ const noTodoCheck: Check = {
139
+ kind: 'page',
140
+ id: 'custom/no-todo',
141
+ name: 'No TODO in production',
142
+ domain: 'seo',
143
+ defaultSeverity: 'warning',
144
+ description: 'Flags pages that still contain TODO markers',
145
+ essential: false,
146
+ run({ html }) {
147
+ if (html.includes('TODO')) {
148
+ return [{ message: 'Page contains a TODO marker' }]
149
+ }
150
+ return []
151
+ },
152
+ }
153
+
154
+ checks({ customChecks: [noTodoCheck] })
155
+ ```
156
+
157
+ ## JSON report
158
+
159
+ Enable `reportJson` to write a machine-readable report to your dist directory
160
+ after every build:
161
+
162
+ ```ts
163
+ checks({ reportJson: true }) // → dist/checks-report.json
164
+ checks({ reportJson: 'my-report.json' }) // → dist/my-report.json
165
+ ```
166
+
167
+ ## Development
168
+
169
+ ```bash
170
+ cd packages/checks
171
+ bun test
172
+ ```
173
+
174
+ Tests use Bun's built-in runner with `happy-dom` for DOM simulation.
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "directory": "packages/checks"
13
13
  },
14
14
  "license": "Apache-2.0",
15
- "version": "0.17.1",
15
+ "version": "0.17.2",
16
16
  "module": "src/index.ts",
17
17
  "types": "src/index.ts",
18
18
  "type": "module",