@rankture/cli 0.1.0
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/LICENSE +21 -0
- package/README.md +637 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.mjs +2877 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/index.d.ts +339 -0
- package/dist/index.mjs +2648 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +72 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rankture
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
# @rankture/cli
|
|
2
|
+
|
|
3
|
+
> SEO audit tool for developers — check your sites before deploy
|
|
4
|
+
|
|
5
|
+
A fast, offline-first SEO checker that runs on your local files. Supports 15+ file types including HTML, JSX/TSX, Vue, Svelte, Astro, Markdown, and template engines. Perfect for CI/CD pipelines, pre-commit hooks, or manual checks before deployment.
|
|
6
|
+
|
|
7
|
+
## Supported File Types
|
|
8
|
+
|
|
9
|
+
| Type | Extensions | Metadata Extraction |
|
|
10
|
+
|------|------------|---------------------|
|
|
11
|
+
| **HTML** | `.html`, `.htm` | Full SEO checks including viewport, canonical |
|
|
12
|
+
| **Astro** | `.astro` | Frontmatter `title`, `description`; `<Image>` component |
|
|
13
|
+
| **React/Next.js** | `.jsx`, `.tsx` | `export const metadata`, `<Head>`, `<Image>`, `<Link>` |
|
|
14
|
+
| **Vue/Nuxt** | `.vue` | `useSeoMeta()`, `useHead()`, `definePageMeta()`, `<NuxtImg>`, `<NuxtLink>` |
|
|
15
|
+
| **Svelte/SvelteKit** | `.svelte` | `<svelte:head>`, Svelte syntax stripped |
|
|
16
|
+
| **Markdown** | `.md`, `.mdx` | Frontmatter, heading/image/link conversion |
|
|
17
|
+
| **Nunjucks** | `.njk` | Block tags stripped, variables marked as dynamic |
|
|
18
|
+
| **EJS** | `.ejs` | Scriptlets stripped, expressions marked as dynamic |
|
|
19
|
+
| **Handlebars** | `.hbs` | Block helpers stripped, expressions marked as dynamic |
|
|
20
|
+
| **Pug** | `.pug` | Basic tag extraction (h1-h6, img, a, title, meta) |
|
|
21
|
+
| **Liquid** | `.liquid` | Shopify/11ty support, schema blocks stripped |
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Global install
|
|
27
|
+
npm install -g @rankture/cli
|
|
28
|
+
|
|
29
|
+
# Or use with npx (no install)
|
|
30
|
+
npx @rankture/cli check ./dist
|
|
31
|
+
|
|
32
|
+
# Or add to your project
|
|
33
|
+
npm install --save-dev @rankture/cli
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# Check your built site (HTML output)
|
|
40
|
+
rankture check ./dist
|
|
41
|
+
|
|
42
|
+
# Check source files directly
|
|
43
|
+
rankture check ./src/pages
|
|
44
|
+
rankture check ./src/content
|
|
45
|
+
|
|
46
|
+
# Check with JSON output
|
|
47
|
+
rankture check ./dist --format json
|
|
48
|
+
|
|
49
|
+
# Fail build on critical issues
|
|
50
|
+
rankture check ./dist --fail-on critical
|
|
51
|
+
|
|
52
|
+
# Write report to file
|
|
53
|
+
rankture check ./dist --format json --output seo-report.json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Commands
|
|
57
|
+
|
|
58
|
+
### `check <path>`
|
|
59
|
+
|
|
60
|
+
Run SEO checks on local files.
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
rankture check ./dist # Built HTML
|
|
64
|
+
rankture check ./src/pages # Astro/Next.js pages
|
|
65
|
+
rankture check ./src/content # Markdown content
|
|
66
|
+
rankture check ./index.html # Single file
|
|
67
|
+
rankture check ./pages/index.vue # Vue component
|
|
68
|
+
rankture check ./dist --watch # Watch mode - re-run on changes
|
|
69
|
+
rankture check ./src --changed # Only check git changed files
|
|
70
|
+
rankture check ./src --staged # Only check git staged files (pre-commit)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Options:**
|
|
74
|
+
|
|
75
|
+
| Option | Description | Default |
|
|
76
|
+
|--------|-------------|---------|
|
|
77
|
+
| `-f, --format <format>` | Output format: `terminal`, `json`, `html` | `terminal` |
|
|
78
|
+
| `-o, --output <file>` | Write output to file | stdout |
|
|
79
|
+
| `--fail-on <level>` | Exit code 1 on: `none`, `critical`, `warning`, `any` | `none` |
|
|
80
|
+
| `--ignore <patterns...>` | Glob patterns to ignore | `[]` |
|
|
81
|
+
| `--config <file>` | Config file path | - |
|
|
82
|
+
| `-w, --watch` | Watch for file changes and re-run checks | `false` |
|
|
83
|
+
| `--changed` | Only check files changed in git (staged + unstaged) | `false` |
|
|
84
|
+
| `--staged` | Only check git staged files (for pre-commit hooks) | `false` |
|
|
85
|
+
|
|
86
|
+
**Output Formats:**
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Terminal output (default) - colorful, human-readable
|
|
90
|
+
rankture check ./dist
|
|
91
|
+
|
|
92
|
+
# JSON output - for programmatic processing
|
|
93
|
+
rankture check ./dist -f json -o seo-report.json
|
|
94
|
+
|
|
95
|
+
# HTML output - visual report to open in browser
|
|
96
|
+
rankture check ./dist -f html -o seo-report.html
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### `init`
|
|
100
|
+
|
|
101
|
+
Create a `rankture.config.json` configuration file.
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
rankture init # Create config file
|
|
105
|
+
rankture init --force # Overwrite existing config
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### `validate <type> <file>`
|
|
109
|
+
|
|
110
|
+
Validate SEO assets like sitemaps, robots.txt, or schema.
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
rankture validate sitemap ./public/sitemap.xml
|
|
114
|
+
rankture validate robots ./public/robots.txt
|
|
115
|
+
rankture validate schema ./schema.json # Coming soon
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Robots.txt Validation:**
|
|
119
|
+
- User-agent directive presence
|
|
120
|
+
- Sitemap directive presence
|
|
121
|
+
- Valid directive syntax
|
|
122
|
+
- Disallow/Allow path format
|
|
123
|
+
- Crawl-delay values
|
|
124
|
+
- Common mistakes (blocking all, blocking important paths)
|
|
125
|
+
|
|
126
|
+
**Sitemap.xml Validation:**
|
|
127
|
+
- Valid XML structure
|
|
128
|
+
- Required `<loc>` tags for all URLs
|
|
129
|
+
- Valid URL formats
|
|
130
|
+
- Optional tag validation (`<lastmod>`, `<changefreq>`, `<priority>`)
|
|
131
|
+
- File size warnings (Google limit: 50MB, 50,000 URLs)
|
|
132
|
+
- URL accessibility sampling
|
|
133
|
+
|
|
134
|
+
### `audit <url>` (Coming Soon)
|
|
135
|
+
|
|
136
|
+
Audit a live URL with optional Pro features.
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
rankture audit https://example.com
|
|
140
|
+
rankture audit https://example.com --api-key YOUR_KEY --sync
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Checks Performed
|
|
144
|
+
|
|
145
|
+
The CLI runs **21 offline checks** across 5 categories:
|
|
146
|
+
|
|
147
|
+
### Technical SEO (HTML only)
|
|
148
|
+
- ✓ Viewport meta tag*
|
|
149
|
+
- ✓ Language attribute*
|
|
150
|
+
- ✓ Canonical URL*
|
|
151
|
+
- ✓ Robots meta tag
|
|
152
|
+
|
|
153
|
+
*Skipped for source files since these are typically in layouts
|
|
154
|
+
|
|
155
|
+
### On-Page SEO (All files)
|
|
156
|
+
- ✓ Title tag (exists, length, uniqueness)
|
|
157
|
+
- ✓ Meta description (exists, length)
|
|
158
|
+
- ✓ Single H1 tag
|
|
159
|
+
- ✓ Heading hierarchy (no skipped levels)
|
|
160
|
+
- ✓ Image alt text
|
|
161
|
+
- ✓ Internal link validity
|
|
162
|
+
|
|
163
|
+
### Structured Data (HTML only)
|
|
164
|
+
- ✓ JSON-LD presence
|
|
165
|
+
- ✓ Schema.org validation
|
|
166
|
+
- ✓ Speakable schema (voice/AI assistant optimization)
|
|
167
|
+
- ✓ Offer/Product schema (pricing, discounts, availability)
|
|
168
|
+
- ✓ FAQ schema (question/answer structured data)
|
|
169
|
+
- ✓ HowTo schema (step-by-step instructions)
|
|
170
|
+
|
|
171
|
+
### Social / Open Graph (HTML only)
|
|
172
|
+
- ✓ og:title, og:description, og:image
|
|
173
|
+
- ✓ og:type, og:url
|
|
174
|
+
- ✓ twitter:card, twitter:title, twitter:description, twitter:image
|
|
175
|
+
|
|
176
|
+
### Accessibility (HTML only)
|
|
177
|
+
- ✓ Skip navigation link
|
|
178
|
+
- ✓ Main landmark (`<main>`)
|
|
179
|
+
- ✓ Navigation landmark (`<nav>`)
|
|
180
|
+
- ✓ Buttons with accessible names
|
|
181
|
+
- ✓ Links with accessible names
|
|
182
|
+
- ✓ Form inputs with labels
|
|
183
|
+
- ✓ Positive tabindex anti-pattern
|
|
184
|
+
- ✓ Focus outline removal
|
|
185
|
+
- ✓ Autoplay video with audio
|
|
186
|
+
- ✓ Color contrast (basic check)
|
|
187
|
+
|
|
188
|
+
## AI & Voice Optimization
|
|
189
|
+
|
|
190
|
+
The CLI includes specialized checks for AI assistants and voice search readiness:
|
|
191
|
+
|
|
192
|
+
### Speakable Schema
|
|
193
|
+
Validates that pages have `SpeakableSpecification` schema for voice assistants (Google Assistant, Alexa, Siri):
|
|
194
|
+
|
|
195
|
+
```html
|
|
196
|
+
<script type="application/ld+json">
|
|
197
|
+
{
|
|
198
|
+
"@type": "WebPage",
|
|
199
|
+
"speakable": {
|
|
200
|
+
"@type": "SpeakableSpecification",
|
|
201
|
+
"cssSelector": [".speakable-intro", ".speakable-faq"]
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
</script>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Offer/Product Schema
|
|
208
|
+
Validates pricing and product information for rich results:
|
|
209
|
+
|
|
210
|
+
```html
|
|
211
|
+
<script type="application/ld+json">
|
|
212
|
+
{
|
|
213
|
+
"@type": "Product",
|
|
214
|
+
"offers": {
|
|
215
|
+
"@type": "Offer",
|
|
216
|
+
"price": "29.00",
|
|
217
|
+
"priceCurrency": "USD",
|
|
218
|
+
"availability": "https://schema.org/InStock"
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
</script>
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### FAQ Schema
|
|
225
|
+
Validates FAQ structured data for featured snippets:
|
|
226
|
+
|
|
227
|
+
```html
|
|
228
|
+
<script type="application/ld+json">
|
|
229
|
+
{
|
|
230
|
+
"@type": "FAQPage",
|
|
231
|
+
"mainEntity": [
|
|
232
|
+
{
|
|
233
|
+
"@type": "Question",
|
|
234
|
+
"name": "What is SEO?",
|
|
235
|
+
"acceptedAnswer": {
|
|
236
|
+
"@type": "Answer",
|
|
237
|
+
"text": "SEO stands for Search Engine Optimization..."
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
]
|
|
241
|
+
}
|
|
242
|
+
</script>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### HowTo Schema
|
|
246
|
+
Validates step-by-step instructions for rich results:
|
|
247
|
+
|
|
248
|
+
```html
|
|
249
|
+
<script type="application/ld+json">
|
|
250
|
+
{
|
|
251
|
+
"@type": "HowTo",
|
|
252
|
+
"name": "How to optimize your website",
|
|
253
|
+
"step": [
|
|
254
|
+
{ "@type": "HowToStep", "text": "Run an SEO audit" },
|
|
255
|
+
{ "@type": "HowToStep", "text": "Fix critical issues" }
|
|
256
|
+
]
|
|
257
|
+
}
|
|
258
|
+
</script>
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Source File Intelligence
|
|
262
|
+
|
|
263
|
+
When checking source files (`.astro`, `.tsx`, `.md`, etc.), the CLI:
|
|
264
|
+
|
|
265
|
+
### Metadata Extraction
|
|
266
|
+
- **Astro frontmatter** - Reads `title` and `description` from YAML frontmatter
|
|
267
|
+
- **Next.js `metadata`** - Parses `export const metadata: Metadata = { ... }`
|
|
268
|
+
- **Vue composables** - Extracts from `useSeoMeta()`, `useHead()`, `definePageMeta()`
|
|
269
|
+
- **Svelte head** - Reads title and meta from `<svelte:head>` block
|
|
270
|
+
|
|
271
|
+
### Component Normalization
|
|
272
|
+
- **Image components** - `<Image>`, `<NuxtImg>`, `<Picture>` → `<img>` for alt text checking
|
|
273
|
+
- **Link components** - `<Link>`, `<NuxtLink>` → `<a>` for internal link checking
|
|
274
|
+
- **JSX curly braces** - Converts `{variable}` to `[dynamic]` markers
|
|
275
|
+
|
|
276
|
+
### Template Engines
|
|
277
|
+
- **Nunjucks** - Strips `{% %}` blocks, marks `{{ }}` as dynamic
|
|
278
|
+
- **EJS** - Strips `<% %>` scriptlets, marks `<%= %>` as dynamic
|
|
279
|
+
- **Liquid** - Strips `{% %}` tags and `{% schema %}` blocks
|
|
280
|
+
- **Handlebars** - Strips `{{# }}` helpers, marks `{{ }}` as dynamic
|
|
281
|
+
|
|
282
|
+
### Smart Check Handling
|
|
283
|
+
- **Skips layout checks** - Doesn't flag missing viewport/canonical/lang (handled by layouts)
|
|
284
|
+
- **Preserves content checks** - Still validates title, description, headings, images, links
|
|
285
|
+
|
|
286
|
+
## Framework-Specific Examples
|
|
287
|
+
|
|
288
|
+
### Next.js (App Router)
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
# Check your pages
|
|
292
|
+
rankture check ./app
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
The CLI extracts metadata from:
|
|
296
|
+
```tsx
|
|
297
|
+
// app/page.tsx
|
|
298
|
+
export const metadata: Metadata = {
|
|
299
|
+
title: 'Home Page',
|
|
300
|
+
description: 'Welcome to our site',
|
|
301
|
+
};
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Astro
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
# Check pages and content
|
|
308
|
+
rankture check ./src/pages ./src/content
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Extracts frontmatter:
|
|
312
|
+
```astro
|
|
313
|
+
---
|
|
314
|
+
title: "Blog Post Title"
|
|
315
|
+
description: "Post description for SEO"
|
|
316
|
+
---
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Nuxt 3
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
# Check pages
|
|
323
|
+
rankture check ./pages
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Extracts from composables:
|
|
327
|
+
```vue
|
|
328
|
+
<script setup>
|
|
329
|
+
useSeoMeta({
|
|
330
|
+
title: 'Page Title',
|
|
331
|
+
description: 'Page description',
|
|
332
|
+
});
|
|
333
|
+
</script>
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### SvelteKit
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
# Check routes
|
|
340
|
+
rankture check ./src/routes
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
Extracts from `<svelte:head>`:
|
|
344
|
+
```svelte
|
|
345
|
+
<svelte:head>
|
|
346
|
+
<title>Page Title</title>
|
|
347
|
+
<meta name="description" content="Description" />
|
|
348
|
+
</svelte:head>
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Markdown/MDX (Content Collections)
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
# Check content directory
|
|
355
|
+
rankture check ./content ./src/content
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Extracts frontmatter and converts syntax:
|
|
359
|
+
```md
|
|
360
|
+
---
|
|
361
|
+
title: "Article Title"
|
|
362
|
+
description: "Article description"
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
# Main Heading
|
|
366
|
+
|
|
367
|
+

|
|
368
|
+
[Link text](/page)
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
## CI/CD Integration
|
|
372
|
+
|
|
373
|
+
### GitHub Actions
|
|
374
|
+
|
|
375
|
+
```yaml
|
|
376
|
+
name: SEO Check
|
|
377
|
+
on: [push, pull_request]
|
|
378
|
+
|
|
379
|
+
jobs:
|
|
380
|
+
seo:
|
|
381
|
+
runs-on: ubuntu-latest
|
|
382
|
+
steps:
|
|
383
|
+
- uses: actions/checkout@v4
|
|
384
|
+
- uses: actions/setup-node@v4
|
|
385
|
+
with:
|
|
386
|
+
node-version: '20'
|
|
387
|
+
|
|
388
|
+
- name: Build site
|
|
389
|
+
run: npm run build
|
|
390
|
+
|
|
391
|
+
- name: Run SEO checks
|
|
392
|
+
run: npx @rankture/cli check ./dist --fail-on critical
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### GitLab CI
|
|
396
|
+
|
|
397
|
+
```yaml
|
|
398
|
+
seo_check:
|
|
399
|
+
stage: test
|
|
400
|
+
script:
|
|
401
|
+
- npm run build
|
|
402
|
+
- npx @rankture/cli check ./dist --fail-on critical
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### Pre-commit Hook
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
# package.json
|
|
409
|
+
{
|
|
410
|
+
"scripts": {
|
|
411
|
+
"seo:check": "rankture check ./dist --fail-on warning"
|
|
412
|
+
},
|
|
413
|
+
"husky": {
|
|
414
|
+
"hooks": {
|
|
415
|
+
"pre-commit": "npm run build && npm run seo:check"
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
## Programmatic API
|
|
422
|
+
|
|
423
|
+
Use the CLI as a library in your Node.js projects:
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
import { checkPage, checkPages } from '@rankture/cli';
|
|
427
|
+
|
|
428
|
+
// Check a single page
|
|
429
|
+
const html = '<html>...</html>';
|
|
430
|
+
const report = await checkPage(html, 'https://example.com');
|
|
431
|
+
|
|
432
|
+
console.log(report.summary.score); // 85
|
|
433
|
+
console.log(report.summary.critical); // 0
|
|
434
|
+
console.log(report.results); // Array of CheckResult
|
|
435
|
+
|
|
436
|
+
// Check multiple pages
|
|
437
|
+
const pages = [
|
|
438
|
+
{ html: '<html>...</html>', url: 'https://example.com' },
|
|
439
|
+
{ html: '<html>...</html>', url: 'https://example.com/about' },
|
|
440
|
+
];
|
|
441
|
+
const fullReport = await checkPages(pages);
|
|
442
|
+
|
|
443
|
+
console.log(fullReport.summary.totalPages); // 2
|
|
444
|
+
console.log(fullReport.summary.score); // 82 (average)
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Individual Checks
|
|
448
|
+
|
|
449
|
+
```typescript
|
|
450
|
+
import { parseHtml, checkMetaTags, checkHeadings, checkImages } from '@rankture/cli';
|
|
451
|
+
|
|
452
|
+
const html = '<html>...</html>';
|
|
453
|
+
const parsed = parseHtml(html, 'https://example.com');
|
|
454
|
+
|
|
455
|
+
// Run individual checks
|
|
456
|
+
const metaResults = checkMetaTags(parsed);
|
|
457
|
+
const headingResults = checkHeadings(parsed);
|
|
458
|
+
const imageResults = checkImages(parsed);
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
## Configuration
|
|
462
|
+
|
|
463
|
+
Create a `rankture.config.json` in your project root:
|
|
464
|
+
|
|
465
|
+
```json
|
|
466
|
+
{
|
|
467
|
+
"ignore": [
|
|
468
|
+
"**/404.html",
|
|
469
|
+
"**/500.html",
|
|
470
|
+
"**/_*.html"
|
|
471
|
+
],
|
|
472
|
+
"checks": {
|
|
473
|
+
"title-length": { "min": 30, "max": 60 },
|
|
474
|
+
"meta-description-length": { "min": 120, "max": 160 },
|
|
475
|
+
"h1-count": { "expected": 1 }
|
|
476
|
+
},
|
|
477
|
+
"failOn": "critical"
|
|
478
|
+
}
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
## Output Formats
|
|
482
|
+
|
|
483
|
+
### Terminal (default)
|
|
484
|
+
|
|
485
|
+
```
|
|
486
|
+
🔍 Checking 5 HTML files...
|
|
487
|
+
|
|
488
|
+
✓ index.html (18/20 passed)
|
|
489
|
+
✗ [critical] Missing meta description
|
|
490
|
+
✗ [warning] Image missing alt text: hero.jpg
|
|
491
|
+
|
|
492
|
+
✓ about.html (20/20 passed)
|
|
493
|
+
All checks passed!
|
|
494
|
+
|
|
495
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
496
|
+
|
|
497
|
+
📊 Summary
|
|
498
|
+
Pages: 5
|
|
499
|
+
Score: 92/100
|
|
500
|
+
Passed: 95
|
|
501
|
+
Failed: 5 (2 critical, 3 warnings)
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
### JSON
|
|
505
|
+
|
|
506
|
+
```json
|
|
507
|
+
{
|
|
508
|
+
"summary": {
|
|
509
|
+
"totalPages": 5,
|
|
510
|
+
"score": 92,
|
|
511
|
+
"passed": 95,
|
|
512
|
+
"failed": 5,
|
|
513
|
+
"critical": 2,
|
|
514
|
+
"warnings": 3
|
|
515
|
+
},
|
|
516
|
+
"pages": [
|
|
517
|
+
{
|
|
518
|
+
"url": "file://./dist/index.html",
|
|
519
|
+
"results": [...]
|
|
520
|
+
}
|
|
521
|
+
],
|
|
522
|
+
"timestamp": "2025-01-15T10:30:00Z"
|
|
523
|
+
}
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
## CI/CD Integration
|
|
527
|
+
|
|
528
|
+
### GitHub Actions
|
|
529
|
+
|
|
530
|
+
```yaml
|
|
531
|
+
# .github/workflows/seo-check.yml
|
|
532
|
+
name: SEO Check
|
|
533
|
+
|
|
534
|
+
on:
|
|
535
|
+
pull_request:
|
|
536
|
+
branches: [main]
|
|
537
|
+
|
|
538
|
+
jobs:
|
|
539
|
+
seo:
|
|
540
|
+
runs-on: ubuntu-latest
|
|
541
|
+
steps:
|
|
542
|
+
- uses: actions/checkout@v4
|
|
543
|
+
with:
|
|
544
|
+
fetch-depth: 0 # Required for --changed mode
|
|
545
|
+
|
|
546
|
+
- uses: actions/setup-node@v4
|
|
547
|
+
with:
|
|
548
|
+
node-version: '20'
|
|
549
|
+
|
|
550
|
+
- name: Build site
|
|
551
|
+
run: npm run build
|
|
552
|
+
|
|
553
|
+
# Option 1: Check only changed files (fast)
|
|
554
|
+
- name: SEO Check (changed files)
|
|
555
|
+
run: npx @rankture/cli check ./dist --changed --fail-on critical
|
|
556
|
+
|
|
557
|
+
# Option 2: Full check on all files
|
|
558
|
+
- name: SEO Check (full)
|
|
559
|
+
run: npx @rankture/cli check ./dist --fail-on critical
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Pre-commit Hook (with Husky)
|
|
563
|
+
|
|
564
|
+
```bash
|
|
565
|
+
# .husky/pre-commit
|
|
566
|
+
#!/bin/sh
|
|
567
|
+
npx @rankture/cli check ./src/pages --staged --fail-on critical
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### GitLab CI
|
|
571
|
+
|
|
572
|
+
```yaml
|
|
573
|
+
seo-check:
|
|
574
|
+
stage: test
|
|
575
|
+
script:
|
|
576
|
+
- npm run build
|
|
577
|
+
- npx @rankture/cli check ./dist --fail-on critical
|
|
578
|
+
only:
|
|
579
|
+
- merge_requests
|
|
580
|
+
```
|
|
581
|
+
|
|
582
|
+
### Generate HTML Report
|
|
583
|
+
|
|
584
|
+
```yaml
|
|
585
|
+
# In GitHub Actions
|
|
586
|
+
- name: Generate SEO Report
|
|
587
|
+
run: npx @rankture/cli check ./dist -f html -o seo-report.html
|
|
588
|
+
|
|
589
|
+
- name: Upload Report
|
|
590
|
+
uses: actions/upload-artifact@v4
|
|
591
|
+
with:
|
|
592
|
+
name: seo-report
|
|
593
|
+
path: seo-report.html
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
## Pro Features (API Key Required)
|
|
597
|
+
|
|
598
|
+
With a [Rankture Pro](https://rankture.com/pricing/) subscription, unlock:
|
|
599
|
+
|
|
600
|
+
- 🌐 **Live URL auditing** - Check live sites, not just static files
|
|
601
|
+
- 📱 **Mobile & desktop** - Separate audits for each viewport
|
|
602
|
+
- 🔗 **Broken link checking** - HTTP validation of all links
|
|
603
|
+
- ⚡ **Core Web Vitals** - LCP, CLS, FID/INP metrics
|
|
604
|
+
- 📊 **Dashboard sync** - Track progress over time
|
|
605
|
+
- 🤖 **AI suggestions** - Intelligent fix recommendations
|
|
606
|
+
- 📄 **PDF reports** - Branded reports for clients
|
|
607
|
+
|
|
608
|
+
```bash
|
|
609
|
+
rankture audit https://example.com --api-key YOUR_KEY --sync
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
Get your API key at [rankture.com/dashboard/settings](https://rankture.com/dashboard/settings/)
|
|
613
|
+
|
|
614
|
+
## Comparison: Free vs Pro
|
|
615
|
+
|
|
616
|
+
| Feature | Free CLI | Pro (API Key) |
|
|
617
|
+
|---------|----------|---------------|
|
|
618
|
+
| Offline HTML checks | ✅ | ✅ |
|
|
619
|
+
| JSON/Terminal output | ✅ | ✅ |
|
|
620
|
+
| CI/CD integration | ✅ | ✅ |
|
|
621
|
+
| Live URL auditing | ❌ | ✅ |
|
|
622
|
+
| Mobile/Desktop audits | ❌ | ✅ |
|
|
623
|
+
| Broken link checking | ❌ | ✅ |
|
|
624
|
+
| Core Web Vitals | ❌ | ✅ |
|
|
625
|
+
| Dashboard sync | ❌ | ✅ |
|
|
626
|
+
| AI suggestions | ❌ | ✅ |
|
|
627
|
+
| PDF reports | ❌ | ✅ |
|
|
628
|
+
|
|
629
|
+
## Related
|
|
630
|
+
|
|
631
|
+
- [Rankture](https://rankture.com) - Full SEO audit SaaS
|
|
632
|
+
- [Free SEO Audit](https://rankture.com/free-seo-audit/) - One-time free audit
|
|
633
|
+
- [Rankture Blog](https://rankture.com/blog/) - SEO tips and guides
|
|
634
|
+
|
|
635
|
+
## License
|
|
636
|
+
|
|
637
|
+
MIT © [Rankture](https://rankture.com)
|
package/dist/cli.d.ts
ADDED