opencastle 0.32.5 → 0.32.6
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 +13 -3
- package/bin/cli.mjs +2 -0
- package/package.json +1 -1
- package/src/dashboard/node_modules/.vite/deps/_metadata.json +6 -6
- package/src/orchestrator/agents/api-designer.agent.md +25 -34
- package/src/orchestrator/agents/architect.agent.md +40 -84
- package/src/orchestrator/agents/content-engineer.agent.md +29 -31
- package/src/orchestrator/agents/copywriter.agent.md +35 -60
- package/src/orchestrator/agents/data-expert.agent.md +24 -30
- package/src/orchestrator/agents/database-engineer.agent.md +26 -31
- package/src/orchestrator/agents/developer.agent.md +32 -34
- package/src/orchestrator/agents/devops-expert.agent.md +31 -26
- package/src/orchestrator/agents/documentation-writer.agent.md +29 -29
- package/src/orchestrator/agents/performance-expert.agent.md +36 -33
- package/src/orchestrator/agents/release-manager.agent.md +25 -34
- package/src/orchestrator/agents/researcher.agent.md +41 -95
- package/src/orchestrator/agents/reviewer.agent.md +24 -34
- package/src/orchestrator/agents/security-expert.agent.md +35 -39
- package/src/orchestrator/agents/seo-specialist.agent.md +25 -32
- package/src/orchestrator/agents/session-guard.agent.md +20 -79
- package/src/orchestrator/agents/team-lead.agent.md +50 -254
- package/src/orchestrator/agents/testing-expert.agent.md +37 -49
- package/src/orchestrator/agents/ui-ux-expert.agent.md +33 -39
- package/src/orchestrator/customizations/KNOWN-ISSUES.md +0 -1
- package/src/orchestrator/customizations/agents/skill-matrix.json +12 -0
- package/src/orchestrator/instructions/general.instructions.md +24 -84
- package/src/orchestrator/plugins/astro/SKILL.md +23 -179
- package/src/orchestrator/plugins/convex/SKILL.md +38 -12
- package/src/orchestrator/plugins/netlify/SKILL.md +17 -13
- package/src/orchestrator/plugins/nextjs/SKILL.md +55 -261
- package/src/orchestrator/plugins/nx/SKILL.md +20 -72
- package/src/orchestrator/plugins/playwright/SKILL.md +5 -17
- package/src/orchestrator/plugins/slack/SKILL.md +28 -190
- package/src/orchestrator/plugins/teams/SKILL.md +10 -140
- package/src/orchestrator/plugins/vitest/SKILL.md +2 -2
- package/src/orchestrator/prompts/bug-fix.prompt.md +25 -63
- package/src/orchestrator/prompts/implement-feature.prompt.md +29 -66
- package/src/orchestrator/prompts/quick-refinement.prompt.md +31 -66
- package/src/orchestrator/skills/accessibility-standards/SKILL.md +50 -105
- package/src/orchestrator/skills/agent-hooks/SKILL.md +60 -110
- package/src/orchestrator/skills/agent-memory/SKILL.md +44 -93
- package/src/orchestrator/skills/api-patterns/SKILL.md +20 -68
- package/src/orchestrator/skills/code-commenting/SKILL.md +49 -101
- package/src/orchestrator/skills/context-map/SKILL.md +47 -88
- package/src/orchestrator/skills/data-engineering/SKILL.md +27 -74
- package/src/orchestrator/skills/decomposition/SKILL.md +50 -98
- package/src/orchestrator/skills/deployment-infrastructure/SKILL.md +44 -107
- package/src/orchestrator/skills/documentation-standards/SKILL.md +28 -89
- package/src/orchestrator/skills/fast-review/SKILL.md +51 -276
- package/src/orchestrator/skills/frontend-design/SKILL.md +53 -163
- package/src/orchestrator/skills/git-workflow/SKILL.md +18 -54
- package/src/orchestrator/skills/memory-merger/SKILL.md +51 -88
- package/src/orchestrator/skills/observability-logging/SKILL.md +29 -75
- package/src/orchestrator/skills/orchestration-protocols/SKILL.md +58 -117
- package/src/orchestrator/skills/panel-majority-vote/SKILL.md +65 -140
- package/src/orchestrator/skills/performance-optimization/SKILL.md +21 -85
- package/src/orchestrator/skills/project-consistency/SKILL.md +62 -281
- package/src/orchestrator/skills/react-development/SKILL.md +38 -86
- package/src/orchestrator/skills/security-hardening/SKILL.md +40 -84
- package/src/orchestrator/skills/self-improvement/SKILL.md +26 -60
- package/src/orchestrator/skills/seo-patterns/SKILL.md +40 -105
- package/src/orchestrator/skills/session-checkpoints/SKILL.md +26 -68
- package/src/orchestrator/skills/team-lead-reference/SKILL.md +66 -206
- package/src/orchestrator/skills/testing-workflow/SKILL.md +42 -112
- package/src/orchestrator/skills/validation-gates/SKILL.md +39 -170
- package/src/orchestrator/snippets/base-output-contract.md +14 -0
- package/src/orchestrator/snippets/discovered-issues-policy.md +15 -0
- package/src/orchestrator/snippets/logging-mandatory.md +11 -0
- package/src/orchestrator/snippets/never-expose-secrets.md +22 -0
|
@@ -3,118 +3,74 @@ name: security-hardening
|
|
|
3
3
|
description: "Security architecture including authentication, authorization, RLS policies, security headers, CSP, input validation, API security, and OAuth patterns. Use when implementing auth flows, writing RLS policies, configuring security headers, validating inputs, or auditing security."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- ⚠️ This file is managed by OpenCastle. Edits will be overwritten on update. Customize in the .opencastle/ directory instead. -->
|
|
7
|
-
|
|
8
6
|
# Security Hardening
|
|
9
7
|
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
```
|
|
13
|
-
Edge Network (WAF, DDoS)
|
|
14
|
-
→ Security Headers (framework config: HSTS, CSP, X-Frame-Options)
|
|
15
|
-
→ Middleware (session refresh)
|
|
16
|
-
→ Server Actions (Auth: CSRF protection)
|
|
17
|
-
→ RLS Policies (row-level authorization)
|
|
18
|
-
```
|
|
8
|
+
## Architecture
|
|
19
9
|
|
|
20
|
-
| Layer |
|
|
10
|
+
| Layer | Tool | Protection |
|
|
21
11
|
|-------|------|------------|
|
|
22
12
|
| Edge | WAF / CDN | DDoS, bot detection |
|
|
23
|
-
| Headers | Framework config | HSTS, CSP,
|
|
24
|
-
| Middleware | Proxy
|
|
13
|
+
| Headers | Framework config | HSTS, CSP, X-Frame-Options |
|
|
14
|
+
| Middleware | Proxy layer | Session refresh, protected routes |
|
|
25
15
|
| Server Actions | Auth provider | Authentication, CSRF |
|
|
26
16
|
| Database | RLS Policies | Row-level authorization |
|
|
27
|
-
| API Routes | CRON_SECRET | Cron job authorization |
|
|
17
|
+
| API Routes | `CRON_SECRET` | Cron job authorization |
|
|
28
18
|
| Input | Zod | Schema validation |
|
|
29
19
|
| Rate Limiting | Proxy layer | IP-based throttling |
|
|
30
20
|
|
|
31
21
|
## Authentication
|
|
32
22
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
- **Server Actions** for sign in/up/out, session management.
|
|
36
|
-
- **Middleware** for session refresh, protected routes.
|
|
37
|
-
- **RLS Policies** in the database.
|
|
38
|
-
- **OAuth providers:** Configured in the auth provider's dashboard.
|
|
39
|
-
- **User roles:** Stored in the user profiles table (e.g., `profiles.roles TEXT[]`).
|
|
40
|
-
- **Key auth files:** Resolve via project-specific customization files.
|
|
41
|
-
- **Cron authorization:** `CRON_SECRET` env var, `Bearer` token in `authorization` header
|
|
42
|
-
|
|
43
|
-
### Server Actions Pattern Benefits
|
|
44
|
-
|
|
45
|
-
- Automatic CSRF protection (POST-only Server Actions).
|
|
46
|
-
- No exposed API endpoints for auth.
|
|
47
|
-
- Server-side session management.
|
|
23
|
+
Auth provider with Server Actions pattern. Resolve library via **database** capability slot in skill matrix.
|
|
48
24
|
|
|
49
|
-
|
|
25
|
+
| Concern | Approach |
|
|
26
|
+
|---------|----------|
|
|
27
|
+
| Sign in/up/out | Server Actions (POST-only → automatic CSRF protection) |
|
|
28
|
+
| Session refresh | Middleware `updateSession()`, HTTP-only cookies |
|
|
29
|
+
| Protected routes | Middleware check |
|
|
30
|
+
| OAuth | Configured in auth provider dashboard |
|
|
31
|
+
| User roles | `profiles.roles TEXT[]` |
|
|
32
|
+
| Cron auth | `CRON_SECRET` env var, `Bearer` token in `authorization` header |
|
|
50
33
|
|
|
51
|
-
|
|
52
|
-
- Automatic refresh via middleware (`updateSession()`).
|
|
53
|
-
- Sign out clears cookie and invalidates session.
|
|
34
|
+
## CSP
|
|
54
35
|
|
|
55
|
-
|
|
36
|
+
Principle of least privilege. External domains are project-specific (see deployment customization).
|
|
56
37
|
|
|
57
|
-
|
|
38
|
+
- `default-src 'self'` — deny by default
|
|
39
|
+
- `object-src 'none'` — block plugins
|
|
40
|
+
- `frame-ancestors 'self'` — prevent clickjacking
|
|
41
|
+
- `upgrade-insecure-requests` — enforce HTTPS
|
|
42
|
+
- Whitelist only required external domains per directive
|
|
58
43
|
|
|
59
|
-
|
|
60
|
-
|---------|--------|
|
|
61
|
-
| Scripts | Project-specific — see deployment customization |
|
|
62
|
-
| Styles | Project-specific — see deployment customization |
|
|
63
|
-
| Fonts | Project-specific — see deployment customization |
|
|
64
|
-
| Frames | Project-specific — see deployment customization |
|
|
44
|
+
**Note:** `'unsafe-inline'`/`'unsafe-eval'` may be required in dev mode — use nonces/hashes in production.
|
|
65
45
|
|
|
66
|
-
|
|
46
|
+
## RLS
|
|
67
47
|
|
|
68
|
-
|
|
69
|
-
- `default-src 'self'` — deny by default.
|
|
70
|
-
- Whitelist only required external domains per directive.
|
|
71
|
-
- `object-src 'none'` — block plugins.
|
|
72
|
-
- `frame-ancestors 'self'` — prevent clickjacking.
|
|
73
|
-
- `upgrade-insecure-requests` — enforce HTTPS.
|
|
48
|
+
> **SQL examples and role system:** See the **database** skill (authoritative source for RLS).
|
|
74
49
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
> **Detailed RLS patterns and SQL examples:** See the **database** skill (resolved via skill matrix), which is the authoritative source for RLS policies, role systems, and migration rules.
|
|
80
|
-
|
|
81
|
-
### Best Practices
|
|
82
|
-
|
|
83
|
-
- Enable RLS on all tables: `ALTER TABLE x ENABLE ROW LEVEL SECURITY;`
|
|
84
|
-
- Test policies with different user roles.
|
|
85
|
-
- Use `auth.uid()` for authentication checks.
|
|
86
|
-
- EXISTS subqueries for role checks.
|
|
87
|
-
- Never rely solely on client-side authorization.
|
|
88
|
-
- Never disable RLS in production.
|
|
50
|
+
- `ALTER TABLE x ENABLE ROW LEVEL SECURITY;` on all tables
|
|
51
|
+
- Use `auth.uid()` for auth checks; EXISTS subqueries for role checks
|
|
52
|
+
- Never rely solely on client-side authorization; never disable RLS in production
|
|
89
53
|
|
|
90
54
|
## API Security
|
|
91
55
|
|
|
92
|
-
### Cron Job Authorization
|
|
93
|
-
|
|
94
56
|
```typescript
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
57
|
+
// Cron authorization pattern
|
|
58
|
+
const authHeader = request.headers.get('authorization');
|
|
59
|
+
if (!authHeader || authHeader !== `Bearer ${process.env.CRON_SECRET}`) {
|
|
60
|
+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
100
61
|
}
|
|
101
62
|
```
|
|
102
63
|
|
|
103
|
-
|
|
104
|
-
- Rotate quarterly.
|
|
105
|
-
|
|
106
|
-
### Input Validation
|
|
64
|
+
Generate secret: `openssl rand -hex 32`. Rotate quarterly.
|
|
107
65
|
|
|
108
|
-
|
|
109
|
-
- React Hook Form for client-side validation.
|
|
110
|
-
- Server-side validation in all Server Actions and route handlers.
|
|
66
|
+
Input: Zod schemas in all Server Actions and route handlers; React Hook Form client-side.
|
|
111
67
|
|
|
112
68
|
## Critical Rules
|
|
113
69
|
|
|
114
|
-
1. Never commit secrets — use
|
|
115
|
-
2.
|
|
116
|
-
3.
|
|
117
|
-
4. Validate all inputs with Zod before
|
|
118
|
-
5. Sanitize user content
|
|
119
|
-
6. Parameterized queries (
|
|
120
|
-
7. Rotate secrets
|
|
70
|
+
1. Never commit secrets — use env vars.
|
|
71
|
+
2. Server Actions for all auth operations.
|
|
72
|
+
3. RLS on all tables — default-deny, explicit-allow.
|
|
73
|
+
4. Validate all inputs with Zod before DB operations.
|
|
74
|
+
5. Sanitize user content (escape HTML).
|
|
75
|
+
6. Parameterized queries (DB client handles automatically).
|
|
76
|
+
7. Rotate secrets quarterly.
|
|
@@ -3,96 +3,62 @@ name: self-improvement
|
|
|
3
3
|
description: "Protocol for reading and updating the lessons-learned knowledge base. MUST be followed by ALL agents — read lessons before work, write lessons after retries. This makes the agent team self-improving across sessions."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- ⚠️ This file is managed by OpenCastle. Edits will be overwritten on update. Customize in the .opencastle/ directory instead. -->
|
|
7
|
-
|
|
8
6
|
# Self-Improvement Protocol
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
## Core Principle
|
|
13
|
-
|
|
14
|
-
**If you retry something with a different approach and it works, document the lesson immediately.** The cost of writing a lesson (2 minutes) is always less than the cost of someone else hitting the same pitfall (5-30 minutes).
|
|
15
|
-
|
|
16
|
-
## The Lessons File
|
|
17
|
-
|
|
18
|
-
Location: `.opencastle/LESSONS-LEARNED.md`
|
|
19
|
-
|
|
20
|
-
This is the team's collective memory — a structured log of tool/command pitfalls, workarounds, and correct approaches discovered through execution.
|
|
8
|
+
## Core Rule
|
|
21
9
|
|
|
22
|
-
|
|
10
|
+
**Retry with a different approach and it works → document the lesson immediately.** File: `.opencastle/LESSONS-LEARNED.md`
|
|
23
11
|
|
|
24
|
-
|
|
12
|
+
## Writing a Lesson
|
|
25
13
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
> **⛔ HARD GATE — Use the CLI to write lessons. Do NOT edit LESSONS-LEARNED.md directly.**
|
|
29
|
-
|
|
30
|
-
Use the `opencastle lesson` CLI command. It auto-increments the lesson ID, formats the entry, and updates the category index.
|
|
14
|
+
> **⛔ HARD GATE — Use the CLI. Do NOT edit LESSONS-LEARNED.md directly.**
|
|
31
15
|
|
|
32
16
|
```sh
|
|
33
17
|
opencastle lesson --title "Short descriptive title" --category general --severity high \
|
|
34
|
-
--problem "What
|
|
35
|
-
--
|
|
36
|
-
--correct "The working solution" \
|
|
37
|
-
--why "Root cause explanation"
|
|
18
|
+
--problem "What was observed" --wrong "Failing approach" --correct "Working solution" \
|
|
19
|
+
--why "Root cause"
|
|
38
20
|
```
|
|
39
21
|
|
|
40
|
-
Required
|
|
41
|
-
Optional flags: `--wrong`, `--correct`, `--why`
|
|
42
|
-
|
|
43
|
-
Run `opencastle lesson --help` for full usage and valid category/severity values.
|
|
44
|
-
|
|
45
|
-
### After writing the lesson
|
|
46
|
-
|
|
47
|
-
If the lesson reveals a gap in existing instruction/skill files, **also update those files** to include the correct approach. This prevents the pitfall at the source level, not just as a retroactive note.
|
|
22
|
+
Required: `--title`, `--category`, `--severity`, `--problem` · Optional: `--wrong`, `--correct`, `--why`
|
|
48
23
|
|
|
49
|
-
|
|
50
|
-
- Lesson about task tracker tools → update the skill mapped by the `task-management` slot in the skill matrix
|
|
51
|
-
- Lesson about codebase-tool commands → update the skill mapped by the `codebase-tool` slot in the skill matrix
|
|
52
|
-
- Lesson about CMS queries → update the skill mapped by the `cms` slot in the skill matrix
|
|
53
|
-
- Lesson about browser testing → update the skill mapped by the `e2e-testing` slot in the skill matrix
|
|
24
|
+
After writing: if the lesson reveals a gap in a skill/instruction file, update that file too (prevents the pitfall at source).
|
|
54
25
|
|
|
55
26
|
## Categories
|
|
56
27
|
|
|
57
28
|
| Category | Covers |
|
|
58
29
|
|----------|--------|
|
|
59
30
|
| `task-management` | Task tracker tools, issue management, workflow states |
|
|
60
|
-
| `jira` | Jira MCP tools (Atlassian Rovo)
|
|
61
|
-
| `mcp-tools` |
|
|
31
|
+
| `jira` | Jira MCP tools (Atlassian Rovo) |
|
|
32
|
+
| `mcp-tools` | MCP server tool quirks (deferred loading, parameters) |
|
|
62
33
|
| `codebase-tool` | Task runner CLI commands, caching, build tools |
|
|
63
|
-
| `terminal` | Shell commands, port
|
|
34
|
+
| `terminal` | Shell commands, port/process management |
|
|
64
35
|
| `framework` | App framework, build, dev server, SSR |
|
|
65
36
|
| `cms` | CMS content queries, schema deployment |
|
|
66
37
|
| `database` | Database auth, migrations, RLS, SQL |
|
|
67
38
|
| `git` | Git operations, branching, merge conflicts |
|
|
68
39
|
| `deployment` | Deployment, environment variables, edge config |
|
|
69
40
|
| `browser-testing` | E2E testing, screenshots, browser automation |
|
|
70
|
-
| `general` | Anything
|
|
41
|
+
| `general` | Anything else |
|
|
71
42
|
|
|
72
|
-
## Severity
|
|
43
|
+
## Severity
|
|
73
44
|
|
|
74
|
-
| Level |
|
|
75
|
-
|
|
76
|
-
| `high` | Blocks work
|
|
77
|
-
| `medium` | Wastes 5+ minutes |
|
|
78
|
-
| `low` | Minor friction |
|
|
45
|
+
| Level | Impact |
|
|
46
|
+
|-------|--------|
|
|
47
|
+
| `high` | Blocks work — agent cannot proceed without the workaround |
|
|
48
|
+
| `medium` | Wastes 5+ minutes |
|
|
49
|
+
| `low` | Minor friction |
|
|
79
50
|
|
|
80
|
-
## Quality
|
|
51
|
+
## Quality Rules
|
|
81
52
|
|
|
82
|
-
-
|
|
83
|
-
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
86
|
-
- **Code blocks are mandatory** — for commands, tool calls, and configurations
|
|
53
|
+
- Include exact error messages, commands, and tool parameters
|
|
54
|
+
- Show wrong **and** correct approaches — the contrast is actionable
|
|
55
|
+
- Explain why (root cause)
|
|
56
|
+
- One lesson per entry; code blocks mandatory for commands
|
|
87
57
|
|
|
88
58
|
## Anti-Patterns
|
|
89
59
|
|
|
90
|
-
|
|
91
|
-
- **Never "fix it and move on"** without documenting — your fix dies with your session
|
|
92
|
-
- **Never write vague lessons** like "the tracker is tricky" — be specific about what fails and what works
|
|
93
|
-
- **Never duplicate existing lessons** — check the index first
|
|
94
|
-
- **Never wait until the end of a session** to write lessons — write them immediately when the retry succeeds
|
|
60
|
+
Never skip reading lessons · Never fix without documenting · Never write vague entries · Never duplicate · Never defer to end of session
|
|
95
61
|
|
|
96
|
-
## Agent Memory
|
|
62
|
+
## Agent Memory
|
|
97
63
|
|
|
98
|
-
For
|
|
64
|
+
For expertise tracking and cross-session knowledge graphs, load the **agent-memory** skill.
|
|
@@ -3,8 +3,6 @@ name: seo-patterns
|
|
|
3
3
|
description: "Technical SEO patterns for meta tags, structured data, sitemaps, URL strategy, and rendering. Use when optimizing pages for search engines or implementing SEO features."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
<!-- ⚠️ This file is managed by OpenCastle. Edits will be overwritten on update. Customize in the .opencastle/ directory instead. -->
|
|
7
|
-
|
|
8
6
|
# SEO Patterns
|
|
9
7
|
|
|
10
8
|
## Core Principles
|
|
@@ -16,10 +14,7 @@ description: "Technical SEO patterns for meta tags, structured data, sitemaps, U
|
|
|
16
14
|
|
|
17
15
|
## Meta Tags & Open Graph
|
|
18
16
|
|
|
19
|
-
Every page template must include the full set of meta tags:
|
|
20
|
-
|
|
21
17
|
```tsx
|
|
22
|
-
// Next.js App Router — layout or page metadata
|
|
23
18
|
export const metadata: Metadata = {
|
|
24
19
|
title: 'Product Name — Short Descriptor',
|
|
25
20
|
description: 'Concise 150-160 char description with primary keyword.',
|
|
@@ -31,35 +26,24 @@ export const metadata: Metadata = {
|
|
|
31
26
|
type: 'website',
|
|
32
27
|
images: [{ url: 'https://example.com/og-image.jpg', width: 1200, height: 630 }],
|
|
33
28
|
},
|
|
34
|
-
twitter: {
|
|
35
|
-
card: 'summary_large_image',
|
|
36
|
-
title: 'Product Name — Short Descriptor',
|
|
37
|
-
images: ['https://example.com/og-image.jpg'],
|
|
38
|
-
},
|
|
29
|
+
twitter: { card: 'summary_large_image', title: 'Product Name — Short Descriptor', images: ['https://example.com/og-image.jpg'] },
|
|
39
30
|
robots: { index: true, follow: true },
|
|
40
31
|
};
|
|
41
32
|
```
|
|
42
33
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
- [ ] `<title>` is unique, 50-60 chars, includes primary keyword
|
|
46
|
-
- [ ] `<meta name="description">` is unique, 150-160 chars, includes CTA
|
|
47
|
-
- [ ] `<link rel="canonical">` points to the single authoritative URL
|
|
48
|
-
- [ ] `og:title`, `og:description`, `og:image` (1200×630 px min), `og:type` are set
|
|
49
|
-
- [ ] `twitter:card`, `twitter:title`, `twitter:image` are set
|
|
50
|
-
- [ ] `robots` directives are correct (`noindex` on admin/draft pages only)
|
|
34
|
+
**Checklist:** unique title (50-60 chars) · unique description (150-160 chars) · canonical URL · `og:title/description/image` (1200×630 px) · `og:type` · `twitter:card/title/image` · `noindex` only on admin/draft pages.
|
|
51
35
|
|
|
52
36
|
## Structured Data (JSON-LD)
|
|
53
37
|
|
|
54
|
-
Use JSON-LD `<script>` blocks — never microdata or RDFa.
|
|
38
|
+
Use JSON-LD `<script>` blocks — never microdata or RDFa.
|
|
55
39
|
|
|
56
40
|
| Page Type | Schema Type(s) | Required Properties |
|
|
57
41
|
|-----------|----------------|---------------------|
|
|
58
42
|
| Homepage | `WebSite`, `Organization` | `name`, `url`, `searchAction`, `logo` |
|
|
59
|
-
| Detail page | `Product`, `Article`, or domain
|
|
60
|
-
| Listing
|
|
61
|
-
|
|
|
62
|
-
| Blog post | `Article`
|
|
43
|
+
| Detail page | `Product`, `Article`, or domain type | `name`, `description`, `image` |
|
|
44
|
+
| Listing page | `ItemList` + `ListItem` | `itemListElement`, `position`, `url` |
|
|
45
|
+
| Breadcrumbs | `BreadcrumbList` | `itemListElement`, `position`, `name` |
|
|
46
|
+
| Blog post | `Article` / `BlogPosting` | `headline`, `datePublished`, `author` |
|
|
63
47
|
| FAQ page | `FAQPage` | `mainEntity` with `Question` + `Answer` |
|
|
64
48
|
|
|
65
49
|
### Example: Breadcrumb + Article
|
|
@@ -67,27 +51,15 @@ Use JSON-LD `<script>` blocks — never microdata or RDFa. Choose schema types b
|
|
|
67
51
|
```tsx
|
|
68
52
|
function StructuredData({ breadcrumbs, article }: Props) {
|
|
69
53
|
const breadcrumbLd = {
|
|
70
|
-
'@context': 'https://schema.org',
|
|
71
|
-
'@type': '
|
|
72
|
-
itemListElement: breadcrumbs.map((crumb, i) => ({
|
|
73
|
-
'@type': 'ListItem',
|
|
74
|
-
position: i + 1,
|
|
75
|
-
name: crumb.label,
|
|
76
|
-
item: crumb.url,
|
|
77
|
-
})),
|
|
54
|
+
'@context': 'https://schema.org', '@type': 'BreadcrumbList',
|
|
55
|
+
itemListElement: breadcrumbs.map((crumb, i) => ({ '@type': 'ListItem', position: i + 1, name: crumb.label, item: crumb.url })),
|
|
78
56
|
};
|
|
79
|
-
|
|
80
57
|
const articleLd = {
|
|
81
|
-
'@context': 'https://schema.org',
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
image: article.imageUrl,
|
|
86
|
-
datePublished: article.publishedAt,
|
|
87
|
-
dateModified: article.updatedAt,
|
|
88
|
-
author: { '@type': 'Person', name: article.author },
|
|
58
|
+
'@context': 'https://schema.org', '@type': 'Article',
|
|
59
|
+
headline: article.title, description: article.summary,
|
|
60
|
+
image: article.imageUrl, datePublished: article.publishedAt,
|
|
61
|
+
dateModified: article.updatedAt, author: { '@type': 'Person', name: article.author },
|
|
89
62
|
};
|
|
90
|
-
|
|
91
63
|
return (
|
|
92
64
|
<>
|
|
93
65
|
<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbLd) }} />
|
|
@@ -97,20 +69,13 @@ function StructuredData({ breadcrumbs, article }: Props) {
|
|
|
97
69
|
}
|
|
98
70
|
```
|
|
99
71
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
- Run every JSON-LD block through [Google's Rich Results Test](https://search.google.com/test/rich-results) before merging.
|
|
103
|
-
- Validate against [schema.org](https://schema.org) definitions for required/recommended properties.
|
|
104
|
-
- Check the Search Console **Enhancements** report after deployment.
|
|
72
|
+
Validate every block via [Google's Rich Results Test](https://search.google.com/test/rich-results) before merging. Check Search Console **Enhancements** after deployment.
|
|
105
73
|
|
|
106
74
|
## Sitemap & Crawlability
|
|
107
75
|
|
|
108
|
-
- Generate
|
|
109
|
-
- Use a **sitemap index** when
|
|
110
|
-
- Include `<lastmod>`
|
|
111
|
-
- Submit sitemaps via Google Search Console and reference them in `robots.txt`.
|
|
112
|
-
|
|
113
|
-
### Example: robots.txt
|
|
76
|
+
- Generate XML sitemap dynamically from your data source (CMS, DB, filesystem).
|
|
77
|
+
- Use a **sitemap index** when >50,000 URLs or >50 MB.
|
|
78
|
+
- Include `<lastmod>` only if accurate; submit via Google Search Console and reference in `robots.txt`.
|
|
114
79
|
|
|
115
80
|
```txt
|
|
116
81
|
User-agent: *
|
|
@@ -118,26 +83,13 @@ Allow: /
|
|
|
118
83
|
Disallow: /admin/
|
|
119
84
|
Disallow: /api/
|
|
120
85
|
Disallow: /preview/
|
|
121
|
-
|
|
122
86
|
Sitemap: https://example.com/sitemap.xml
|
|
123
87
|
```
|
|
124
88
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
- [ ] `robots.txt` allows crawling of all public pages
|
|
128
|
-
- [ ] `robots.txt` blocks admin, API, and preview routes
|
|
129
|
-
- [ ] XML sitemap is auto-generated and up to date
|
|
130
|
-
- [ ] Sitemap is referenced in `robots.txt`
|
|
131
|
-
- [ ] Internal links connect all public pages (no orphan pages)
|
|
132
|
-
- [ ] Page load time < 3s (crawl budget efficiency)
|
|
89
|
+
**Checklist:** robots.txt allows all public pages · blocks admin/API/preview · XML sitemap auto-generated and current · referenced in robots.txt · no orphan pages · page load < 3s.
|
|
133
90
|
|
|
134
91
|
## URL Strategy
|
|
135
92
|
|
|
136
|
-
- Use lowercase, hyphen-separated slugs: `/blog/my-post-title`
|
|
137
|
-
- Keep URLs short, keyword-relevant, and human-readable.
|
|
138
|
-
- Enforce trailing-slash consistency (pick one, redirect the other).
|
|
139
|
-
- Implement 301 redirects for any renamed or moved pages.
|
|
140
|
-
|
|
141
93
|
| Pattern | Good | Bad |
|
|
142
94
|
|---------|------|-----|
|
|
143
95
|
| Slug format | `/products/blue-widget` | `/products/Blue_Widget` |
|
|
@@ -145,56 +97,39 @@ Sitemap: https://example.com/sitemap.xml
|
|
|
145
97
|
| Consistency | Always `/path/` or `/path` | Mixed trailing slashes |
|
|
146
98
|
| Parameters | `/products?sort=price` | `/products/sort/price/asc` |
|
|
147
99
|
|
|
148
|
-
### Redirect Example (Next.js)
|
|
149
|
-
|
|
150
100
|
```ts
|
|
151
101
|
// next.config.ts
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
{ source: '/blog/:slug/amp', destination: '/blog/:slug', permanent: true },
|
|
157
|
-
];
|
|
158
|
-
},
|
|
159
|
-
};
|
|
102
|
+
const redirects = [
|
|
103
|
+
{ source: '/old-page', destination: '/new-page', permanent: true },
|
|
104
|
+
{ source: '/blog/:slug/amp', destination: '/blog/:slug', permanent: true },
|
|
105
|
+
];
|
|
160
106
|
```
|
|
161
107
|
|
|
162
108
|
## Rendering & Indexability
|
|
163
109
|
|
|
164
|
-
|
|
165
|
-
- **Client-hydrated** interactive elements (filters, modals) are fine, but content behind JS-only rendering will not be indexed reliably.
|
|
166
|
-
- Use semantic HTML (`<h1>`–`<h6>`, `<article>`, `<nav>`, `<main>`) for crawlers to understand page structure.
|
|
110
|
+
Server-render all indexed content. Use semantic HTML (`<h1>`–`<h6>`, `<article>`, `<nav>`, `<main>`) for crawler structure.
|
|
167
111
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
|
171
|
-
|
|
172
|
-
| `
|
|
173
|
-
| `loading` | Lazy-load below-fold images | `loading="lazy"` |
|
|
174
|
-
| `width` / `height` | Prevents layout shift (CLS) | `width={800} height={600}` |
|
|
112
|
+
| Image Attribute | Purpose | Example |
|
|
113
|
+
|-----------------|---------|---------|
|
|
114
|
+
| `alt` | Describes for crawlers + screen readers | `alt="Blue widget on white background"` |
|
|
115
|
+
| `loading` | Lazy-load below-fold | `loading="lazy"` |
|
|
116
|
+
| `width` / `height` | Prevents CLS | `width={800} height={600}` |
|
|
175
117
|
| File name | Keyword signal | `blue-widget-front.webp` |
|
|
176
|
-
| Format | Performance + quality |
|
|
177
|
-
|
|
178
|
-
### Indexability Checklist
|
|
118
|
+
| Format | Performance + quality | WebP/AVIF with JPEG fallback |
|
|
179
119
|
|
|
180
|
-
|
|
181
|
-
- [ ] `<h1>` is unique per page and contains the primary keyword
|
|
182
|
-
- [ ] Structured data is present in the server-rendered HTML
|
|
183
|
-
- [ ] Images have descriptive `alt` text
|
|
184
|
-
- [ ] No `noindex` on pages that should be indexed
|
|
185
|
-
- [ ] Hydration does not remove or rewrite structured data scripts
|
|
120
|
+
**Checklist:** primary content in initial HTML · unique `<h1>` with primary keyword · structured data in SSR HTML · descriptive `alt` on all images · no stray `noindex` · hydration preserves structured data scripts.
|
|
186
121
|
|
|
187
122
|
## Anti-Patterns
|
|
188
123
|
|
|
189
124
|
| Anti-Pattern | Why It's Bad | Correct Approach |
|
|
190
125
|
|---|---|---|
|
|
191
|
-
| Duplicate `<title>`
|
|
192
|
-
| Missing canonical URL |
|
|
193
|
-
| Client-only rendered content | Googlebot may
|
|
194
|
-
| Hardcoded sitemap
|
|
195
|
-
|
|
|
196
|
-
|
|
|
197
|
-
| Missing `alt`
|
|
198
|
-
|
|
|
199
|
-
| Blocking CSS/JS in
|
|
200
|
-
| Mixed trailing slash URLs | Splits link equity
|
|
126
|
+
| Duplicate `<title>` | Dilutes ranking signals | Unique, keyword-specific title per page |
|
|
127
|
+
| Missing canonical URL | Duplicate content penalties | Add `<link rel="canonical">` to every page |
|
|
128
|
+
| Client-only rendered content | Googlebot may miss JS | Server-render all indexable content |
|
|
129
|
+
| Hardcoded sitemap | Goes stale | Generate sitemap dynamically |
|
|
130
|
+
| `noindex` as "temporary" fix | Often forgotten | Fix the underlying issue |
|
|
131
|
+
| Keyword stuffing in meta tags | Penalized by search engines | Natural, user-focused descriptions |
|
|
132
|
+
| Missing `alt` on images | Lost image traffic + a11y failure | Descriptive alt on every meaningful image |
|
|
133
|
+
| Unvalidated structured data | Silent errors = rich result loss | Validate with Rich Results Test before merge |
|
|
134
|
+
| Blocking CSS/JS in robots.txt | Prevents page rendering | Only block admin/API routes |
|
|
135
|
+
| Mixed trailing slash URLs | Splits link equity | Pick one convention, 301-redirect other |
|