@rankcli/agent-runtime 0.0.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.
Files changed (178) hide show
  1. package/README.md +242 -0
  2. package/dist/analyzer-2CSWIQGD.mjs +6 -0
  3. package/dist/chunk-YNZYHEYM.mjs +774 -0
  4. package/dist/index.d.mts +4012 -0
  5. package/dist/index.d.ts +4012 -0
  6. package/dist/index.js +29672 -0
  7. package/dist/index.mjs +28602 -0
  8. package/package.json +53 -0
  9. package/scripts/build-deno.ts +134 -0
  10. package/src/audit/ai/analyzer.ts +347 -0
  11. package/src/audit/ai/index.ts +29 -0
  12. package/src/audit/ai/prompts/content-analysis.ts +271 -0
  13. package/src/audit/ai/types.ts +179 -0
  14. package/src/audit/checks/additional-checks.ts +439 -0
  15. package/src/audit/checks/ai-citation-worthiness.ts +399 -0
  16. package/src/audit/checks/ai-content-structure.ts +325 -0
  17. package/src/audit/checks/ai-readiness.ts +339 -0
  18. package/src/audit/checks/anchor-text.ts +179 -0
  19. package/src/audit/checks/answer-conciseness.ts +322 -0
  20. package/src/audit/checks/asset-minification.ts +270 -0
  21. package/src/audit/checks/bing-optimization.ts +206 -0
  22. package/src/audit/checks/brand-mention-optimization.ts +349 -0
  23. package/src/audit/checks/caching-headers.ts +305 -0
  24. package/src/audit/checks/canonical-advanced.ts +150 -0
  25. package/src/audit/checks/canonical-domain.ts +196 -0
  26. package/src/audit/checks/citation-quality.ts +358 -0
  27. package/src/audit/checks/client-rendering.ts +542 -0
  28. package/src/audit/checks/color-contrast.ts +342 -0
  29. package/src/audit/checks/content-freshness.ts +170 -0
  30. package/src/audit/checks/content-science.ts +589 -0
  31. package/src/audit/checks/conversion-elements.ts +526 -0
  32. package/src/audit/checks/crawlability.ts +220 -0
  33. package/src/audit/checks/directory-listing.ts +172 -0
  34. package/src/audit/checks/dom-analysis.ts +191 -0
  35. package/src/audit/checks/dom-size.ts +246 -0
  36. package/src/audit/checks/duplicate-content.ts +194 -0
  37. package/src/audit/checks/eeat-signals.ts +990 -0
  38. package/src/audit/checks/entity-seo.ts +396 -0
  39. package/src/audit/checks/featured-snippet.ts +473 -0
  40. package/src/audit/checks/freshness-signals.ts +443 -0
  41. package/src/audit/checks/funnel-intent.ts +463 -0
  42. package/src/audit/checks/hreflang.ts +174 -0
  43. package/src/audit/checks/html-compliance.ts +302 -0
  44. package/src/audit/checks/image-dimensions.ts +167 -0
  45. package/src/audit/checks/images.ts +160 -0
  46. package/src/audit/checks/indexnow.ts +275 -0
  47. package/src/audit/checks/interactive-tools.ts +475 -0
  48. package/src/audit/checks/internal-link-graph.ts +436 -0
  49. package/src/audit/checks/keyword-analysis.ts +239 -0
  50. package/src/audit/checks/keyword-cannibalization.ts +385 -0
  51. package/src/audit/checks/keyword-placement.ts +471 -0
  52. package/src/audit/checks/links.ts +203 -0
  53. package/src/audit/checks/llms-txt.ts +224 -0
  54. package/src/audit/checks/local-seo.ts +296 -0
  55. package/src/audit/checks/mobile.ts +167 -0
  56. package/src/audit/checks/modern-images.ts +226 -0
  57. package/src/audit/checks/navboost-signals.ts +395 -0
  58. package/src/audit/checks/on-page.ts +209 -0
  59. package/src/audit/checks/page-resources.ts +285 -0
  60. package/src/audit/checks/pagination.ts +180 -0
  61. package/src/audit/checks/performance.ts +153 -0
  62. package/src/audit/checks/platform-presence.ts +580 -0
  63. package/src/audit/checks/redirect-analysis.ts +153 -0
  64. package/src/audit/checks/redirect-chain.ts +389 -0
  65. package/src/audit/checks/resource-hints.ts +420 -0
  66. package/src/audit/checks/responsive-css.ts +247 -0
  67. package/src/audit/checks/responsive-images.ts +396 -0
  68. package/src/audit/checks/review-ecosystem.ts +415 -0
  69. package/src/audit/checks/robots-validation.ts +373 -0
  70. package/src/audit/checks/security-headers.ts +172 -0
  71. package/src/audit/checks/security.ts +144 -0
  72. package/src/audit/checks/serp-preview.ts +251 -0
  73. package/src/audit/checks/site-maturity.ts +444 -0
  74. package/src/audit/checks/social-meta.test.ts +275 -0
  75. package/src/audit/checks/social-meta.ts +134 -0
  76. package/src/audit/checks/soft-404.ts +151 -0
  77. package/src/audit/checks/structured-data.ts +238 -0
  78. package/src/audit/checks/tech-detection.ts +496 -0
  79. package/src/audit/checks/topical-clusters.ts +435 -0
  80. package/src/audit/checks/tracker-bloat.ts +462 -0
  81. package/src/audit/checks/tracking-verification.test.ts +371 -0
  82. package/src/audit/checks/tracking-verification.ts +636 -0
  83. package/src/audit/checks/url-safety.ts +682 -0
  84. package/src/audit/deno-entry.ts +66 -0
  85. package/src/audit/discovery/index.ts +15 -0
  86. package/src/audit/discovery/link-crawler.ts +232 -0
  87. package/src/audit/discovery/repo-routes.ts +347 -0
  88. package/src/audit/engine.ts +620 -0
  89. package/src/audit/fixes/index.ts +209 -0
  90. package/src/audit/fixes/social-meta-fixes.test.ts +329 -0
  91. package/src/audit/fixes/social-meta-fixes.ts +463 -0
  92. package/src/audit/index.ts +74 -0
  93. package/src/audit/runner.test.ts +299 -0
  94. package/src/audit/runner.ts +130 -0
  95. package/src/audit/types.ts +1953 -0
  96. package/src/content/featured-snippet.ts +367 -0
  97. package/src/content/generator.test.ts +534 -0
  98. package/src/content/generator.ts +501 -0
  99. package/src/content/headline.ts +317 -0
  100. package/src/content/index.ts +62 -0
  101. package/src/content/intent.ts +258 -0
  102. package/src/content/keyword-density.ts +349 -0
  103. package/src/content/readability.ts +262 -0
  104. package/src/executor.ts +336 -0
  105. package/src/fixer.ts +416 -0
  106. package/src/frameworks/detector.test.ts +248 -0
  107. package/src/frameworks/detector.ts +371 -0
  108. package/src/frameworks/index.ts +68 -0
  109. package/src/frameworks/recipes/angular.yaml +171 -0
  110. package/src/frameworks/recipes/astro.yaml +206 -0
  111. package/src/frameworks/recipes/django.yaml +180 -0
  112. package/src/frameworks/recipes/laravel.yaml +137 -0
  113. package/src/frameworks/recipes/nextjs.yaml +268 -0
  114. package/src/frameworks/recipes/nuxt.yaml +175 -0
  115. package/src/frameworks/recipes/rails.yaml +188 -0
  116. package/src/frameworks/recipes/react.yaml +202 -0
  117. package/src/frameworks/recipes/sveltekit.yaml +154 -0
  118. package/src/frameworks/recipes/vue.yaml +137 -0
  119. package/src/frameworks/recipes/wordpress.yaml +209 -0
  120. package/src/frameworks/suggestion-engine.ts +320 -0
  121. package/src/geo/geo-content.test.ts +305 -0
  122. package/src/geo/geo-content.ts +266 -0
  123. package/src/geo/geo-history.test.ts +473 -0
  124. package/src/geo/geo-history.ts +433 -0
  125. package/src/geo/geo-tracker.test.ts +359 -0
  126. package/src/geo/geo-tracker.ts +411 -0
  127. package/src/geo/index.ts +10 -0
  128. package/src/git/commit-helper.test.ts +261 -0
  129. package/src/git/commit-helper.ts +329 -0
  130. package/src/git/index.ts +12 -0
  131. package/src/git/pr-helper.test.ts +284 -0
  132. package/src/git/pr-helper.ts +307 -0
  133. package/src/index.ts +66 -0
  134. package/src/keywords/ai-keyword-engine.ts +1062 -0
  135. package/src/keywords/ai-summarizer.ts +387 -0
  136. package/src/keywords/ci-mode.ts +555 -0
  137. package/src/keywords/engine.ts +359 -0
  138. package/src/keywords/index.ts +151 -0
  139. package/src/keywords/llm-judge.ts +357 -0
  140. package/src/keywords/nlp-analysis.ts +706 -0
  141. package/src/keywords/prioritizer.ts +295 -0
  142. package/src/keywords/site-crawler.ts +342 -0
  143. package/src/keywords/sources/autocomplete.ts +139 -0
  144. package/src/keywords/sources/competitive-search.ts +450 -0
  145. package/src/keywords/sources/competitor-analysis.ts +374 -0
  146. package/src/keywords/sources/dataforseo.ts +206 -0
  147. package/src/keywords/sources/free-sources.ts +294 -0
  148. package/src/keywords/sources/gsc.ts +123 -0
  149. package/src/keywords/topic-grouping.ts +327 -0
  150. package/src/keywords/types.ts +144 -0
  151. package/src/keywords/wizard.ts +457 -0
  152. package/src/loader.ts +40 -0
  153. package/src/reports/index.ts +7 -0
  154. package/src/reports/report-generator.test.ts +293 -0
  155. package/src/reports/report-generator.ts +713 -0
  156. package/src/scheduler/alerts.test.ts +458 -0
  157. package/src/scheduler/alerts.ts +328 -0
  158. package/src/scheduler/index.ts +8 -0
  159. package/src/scheduler/scheduled-audit.test.ts +377 -0
  160. package/src/scheduler/scheduled-audit.ts +149 -0
  161. package/src/test/integration-test.ts +325 -0
  162. package/src/tools/analyzer.ts +373 -0
  163. package/src/tools/crawl.ts +293 -0
  164. package/src/tools/files.ts +301 -0
  165. package/src/tools/h1-fixer.ts +249 -0
  166. package/src/tools/index.ts +67 -0
  167. package/src/tracking/github-action.ts +326 -0
  168. package/src/tracking/google-analytics.ts +265 -0
  169. package/src/tracking/index.ts +45 -0
  170. package/src/tracking/report-generator.ts +386 -0
  171. package/src/tracking/search-console.ts +335 -0
  172. package/src/types.ts +134 -0
  173. package/src/utils/http.ts +302 -0
  174. package/src/wasm-adapter.ts +297 -0
  175. package/src/wasm-entry.ts +14 -0
  176. package/tsconfig.json +17 -0
  177. package/tsup.wasm.config.ts +26 -0
  178. package/vitest.config.ts +15 -0
