@qobi/seocode 0.1.0 → 0.1.1
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 +107 -0
- package/dist/src/cli/index.js +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# SEOCode
|
|
2
|
+
|
|
3
|
+
**Framework-aware technical SEO review for your codebase.** A zero-config CLI that catches deploy-blocking SEO regressions — accidental `noindex`, dynamic metadata that never renders, broken JSON-LD, missing titles — *before* you push, right in your terminal.
|
|
4
|
+
|
|
5
|
+
It understands your framework. Titles and descriptions set through the **Next.js** Metadata API / `generateMetadata`, **Remix** `meta()`, or **Astro** layouts are read the way the framework actually renders them — so you don't get false "missing title" noise on correct code.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx @qobi/seocode check
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# one-shot, no install
|
|
17
|
+
npx @qobi/seocode check
|
|
18
|
+
|
|
19
|
+
# or install globally — the command is just `seocode`
|
|
20
|
+
npm i -g @qobi/seocode
|
|
21
|
+
seocode check
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Requires Node.js ≥ 20.
|
|
25
|
+
|
|
26
|
+
## Commands
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
seocode check # scan the repo (or given paths) for SEO issues
|
|
30
|
+
seocode check src/ app/ # scan specific paths
|
|
31
|
+
seocode check --fix # scan, then apply safe, mechanical fixes to your files
|
|
32
|
+
seocode check --staged # review only git-staged files (pre-commit mode)
|
|
33
|
+
seocode check --json # machine-readable output (for editors / CI)
|
|
34
|
+
seocode init # create a .seocode.json + set up a pre-commit hook
|
|
35
|
+
seocode init --hook # also install .git/hooks/pre-commit for you
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Exit code** is `1` when deploy-blocking (critical) issues are found, `0` otherwise — so it drops straight into a pre-commit hook or a CI step.
|
|
39
|
+
|
|
40
|
+
## What it checks
|
|
41
|
+
|
|
42
|
+
Critical, deploy-blocking issues are surfaced first; lower-severity suggestions stay out of the way.
|
|
43
|
+
|
|
44
|
+
- **Critical** — accidental `noindex`, missing `<title>`, broken/invalid JSON-LD, unrendered dynamic metadata, missing `<h1>`, duplicate `<h1>`, images missing `alt`
|
|
45
|
+
- **Warnings** — title/description length, missing Open Graph / Twitter tags, broken heading hierarchy, missing canonical, vague link text
|
|
46
|
+
- **Info** — lazy-loading hints, AVIF format, LCP preload, structured-data recommendations, and more
|
|
47
|
+
|
|
48
|
+
…across HTML, JS, JSX, TSX, Vue, Svelte, and Astro files. Framework shells, utility files, and component libraries are scoped automatically.
|
|
49
|
+
|
|
50
|
+
### `--fix`
|
|
51
|
+
|
|
52
|
+
`--fix` applies only the transforms SEOCode can make with certainty — never a guess. Today that covers:
|
|
53
|
+
|
|
54
|
+
- adding `loading="lazy"` to images that lack it
|
|
55
|
+
- adding `rel="noopener noreferrer"` to external links that have no `rel`
|
|
56
|
+
|
|
57
|
+
Everything else is reported with the exact tag to add and the line to change.
|
|
58
|
+
|
|
59
|
+
## Framework awareness
|
|
60
|
+
|
|
61
|
+
SEOCode reads framework metadata instead of just literal tags, so it won't false-flag idiomatic code:
|
|
62
|
+
|
|
63
|
+
- **Next.js** — `metadata` / `generateMetadata`, App Router layouts & pages, `next/og` image routes, JSON-LD via `dangerouslySetInnerHTML`
|
|
64
|
+
- **Remix** — `meta()` exports
|
|
65
|
+
- **Astro** — layouts with dynamic `<title>{title}</title>`, pages that delegate their `<head>` to a layout
|
|
66
|
+
- **Plain HTML / Vue / Svelte** — the `<head>` is checked directly
|
|
67
|
+
|
|
68
|
+
The head is composed by the framework across layouts, pages, and merged metadata — so on framework files, SEOCode reports only what it can prove, and stays silent where it can't. Real signal (like an accidental `noindex`) still comes through.
|
|
69
|
+
|
|
70
|
+
## Configuration
|
|
71
|
+
|
|
72
|
+
Drop a `.seocode.json` in your repo root (all fields optional):
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"exclude": ["emails/**", "public/legacy/**", "**/*.stories.tsx"],
|
|
77
|
+
"rules": {
|
|
78
|
+
"title-too-short": "off",
|
|
79
|
+
"missing-canonical": "info"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
- **`exclude`** — glob patterns to skip (`*` within a segment, `**` across segments, trailing `/` for a whole directory)
|
|
85
|
+
- **`rules`** — set a rule to `"off"` (or `false`) to disable it, or to `"critical"` / `"warning"` / `"info"` to change its severity
|
|
86
|
+
|
|
87
|
+
A missing or malformed config falls back to defaults — a typo can't break your reviews.
|
|
88
|
+
|
|
89
|
+
## Pre-commit hook
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
seocode init --hook # installs .git/hooks/pre-commit → seocode check --staged
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
…or with [husky](https://typicode.github.io/husky):
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
echo "npx @qobi/seocode check --staged" > .husky/pre-commit
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## SEOCode as a GitHub App
|
|
102
|
+
|
|
103
|
+
Prefer automated reviews on every pull request instead of (or alongside) the CLI? The hosted **SEOCode GitHub App** posts a critical-first review comment on every PR, offers one-click fixes, sets a merge status check, and judges each PR on what *it* changed (legacy debt never blocks your merge). See **[seocode.io](https://seocode.io)**.
|
|
104
|
+
|
|
105
|
+
## License
|
|
106
|
+
|
|
107
|
+
MIT © SEOCode
|
package/dist/src/cli/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import { formatTerminal } from './format-terminal.js';
|
|
|
10
10
|
import { applyFixes } from './fix.js';
|
|
11
11
|
import { stagedFiles } from './staged.js';
|
|
12
12
|
import { runInit } from './init.js';
|
|
13
|
-
const VERSION = '0.1.
|
|
13
|
+
const VERSION = '0.1.1';
|
|
14
14
|
function parseArgs(argv) {
|
|
15
15
|
const a = {
|
|
16
16
|
command: 'check', paths: [], json: false,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qobi/seocode",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Framework-aware technical SEO review for your codebase — zero-config CLI that catches deploy-blocking SEO regressions (noindex, dynamic metadata, broken JSON-LD) before you push.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|