@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,268 @@
1
+ # Next.js SEO Recipe
2
+ # Next.js has excellent SEO by default, but there are still common mistakes
3
+
4
+ framework: nextjs
5
+ display_name: Next.js
6
+ category: meta-framework
7
+ base_framework: react
8
+ ssr_default: true
9
+
10
+ seo_strengths:
11
+ - "Server-side rendering by default"
12
+ - "Static site generation support"
13
+ - "Built-in Image component with optimization"
14
+ - "Automatic code splitting"
15
+ - "File-based routing"
16
+ - "Built-in metadata API (App Router)"
17
+
18
+ checks:
19
+ # App Router specific
20
+ - code: NEXTJS_NO_METADATA_API
21
+ severity: warning
22
+ title: "Not using Next.js Metadata API"
23
+ description: "Next.js 13+ has a built-in Metadata API that's better than react-helmet."
24
+ howToFix: |
25
+ Use the Metadata API in your layout or page:
26
+
27
+ ```tsx
28
+ // app/page.tsx
29
+ import { Metadata } from 'next';
30
+
31
+ export const metadata: Metadata = {
32
+ title: 'Page Title',
33
+ description: 'Page description',
34
+ openGraph: {
35
+ title: 'OG Title',
36
+ description: 'OG Description',
37
+ images: ['/og-image.jpg'],
38
+ },
39
+ };
40
+
41
+ // For dynamic metadata
42
+ export async function generateMetadata({ params }): Promise<Metadata> {
43
+ const product = await getProduct(params.id);
44
+ return {
45
+ title: product.name,
46
+ description: product.description,
47
+ };
48
+ }
49
+ ```
50
+ app_router_only: true
51
+
52
+ - code: NEXTJS_GENERATESTATICPARAMS_MISSING
53
+ severity: warning
54
+ title: "Dynamic routes without generateStaticParams"
55
+ description: "Dynamic routes like [id] should pre-generate static pages for SEO."
56
+ howToFix: |
57
+ Add generateStaticParams to pre-render dynamic pages:
58
+
59
+ ```tsx
60
+ // app/products/[id]/page.tsx
61
+ export async function generateStaticParams() {
62
+ const products = await getProducts();
63
+ return products.map((product) => ({
64
+ id: product.id.toString(),
65
+ }));
66
+ }
67
+ ```
68
+ app_router_only: true
69
+
70
+ # Pages Router specific
71
+ - code: NEXTJS_NO_GETSTATICPROPS
72
+ severity: warning
73
+ title: "Pages without getStaticProps/getServerSideProps"
74
+ description: "Pages fetching data client-side miss SEO benefits of SSR/SSG."
75
+ howToFix: |
76
+ Move data fetching to getStaticProps (for static) or getServerSideProps (for dynamic):
77
+
78
+ ```tsx
79
+ // pages/products.tsx
80
+ export async function getStaticProps() {
81
+ const products = await fetchProducts();
82
+ return {
83
+ props: { products },
84
+ revalidate: 3600, // ISR: regenerate every hour
85
+ };
86
+ }
87
+ ```
88
+ pages_router_only: true
89
+
90
+ # Common issues
91
+ - code: NEXTJS_IMAGE_NOT_USED
92
+ severity: warning
93
+ title: "Using <img> instead of next/image"
94
+ description: "The next/image component provides automatic optimization, lazy loading, and prevents CLS."
95
+ howToFix: |
96
+ Replace <img> with next/image:
97
+
98
+ ```tsx
99
+ import Image from 'next/image';
100
+
101
+ // Before
102
+ <img src="/hero.jpg" alt="Hero" />
103
+
104
+ // After
105
+ <Image
106
+ src="/hero.jpg"
107
+ alt="Hero"
108
+ width={1200}
109
+ height={630}
110
+ priority // for above-the-fold images
111
+ />
112
+ ```
113
+
114
+ - code: NEXTJS_NO_PRIORITY_IMAGE
115
+ severity: notice
116
+ title: "LCP image missing priority prop"
117
+ description: "The largest image above the fold should have priority={true} for faster LCP."
118
+ howToFix: |
119
+ Add priority to your hero/LCP image:
120
+
121
+ ```tsx
122
+ <Image
123
+ src="/hero.jpg"
124
+ alt="Hero"
125
+ width={1200}
126
+ height={630}
127
+ priority
128
+ />
129
+ ```
130
+
131
+ - code: NEXTJS_LINK_NO_PREFETCH
132
+ severity: notice
133
+ title: "Link without prefetch consideration"
134
+ description: "Next.js prefetches all links by default, which can waste bandwidth."
135
+ howToFix: |
136
+ Disable prefetch for less important links:
137
+
138
+ ```tsx
139
+ <Link href="/terms" prefetch={false}>
140
+ Terms of Service
141
+ </Link>
142
+ ```
143
+
144
+ - code: NEXTJS_NO_ROBOTS_TXT
145
+ severity: warning
146
+ title: "Missing robots.txt configuration"
147
+ description: "Next.js can generate robots.txt automatically."
148
+ howToFix: |
149
+ App Router - create app/robots.ts:
150
+ ```tsx
151
+ import { MetadataRoute } from 'next';
152
+
153
+ export default function robots(): MetadataRoute.Robots {
154
+ return {
155
+ rules: {
156
+ userAgent: '*',
157
+ allow: '/',
158
+ disallow: '/api/',
159
+ },
160
+ sitemap: 'https://yoursite.com/sitemap.xml',
161
+ };
162
+ }
163
+ ```
164
+
165
+ Pages Router - create public/robots.txt or use next-sitemap package.
166
+
167
+ - code: NEXTJS_NO_SITEMAP
168
+ severity: warning
169
+ title: "Missing sitemap configuration"
170
+ description: "Next.js can generate sitemaps automatically."
171
+ howToFix: |
172
+ App Router - create app/sitemap.ts:
173
+ ```tsx
174
+ import { MetadataRoute } from 'next';
175
+
176
+ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
177
+ const products = await getProducts();
178
+
179
+ return [
180
+ { url: 'https://yoursite.com', lastModified: new Date() },
181
+ { url: 'https://yoursite.com/about', lastModified: new Date() },
182
+ ...products.map((product) => ({
183
+ url: `https://yoursite.com/products/${product.id}`,
184
+ lastModified: product.updatedAt,
185
+ })),
186
+ ];
187
+ }
188
+ ```
189
+
190
+ - code: NEXTJS_USE_CLIENT_OVERUSE
191
+ severity: warning
192
+ title: "Overusing 'use client' directive"
193
+ description: "Too many client components reduces SSR benefits."
194
+ howToFix: |
195
+ Keep 'use client' at the leaf level:
196
+
197
+ ```tsx
198
+ // Bad - entire page is client-rendered
199
+ 'use client';
200
+ export default function Page() { ... }
201
+
202
+ // Good - only interactive parts are client
203
+ // page.tsx (Server Component)
204
+ import ClientButton from './ClientButton';
205
+ export default function Page() {
206
+ return <div>
207
+ <h1>Server rendered content</h1>
208
+ <ClientButton /> {/* Only this is client */}
209
+ </div>
210
+ }
211
+ ```
212
+
213
+ - code: NEXTJS_FONT_NOT_OPTIMIZED
214
+ severity: notice
215
+ title: "Not using next/font for fonts"
216
+ description: "next/font automatically optimizes fonts and prevents CLS."
217
+ howToFix: |
218
+ Use next/font for Google Fonts or local fonts:
219
+
220
+ ```tsx
221
+ import { Inter } from 'next/font/google';
222
+
223
+ const inter = Inter({ subsets: ['latin'] });
224
+
225
+ export default function RootLayout({ children }) {
226
+ return (
227
+ <html lang="en" className={inter.className}>
228
+ <body>{children}</body>
229
+ </html>
230
+ );
231
+ }
232
+ ```
233
+
234
+ - code: NEXTJS_NO_TRAILING_SLASH_CONFIG
235
+ severity: notice
236
+ title: "Inconsistent trailing slash handling"
237
+ description: "Inconsistent URLs can cause duplicate content issues."
238
+ howToFix: |
239
+ Configure trailingSlash in next.config.js:
240
+
241
+ ```js
242
+ module.exports = {
243
+ trailingSlash: true, // or false
244
+ };
245
+ ```
246
+
247
+ performance_tips:
248
+ - "Use React Server Components for static content"
249
+ - "Add priority to LCP images"
250
+ - "Use next/font for fonts"
251
+ - "Enable ISR for frequently updated pages"
252
+ - "Use Route Handlers instead of API routes for server-only logic"
253
+
254
+ structured_data:
255
+ - type: "JSON-LD in metadata"
256
+ example: |
257
+ ```tsx
258
+ export const metadata: Metadata = {
259
+ other: {
260
+ 'script:ld+json': JSON.stringify({
261
+ '@context': 'https://schema.org',
262
+ '@type': 'Organization',
263
+ name: 'Your Company',
264
+ url: 'https://yoursite.com',
265
+ }),
266
+ },
267
+ };
268
+ ```
@@ -0,0 +1,175 @@
1
+ # Nuxt SEO Recipe
2
+ # Nuxt has excellent SEO capabilities, similar to Next.js for Vue
3
+
4
+ framework: nuxt
5
+ display_name: Nuxt
6
+ category: meta-framework
7
+ base_framework: vue
8
+ ssr_default: true
9
+
10
+ seo_strengths:
11
+ - "Universal rendering (SSR) by default"
12
+ - "Static site generation support"
13
+ - "Built-in useSeoMeta composable"
14
+ - "Automatic code splitting"
15
+ - "File-based routing"
16
+ - "NuxtImage for image optimization"
17
+
18
+ checks:
19
+ - code: NUXT_NO_USESEOMETA
20
+ severity: warning
21
+ title: "Not using useSeoMeta composable"
22
+ description: "Nuxt 3 has built-in SEO meta composables that are cleaner than useHead."
23
+ howToFix: |
24
+ Use useSeoMeta for SEO tags:
25
+
26
+ ```vue
27
+ <script setup>
28
+ useSeoMeta({
29
+ title: 'Page Title',
30
+ description: 'Page description',
31
+ ogTitle: 'OG Title',
32
+ ogDescription: 'OG Description',
33
+ ogImage: '/og-image.jpg',
34
+ twitterCard: 'summary_large_image',
35
+ });
36
+ </script>
37
+ ```
38
+
39
+ - code: NUXT_USEFETCH_CLIENT_ONLY
40
+ severity: warning
41
+ title: "Data fetching only on client side"
42
+ description: "Using onMounted for data fetching bypasses SSR benefits."
43
+ howToFix: |
44
+ Use useFetch or useAsyncData instead:
45
+
46
+ ```vue
47
+ <script setup>
48
+ // Bad - client only
49
+ const data = ref(null);
50
+ onMounted(async () => {
51
+ data.value = await $fetch('/api/data');
52
+ });
53
+
54
+ // Good - SSR friendly
55
+ const { data } = await useFetch('/api/data');
56
+ </script>
57
+ ```
58
+
59
+ - code: NUXT_NO_NUXT_IMAGE
60
+ severity: warning
61
+ title: "Not using NuxtImage for images"
62
+ description: "@nuxt/image provides automatic optimization and responsive images."
63
+ howToFix: |
64
+ Install and use NuxtImage:
65
+
66
+ ```bash
67
+ npx nuxi module add image
68
+ ```
69
+
70
+ ```vue
71
+ <template>
72
+ <NuxtImg
73
+ src="/hero.jpg"
74
+ alt="Hero"
75
+ width="1200"
76
+ height="630"
77
+ preload
78
+ />
79
+ </template>
80
+ ```
81
+
82
+ - code: NUXT_NO_ROBOTS
83
+ severity: warning
84
+ title: "Missing robots.txt configuration"
85
+ description: "Use @nuxtjs/robots module for robots.txt."
86
+ howToFix: |
87
+ Install and configure robots module:
88
+
89
+ ```bash
90
+ npm install @nuxtjs/robots
91
+ ```
92
+
93
+ ```ts
94
+ // nuxt.config.ts
95
+ export default defineNuxtConfig({
96
+ modules: ['@nuxtjs/robots'],
97
+ robots: {
98
+ rules: [
99
+ { UserAgent: '*', Allow: '/' },
100
+ { UserAgent: '*', Disallow: '/api/' },
101
+ ],
102
+ sitemap: 'https://yoursite.com/sitemap.xml',
103
+ },
104
+ });
105
+ ```
106
+
107
+ - code: NUXT_NO_SITEMAP
108
+ severity: warning
109
+ title: "Missing sitemap configuration"
110
+ description: "Use @nuxtjs/sitemap module for automatic sitemap."
111
+ howToFix: |
112
+ Install sitemap module:
113
+
114
+ ```bash
115
+ npm install @nuxtjs/sitemap
116
+ ```
117
+
118
+ ```ts
119
+ // nuxt.config.ts
120
+ export default defineNuxtConfig({
121
+ modules: ['@nuxtjs/sitemap'],
122
+ sitemap: {
123
+ hostname: 'https://yoursite.com',
124
+ },
125
+ });
126
+ ```
127
+
128
+ - code: NUXT_SPA_MODE
129
+ severity: error
130
+ title: "Nuxt running in SPA mode"
131
+ description: "SPA mode disables SSR, losing SEO benefits."
132
+ howToFix: |
133
+ Remove ssr: false from nuxt.config.ts:
134
+
135
+ ```ts
136
+ export default defineNuxtConfig({
137
+ // Remove this line
138
+ // ssr: false,
139
+ });
140
+ ```
141
+
142
+ If you need client-only components, use <ClientOnly>:
143
+ ```vue
144
+ <ClientOnly>
145
+ <BrowserOnlyWidget />
146
+ </ClientOnly>
147
+ ```
148
+
149
+ - code: NUXT_NO_PRERENDER
150
+ severity: notice
151
+ title: "Static pages not pre-rendered"
152
+ description: "Static pages could be pre-rendered for better performance."
153
+ howToFix: |
154
+ Enable route prerendering in nuxt.config.ts:
155
+
156
+ ```ts
157
+ export default defineNuxtConfig({
158
+ routeRules: {
159
+ '/about': { prerender: true },
160
+ '/blog/**': { prerender: true },
161
+ },
162
+ });
163
+ ```
164
+
165
+ Or generate a fully static site:
166
+ ```bash
167
+ nuxt generate
168
+ ```
169
+
170
+ performance_tips:
171
+ - "Use useLazyFetch for non-critical data"
172
+ - "Add preload prop to NuxtImg for LCP images"
173
+ - "Use Nuxt DevTools to identify performance issues"
174
+ - "Configure image provider for CDN delivery"
175
+ - "Use route rules for caching strategies"
@@ -0,0 +1,188 @@
1
+ # Ruby on Rails SEO Recipe
2
+ # Rails is server-rendered by default, excellent for SEO
3
+
4
+ framework: rails
5
+ display_name: Ruby on Rails
6
+ category: server-rendered
7
+ ssr_default: true
8
+
9
+ seo_strengths:
10
+ - "Server-rendered HTML by default"
11
+ - "Turbo for fast navigation without SPA"
12
+ - "Strong conventions reduce mistakes"
13
+ - "Mature gem ecosystem"
14
+
15
+ checks:
16
+ - code: RAILS_NO_META_TAGS_GEM
17
+ severity: warning
18
+ title: "Not using meta-tags gem"
19
+ description: "The meta-tags gem provides a clean API for SEO tags."
20
+ howToFix: |
21
+ Add meta-tags to Gemfile:
22
+
23
+ ```ruby
24
+ gem 'meta-tags'
25
+ ```
26
+
27
+ Run `bundle install`, then:
28
+
29
+ ```ruby
30
+ # app/views/layouts/application.html.erb
31
+ <head>
32
+ <%= display_meta_tags site: 'Your Site' %>
33
+ </head>
34
+ ```
35
+
36
+ ```ruby
37
+ # In controllers or views
38
+ set_meta_tags title: 'Page Title',
39
+ description: 'Page description',
40
+ keywords: 'seo, rails'
41
+ ```
42
+
43
+ - code: RAILS_NO_SITEMAP_GEM
44
+ severity: warning
45
+ title: "Not using sitemap_generator gem"
46
+ description: "sitemap_generator creates SEO-friendly sitemaps automatically."
47
+ howToFix: |
48
+ Add to Gemfile:
49
+
50
+ ```ruby
51
+ gem 'sitemap_generator'
52
+ ```
53
+
54
+ Generate config:
55
+ ```bash
56
+ rails sitemap:install
57
+ ```
58
+
59
+ Configure config/sitemap.rb:
60
+ ```ruby
61
+ SitemapGenerator::Sitemap.default_host = "https://yoursite.com"
62
+
63
+ SitemapGenerator::Sitemap.create do
64
+ add '/about', changefreq: 'monthly'
65
+ Product.find_each do |product|
66
+ add product_path(product), lastmod: product.updated_at
67
+ end
68
+ end
69
+ ```
70
+
71
+ Generate: `rails sitemap:refresh`
72
+
73
+ - code: RAILS_NO_CANONICAL
74
+ severity: warning
75
+ title: "Missing canonical URLs"
76
+ description: "Rails apps with multiple URLs for same content need canonicals."
77
+ howToFix: |
78
+ Add canonical tag in layout:
79
+
80
+ ```erb
81
+ <!-- Using meta-tags gem -->
82
+ <%= display_meta_tags canonical: request.original_url %>
83
+
84
+ <!-- Or manually -->
85
+ <link rel="canonical" href="<%= request.original_url.split('?').first %>" />
86
+ ```
87
+
88
+ - code: RAILS_TURBO_BREAKS_CRAWLERS
89
+ severity: notice
90
+ title: "Turbo may affect JavaScript-dependent crawlers"
91
+ description: "Turbo Drive updates pages via JavaScript, which some crawlers may miss."
92
+ howToFix: |
93
+ For SEO-critical pages, ensure content is in initial HTML.
94
+
95
+ For dynamic content, add data-turbo="false":
96
+ ```erb
97
+ <%= link_to 'Critical Page', critical_path, data: { turbo: false } %>
98
+ ```
99
+
100
+ Or disable for specific pages:
101
+ ```erb
102
+ <meta name="turbo-visit-control" content="reload">
103
+ ```
104
+
105
+ - code: RAILS_NO_JSON_LD
106
+ severity: notice
107
+ title: "No structured data detected"
108
+ description: "Add JSON-LD for rich snippets."
109
+ howToFix: |
110
+ Create a helper:
111
+
112
+ ```ruby
113
+ # app/helpers/seo_helper.rb
114
+ module SeoHelper
115
+ def json_ld(data)
116
+ content_tag :script, data.to_json.html_safe,
117
+ type: 'application/ld+json'
118
+ end
119
+ end
120
+ ```
121
+
122
+ Use in views:
123
+ ```erb
124
+ <%= json_ld({
125
+ "@context" => "https://schema.org",
126
+ "@type" => "Product",
127
+ "name" => @product.name,
128
+ "description" => @product.description
129
+ }) %>
130
+ ```
131
+
132
+ - code: RAILS_SLOW_QUERIES
133
+ severity: warning
134
+ title: "N+1 queries may slow pages"
135
+ description: "Slow pages hurt SEO. Use includes/eager_load."
136
+ howToFix: |
137
+ Use bullet gem to detect N+1:
138
+
139
+ ```ruby
140
+ # Gemfile
141
+ gem 'bullet', group: 'development'
142
+ ```
143
+
144
+ Fix with includes:
145
+ ```ruby
146
+ # Before (N+1)
147
+ @posts = Post.all
148
+ @posts.each { |p| p.author.name }
149
+
150
+ # After (2 queries)
151
+ @posts = Post.includes(:author).all
152
+ ```
153
+
154
+ - code: RAILS_NO_CACHING
155
+ severity: notice
156
+ title: "Page caching not configured"
157
+ description: "Rails caching can dramatically improve response times."
158
+ howToFix: |
159
+ Enable caching in production:
160
+
161
+ ```ruby
162
+ # config/environments/production.rb
163
+ config.action_controller.perform_caching = true
164
+ config.cache_store = :redis_cache_store, { url: ENV['REDIS_URL'] }
165
+ ```
166
+
167
+ Use fragment caching:
168
+ ```erb
169
+ <% cache @product do %>
170
+ <%= render @product %>
171
+ <% end %>
172
+ ```
173
+
174
+ performance_tips:
175
+ - "Use Russian doll caching for nested views"
176
+ - "Enable asset fingerprinting and CDN"
177
+ - "Use Turbo for SPA-like experience"
178
+ - "Profile with rack-mini-profiler"
179
+ - "Use Postgres for full-text search instead of LIKE"
180
+
181
+ recommended_gems:
182
+ seo:
183
+ - "meta-tags - SEO tag management"
184
+ - "sitemap_generator - XML sitemaps"
185
+ performance:
186
+ - "bullet - N+1 detection"
187
+ - "rack-mini-profiler - Performance profiling"
188
+ - "bootsnap - Faster boot times"