@@ -0,0 +1,202 @@
1
+ # React SEO Recipe
2
+ # Client-side rendering frameworks are notoriously problematic for SEO
3
+
4
+ framework: react
5
+ display_name: React
6
+ category: spa
7
+ ssr_default: false
8
+
9
+ seo_challenges:
10
+ - "Client-side rendering means empty HTML for crawlers"
11
+ - "Dynamic content invisible to search engines"
12
+ - "Slow First Contentful Paint"
13
+ - "No server-side meta tag generation"
14
+ - "JavaScript-dependent routing breaks crawlability"
15
+
16
+ checks:
17
+ # Critical - these will severely hurt SEO
18
+ - code: REACT_CSR_DETECTED
19
+ severity: error
20
+ title: "Client-side rendered React app detected"
21
+ description: "React apps without SSR send empty HTML to crawlers. Search engines may not index your content."
22
+ impact: "Critical - your content is likely invisible to Google"
23
+ howToFix: |
24
+ Option 1: Migrate to Next.js for automatic SSR/SSG
25
+ Option 2: Add prerendering with react-snap or prerender.io
26
+ Option 3: Use react-helmet-async with a prerender service
27
+ detection:
28
+ html_patterns:
29
+ - '<div id="root"></div>'
30
+ - '<div id="app"></div>'
31
+ missing_content: true # Body has minimal text content
32
+
33
+ - code: REACT_NO_SSR_META
34
+ severity: error
35
+ title: "Meta tags not server-rendered"
36
+ description: "Title and meta description are set client-side and won't be seen by crawlers."
37
+ impact: "Search results will show wrong or missing title/description"
38
+ howToFix: |
39
+ For Vite/CRA: Use a prerender plugin or migrate to Next.js
40
+
41
+ Quick fix with vite-plugin-ssr:
42
+ ```tsx
43
+ // pages/+Head.tsx
44
+ export function Head() {
45
+ return <>
46
+ <title>Your Title</title>
47
+ <meta name="description" content="Your description" />
48
+ </>
49
+ }
50
+ ```
51
+ detection:
52
+ title_in_js: true
53
+ title_not_in_html: true
54
+
55
+ - code: REACT_HYDRATION_MISMATCH
56
+ severity: warning
57
+ title: "Hydration mismatch detected"
58
+ description: "Server HTML differs from client render, causing flicker and potential SEO issues."
59
+ impact: "Can cause content to briefly disappear, confusing crawlers"
60
+ howToFix: |
61
+ Common causes:
62
+ 1. Using Date.now() or Math.random() in render
63
+ 2. Browser-only APIs like window.localStorage
64
+ 3. Different data on server vs client
65
+
66
+ Fix: Use useEffect for browser-only code:
67
+ ```tsx
68
+ const [mounted, setMounted] = useState(false);
69
+ useEffect(() => setMounted(true), []);
70
+ if (!mounted) return null; // or skeleton
71
+ ```
72
+
73
+ # Warnings - important but not critical
74
+ - code: REACT_HELMET_NOT_ASYNC
75
+ severity: warning
76
+ title: "Using react-helmet instead of react-helmet-async"
77
+ description: "react-helmet has memory leaks and doesn't work properly with SSR."
78
+ howToFix: |
79
+ Replace react-helmet with react-helmet-async:
80
+ ```bash
81
+ npm uninstall react-helmet
82
+ npm install react-helmet-async
83
+ ```
84
+
85
+ Update imports:
86
+ ```tsx
87
+ // Before
88
+ import { Helmet } from 'react-helmet';
89
+
90
+ // After
91
+ import { Helmet, HelmetProvider } from 'react-helmet-async';
92
+
93
+ // Wrap app in provider
94
+ <HelmetProvider>
95
+ <App />
96
+ </HelmetProvider>
97
+ ```
98
+
99
+ - code: REACT_ROUTER_NO_SSR
100
+ severity: warning
101
+ title: "React Router without server-side support"
102
+ description: "Client-side routing breaks when crawlers access URLs directly."
103
+ howToFix: |
104
+ Ensure your server returns the same HTML for all routes.
105
+
106
+ For static hosting (Netlify, Vercel):
107
+ Add a redirect rule to serve index.html for all routes.
108
+
109
+ netlify.toml:
110
+ ```toml
111
+ [[redirects]]
112
+ from = "/*"
113
+ to = "/index.html"
114
+ status = 200
115
+ ```
116
+
117
+ - code: REACT_NO_PRERENDER
118
+ severity: warning
119
+ title: "No prerendering configured"
120
+ description: "Static pages could be prerendered for better SEO and performance."
121
+ howToFix: |
122
+ Add react-snap for build-time prerendering:
123
+ ```bash
124
+ npm install react-snap
125
+ ```
126
+
127
+ package.json:
128
+ ```json
129
+ {
130
+ "scripts": {
131
+ "postbuild": "react-snap"
132
+ },
133
+ "reactSnap": {
134
+ "source": "build"
135
+ }
136
+ }
137
+ ```
138
+
139
+ # Performance-related
140
+ - code: REACT_BUNDLE_TOO_LARGE
141
+ severity: warning
142
+ title: "React bundle too large"
143
+ description: "Large JavaScript bundles delay interactivity and hurt Core Web Vitals."
144
+ howToFix: |
145
+ 1. Use React.lazy() for code splitting:
146
+ ```tsx
147
+ const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
148
+
149
+ <Suspense fallback={<Loading />}>
150
+ <HeavyComponent />
151
+ </Suspense>
152
+ ```
153
+
154
+ 2. Analyze bundle with source-map-explorer:
155
+ ```bash
156
+ npm install source-map-explorer
157
+ npx source-map-explorer build/static/js/*.js
158
+ ```
159
+
160
+ - code: REACT_NO_SUSPENSE
161
+ severity: notice
162
+ title: "Not using Suspense for data fetching"
163
+ description: "Without Suspense, content pops in causing layout shifts (CLS)."
164
+ howToFix: |
165
+ Use Suspense with a data fetching library:
166
+ ```tsx
167
+ <Suspense fallback={<Skeleton />}>
168
+ <DataComponent />
169
+ </Suspense>
170
+ ```
171
+
172
+ performance_tips:
173
+ - "Use React.memo() for expensive components"
174
+ - "Lazy load routes with React.lazy()"
175
+ - "Use useMemo/useCallback to prevent unnecessary rerenders"
176
+ - "Consider using Preact for smaller bundle size"
177
+ - "Use production builds (NODE_ENV=production)"
178
+
179
+ migration_paths:
180
+ nextjs:
181
+ effort: medium
182
+ benefits:
183
+ - "Automatic SSR/SSG"
184
+ - "Built-in Image optimization"
185
+ - "File-based routing"
186
+ - "API routes"
187
+ guide: "https://nextjs.org/docs/migrating/from-create-react-app"
188
+
189
+ remix:
190
+ effort: medium
191
+ benefits:
192
+ - "Nested routing with data loading"
193
+ - "Progressive enhancement"
194
+ - "Better error boundaries"
195
+ guide: "https://remix.run/docs/en/main/guides/migrating-react-router-app"
196
+
197
+ vite-ssr:
198
+ effort: low
199
+ benefits:
200
+ - "Keep existing code"
201
+ - "Add SSR incrementally"
202
+ guide: "https://vite-plugin-ssr.com/"
@@ -0,0 +1,154 @@
1
+ # SvelteKit SEO Recipe
2
+ # SvelteKit has excellent SSR and SSG support with minimal overhead
3
+
4
+ framework: sveltekit
5
+ display_name: SvelteKit
6
+ category: meta-framework
7
+ base_framework: svelte
8
+ ssr_default: true
9
+
10
+ seo_strengths:
11
+ - "SSR by default"
12
+ - "Excellent performance (small runtime)"
13
+ - "Built-in prerendering"
14
+ - "File-based routing"
15
+ - "Form actions for progressive enhancement"
16
+
17
+ checks:
18
+ - code: SVELTEKIT_NO_LOAD_FUNCTION
19
+ severity: warning
20
+ title: "Page without load function"
21
+ description: "Data fetching in +page.svelte bypasses SSR. Use +page.server.ts or +page.ts."
22
+ howToFix: |
23
+ Move data fetching to a load function:
24
+
25
+ ```ts
26
+ // src/routes/products/+page.server.ts
27
+ export async function load({ fetch }) {
28
+ const products = await fetch('/api/products').then(r => r.json());
29
+ return { products };
30
+ }
31
+ ```
32
+
33
+ ```svelte
34
+ <!-- src/routes/products/+page.svelte -->
35
+ <script>
36
+ export let data;
37
+ </script>
38
+
39
+ {#each data.products as product}
40
+ <div>{product.name}</div>
41
+ {/each}
42
+ ```
43
+
44
+ - code: SVELTEKIT_NO_LAYOUT_HEAD
45
+ severity: warning
46
+ title: "Missing svelte:head in layout"
47
+ description: "Common meta tags should be in a layout for consistency."
48
+ howToFix: |
49
+ Add svelte:head to your layout:
50
+
51
+ ```svelte
52
+ <!-- src/routes/+layout.svelte -->
53
+ <script>
54
+ import { page } from '$app/stores';
55
+ </script>
56
+
57
+ <svelte:head>
58
+ <title>{$page.data.title ?? 'Your Site'}</title>
59
+ <meta name="description" content={$page.data.description ?? 'Default description'} />
60
+ <link rel="canonical" href={$page.url.href} />
61
+ </svelte:head>
62
+
63
+ <slot />
64
+ ```
65
+
66
+ - code: SVELTEKIT_NO_PRERENDER
67
+ severity: notice
68
+ title: "Static pages not prerendered"
69
+ description: "Static pages should be prerendered for best performance."
70
+ howToFix: |
71
+ Add prerender to static pages:
72
+
73
+ ```ts
74
+ // src/routes/about/+page.ts
75
+ export const prerender = true;
76
+ ```
77
+
78
+ Or set default in svelte.config.js:
79
+ ```js
80
+ kit: {
81
+ prerender: {
82
+ default: true
83
+ }
84
+ }
85
+ ```
86
+
87
+ - code: SVELTEKIT_NO_TRAILING_SLASH
88
+ severity: notice
89
+ title: "Inconsistent trailing slash handling"
90
+ description: "Configure trailing slash to avoid duplicate content."
91
+ howToFix: |
92
+ Set in svelte.config.js:
93
+
94
+ ```js
95
+ kit: {
96
+ trailingSlash: 'never' // or 'always'
97
+ }
98
+ ```
99
+
100
+ - code: SVELTEKIT_ENHANCED_IMAGE
101
+ severity: notice
102
+ title: "Not using enhanced images"
103
+ description: "SvelteKit supports enhanced images with @sveltejs/enhanced-img."
104
+ howToFix: |
105
+ Install enhanced images:
106
+
107
+ ```bash
108
+ npm install @sveltejs/enhanced-img
109
+ ```
110
+
111
+ ```svelte
112
+ <script>
113
+ import { Image } from '@sveltejs/enhanced-img';
114
+ import heroImage from '$lib/images/hero.jpg';
115
+ </script>
116
+
117
+ <Image src={heroImage} alt="Hero" />
118
+ ```
119
+
120
+ - code: SVELTEKIT_NO_SITEMAP
121
+ severity: warning
122
+ title: "Missing sitemap"
123
+ description: "Use svelte-sitemap or generate manually."
124
+ howToFix: |
125
+ Option 1: Use svelte-sitemap
126
+ ```bash
127
+ npm install svelte-sitemap
128
+ npx svelte-sitemap --domain https://yoursite.com
129
+ ```
130
+
131
+ Option 2: Create src/routes/sitemap.xml/+server.ts:
132
+ ```ts
133
+ export async function GET() {
134
+ const pages = ['/', '/about', '/products'];
135
+ const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
136
+ <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
137
+ ${pages.map(page => `
138
+ <url>
139
+ <loc>https://yoursite.com${page}</loc>
140
+ </url>
141
+ `).join('')}
142
+ </urlset>`;
143
+ return new Response(sitemap, {
144
+ headers: { 'Content-Type': 'application/xml' }
145
+ });
146
+ }
147
+ ```
148
+
149
+ performance_tips:
150
+ - "Use load functions for SSR data"
151
+ - "Prerender static pages"
152
+ - "Use streaming for slow data sources"
153
+ - "Leverage Svelte's small runtime"
154
+ - "Use form actions for progressive enhancement"
@@ -0,0 +1,137 @@
1
+ # Vue.js SEO Recipe
2
+ # Similar challenges to React for client-side rendered apps
3
+
4
+ framework: vue
5
+ display_name: Vue.js
6
+ category: spa
7
+ ssr_default: false
8
+
9
+ seo_challenges:
10
+ - "Client-side rendering sends empty HTML to crawlers"
11
+ - "Vue Router requires proper server configuration"
12
+ - "Async components delay content rendering"
13
+ - "No built-in meta tag management"
14
+
15
+ checks:
16
+ - code: VUE_CSR_DETECTED
17
+ severity: error
18
+ title: "Client-side rendered Vue app detected"
19
+ description: "Vue apps without SSR send empty HTML to crawlers."
20
+ impact: "Your content may not be indexed by search engines"
21
+ howToFix: |
22
+ Option 1: Migrate to Nuxt for automatic SSR/SSG
23
+ Option 2: Add SSR with @vue/server-renderer
24
+ Option 3: Use prerendering with prerender-spa-plugin
25
+
26
+ For Nuxt migration, most Vue components work directly.
27
+
28
+ - code: VUE_NO_META_MANAGEMENT
29
+ severity: error
30
+ title: "No meta tag management library"
31
+ description: "Title and meta description are not dynamically managed."
32
+ howToFix: |
33
+ Install @vueuse/head or vue-meta:
34
+
35
+ ```bash
36
+ npm install @vueuse/head
37
+ ```
38
+
39
+ ```ts
40
+ // main.ts
41
+ import { createHead } from '@vueuse/head';
42
+ const head = createHead();
43
+ app.use(head);
44
+ ```
45
+
46
+ ```vue
47
+ <script setup>
48
+ import { useHead } from '@vueuse/head';
49
+
50
+ useHead({
51
+ title: 'Page Title',
52
+ meta: [
53
+ { name: 'description', content: 'Page description' },
54
+ ],
55
+ });
56
+ </script>
57
+ ```
58
+
59
+ - code: VUE_ROUTER_HISTORY_MODE
60
+ severity: warning
61
+ title: "Vue Router not in history mode"
62
+ description: "Hash mode (#/) creates ugly URLs and SEO issues."
63
+ howToFix: |
64
+ Use createWebHistory instead of createWebHashHistory:
65
+
66
+ ```ts
67
+ import { createRouter, createWebHistory } from 'vue-router';
68
+
69
+ const router = createRouter({
70
+ history: createWebHistory(),
71
+ routes: [...],
72
+ });
73
+ ```
74
+
75
+ Then configure your server to return index.html for all routes.
76
+
77
+ - code: VUE_ASYNC_COMPONENT_NO_LOADING
78
+ severity: warning
79
+ title: "Async components without loading state"
80
+ description: "Async components can cause CLS when they pop in."
81
+ howToFix: |
82
+ Provide a loading component:
83
+
84
+ ```ts
85
+ import { defineAsyncComponent } from 'vue';
86
+
87
+ const AsyncComp = defineAsyncComponent({
88
+ loader: () => import('./HeavyComponent.vue'),
89
+ loadingComponent: LoadingSpinner,
90
+ delay: 200,
91
+ });
92
+ ```
93
+
94
+ - code: VUE_NO_KEY_ON_LIST
95
+ severity: notice
96
+ title: "v-for without :key attribute"
97
+ description: "Missing keys can cause rendering issues and affect SEO crawling."
98
+ howToFix: |
99
+ Always use :key with v-for:
100
+
101
+ ```vue
102
+ <div v-for="item in items" :key="item.id">
103
+ {{ item.name }}
104
+ </div>
105
+ ```
106
+
107
+ - code: VUE_TRANSITION_CLS
108
+ severity: notice
109
+ title: "Transitions may cause layout shifts"
110
+ description: "CSS transitions that change element size cause CLS."
111
+ howToFix: |
112
+ Use transform instead of width/height changes:
113
+
114
+ ```css
115
+ /* Bad - causes CLS */
116
+ .fade-enter-active { height: 0 to 100px; }
117
+
118
+ /* Good - no CLS */
119
+ .fade-enter-active { transform: scaleY(0) to scaleY(1); }
120
+ ```
121
+
122
+ performance_tips:
123
+ - "Use Vite for faster development and optimized builds"
124
+ - "Lazy load routes with dynamic imports"
125
+ - "Use v-once for static content"
126
+ - "Use v-memo for expensive list items"
127
+ - "Consider Nuxt for SSR/SSG"
128
+
129
+ migration_paths:
130
+ nuxt:
131
+ effort: low
132
+ benefits:
133
+ - "Automatic SSR/SSG"
134
+ - "File-based routing"
135
+ - "Auto-imports"
136
+ - "Built-in SEO utilities"
137
+ guide: "https://nuxt.com/docs/migration/overview"
@@ -0,0 +1,209 @@
1
+ # WordPress SEO Recipe
2
+ # WordPress powers 40%+ of the web - SEO is well-supported with plugins
3
+
4
+ framework: wordpress
5
+ display_name: WordPress
6
+ category: cms
7
+ ssr_default: true # PHP renders on server
8
+
9
+ seo_strengths:
10
+ - "Server-rendered HTML by default"
11
+ - "Mature SEO plugin ecosystem"
12
+ - "Built-in canonical URL support"
13
+ - "Sitemap generation via plugins"
14
+ - "Structured data plugins available"
15
+
16
+ seo_challenges:
17
+ - "Plugin bloat can slow performance"
18
+ - "Default themes often lack optimization"
19
+ - "Image optimization requires plugins"
20
+ - "Caching needed for performance"
21
+
22
+ checks:
23
+ - code: WORDPRESS_NO_SEO_PLUGIN
24
+ severity: warning
25
+ title: "No SEO plugin detected"
26
+ description: "WordPress benefits greatly from an SEO plugin like Yoast or Rank Math."
27
+ howToFix: |
28
+ Install an SEO plugin:
29
+
30
+ **Yoast SEO** (most popular):
31
+ 1. Go to Plugins > Add New
32
+ 2. Search "Yoast SEO"
33
+ 3. Install and activate
34
+
35
+ **Rank Math** (feature-rich free tier):
36
+ 1. Go to Plugins > Add New
37
+ 2. Search "Rank Math"
38
+ 3. Install and activate
39
+
40
+ Both provide:
41
+ - Meta title/description management
42
+ - XML sitemap generation
43
+ - Schema markup
44
+ - Content analysis
45
+
46
+ - code: WORDPRESS_OUTDATED
47
+ severity: error
48
+ title: "WordPress core is outdated"
49
+ description: "Running outdated WordPress is a security risk and may have SEO bugs."
50
+ howToFix: |
51
+ Update WordPress:
52
+ 1. Backup your site first
53
+ 2. Go to Dashboard > Updates
54
+ 3. Click "Update Now"
55
+
56
+ Enable auto-updates in wp-config.php:
57
+ ```php
58
+ define('WP_AUTO_UPDATE_CORE', true);
59
+ ```
60
+
61
+ - code: WORDPRESS_NO_CACHING
62
+ severity: warning
63
+ title: "No caching plugin detected"
64
+ description: "WordPress without caching is slow, hurting Core Web Vitals."
65
+ howToFix: |
66
+ Install a caching plugin:
67
+
68
+ **WP Super Cache** (simple):
69
+ - Easy setup, good for most sites
70
+
71
+ **W3 Total Cache** (advanced):
72
+ - More features, steeper learning curve
73
+
74
+ **LiteSpeed Cache** (if on LiteSpeed server):
75
+ - Best performance on compatible hosts
76
+
77
+ - code: WORDPRESS_LARGE_IMAGES
78
+ severity: warning
79
+ title: "Images not optimized"
80
+ description: "Large images slow down WordPress significantly."
81
+ howToFix: |
82
+ Install an image optimization plugin:
83
+
84
+ **ShortPixel** or **Smush**:
85
+ - Compresses existing images
86
+ - Optimizes on upload
87
+ - WebP conversion
88
+
89
+ Or use Cloudflare Polish for automatic optimization.
90
+
91
+ - code: WORDPRESS_TOO_MANY_PLUGINS
92
+ severity: warning
93
+ title: "Too many plugins installed"
94
+ description: "Each plugin adds overhead. Many sites have 30+ plugins when 10-15 suffice."
95
+ howToFix: |
96
+ Audit your plugins:
97
+ 1. Go to Plugins > Installed Plugins
98
+ 2. Deactivate plugins not in use
99
+ 3. Delete deactivated plugins
100
+ 4. Consider consolidating (one SEO plugin, one security plugin)
101
+
102
+ Aim for under 20 plugins.
103
+
104
+ - code: WORDPRESS_NO_LAZY_LOAD
105
+ severity: notice
106
+ title: "Native lazy loading not enabled"
107
+ description: "WordPress 5.5+ has native lazy loading, but themes may disable it."
108
+ howToFix: |
109
+ Check if lazy loading is enabled:
110
+ ```php
111
+ // In functions.php, remove if present:
112
+ add_filter('wp_lazy_loading_enabled', '__return_false');
113
+ ```
114
+
115
+ For older WordPress, add:
116
+ ```php
117
+ add_filter('wp_lazy_loading_enabled', '__return_true');
118
+ ```
119
+
120
+ - code: WORDPRESS_NO_WEBP
121
+ severity: notice
122
+ title: "Not serving WebP images"
123
+ description: "WebP images are 25-35% smaller than JPEG."
124
+ howToFix: |
125
+ Use a plugin that serves WebP:
126
+
127
+ 1. **ShortPixel**: Auto-converts and serves WebP
128
+ 2. **WebP Express**: Converts and configures server
129
+
130
+ Or use Cloudflare with Polish enabled for automatic WebP.
131
+
132
+ - code: WORDPRESS_NO_PRELOAD_HINTS
133
+ severity: notice
134
+ title: "Missing resource hints"
135
+ description: "Preload hints can speed up critical resources."
136
+ howToFix: |
137
+ Add to your theme's functions.php:
138
+
139
+ ```php
140
+ function add_resource_hints() {
141
+ // Preload critical font
142
+ echo '<link rel="preload" href="/wp-content/themes/yourtheme/fonts/main.woff2" as="font" type="font/woff2" crossorigin>';
143
+
144
+ // Preconnect to external domains
145
+ echo '<link rel="preconnect" href="https://fonts.googleapis.com">';
146
+ }
147
+ add_action('wp_head', 'add_resource_hints', 1);
148
+ ```
149
+
150
+ - code: WORDPRESS_BLOCKING_SCRIPTS
151
+ severity: warning
152
+ title: "Render-blocking scripts detected"
153
+ description: "JavaScript in <head> blocks rendering."
154
+ howToFix: |
155
+ Use a plugin like **Autoptimize** or **Asset CleanUp** to:
156
+ - Defer JavaScript
157
+ - Inline critical CSS
158
+ - Combine files
159
+
160
+ Or add defer manually in functions.php:
161
+ ```php
162
+ function defer_scripts($tag, $handle) {
163
+ if (is_admin()) return $tag;
164
+ return str_replace(' src', ' defer src', $tag);
165
+ }
166
+ add_filter('script_loader_tag', 'defer_scripts', 10, 2);
167
+ ```
168
+
169
+ - code: WORDPRESS_NO_SCHEMA
170
+ severity: warning
171
+ title: "No structured data detected"
172
+ description: "Schema markup helps with rich snippets."
173
+ howToFix: |
174
+ **If using Yoast/Rank Math**: Schema is included.
175
+
176
+ **Manual schema** in theme:
177
+ ```php
178
+ function add_organization_schema() {
179
+ if (is_front_page()) {
180
+ echo '<script type="application/ld+json">
181
+ {
182
+ "@context": "https://schema.org",
183
+ "@type": "Organization",
184
+ "name": "Your Company",
185
+ "url": "' . home_url() . '"
186
+ }
187
+ </script>';
188
+ }
189
+ }
190
+ add_action('wp_footer', 'add_organization_schema');
191
+ ```
192
+
193
+ performance_tips:
194
+ - "Use a quality managed WordPress host (WP Engine, Kinsta)"
195
+ - "Enable object caching (Redis/Memcached)"
196
+ - "Use a CDN (Cloudflare, Fastly)"
197
+ - "Keep plugins under 20"
198
+ - "Choose a lightweight theme (GeneratePress, Astra)"
199
+ - "Disable unnecessary features (emojis, embeds)"
200
+
201
+ recommended_plugins:
202
+ seo:
203
+ - "Yoast SEO or Rank Math"
204
+ performance:
205
+ - "WP Super Cache or LiteSpeed Cache"
206
+ - "ShortPixel or Smush (images)"
207
+ - "Autoptimize (JS/CSS)"
208
+ security:
209
+ - "Wordfence or Sucuri"