@lynxflow/seo-engine 1.6.0 → 1.6.2

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/dist/index.mjs CHANGED
@@ -3231,6 +3231,87 @@ function resolveBuiltInLocations(territories) {
3231
3231
  return results.length > 0 ? results : [...BUILT_IN_LOCATIONS_DATABASE.fr];
3232
3232
  }
3233
3233
 
3234
+ // src/og-image-generator.ts
3235
+ class OgImageGenerator {
3236
+ static generateOgImageUrl(domain, pageMeta, brandName) {
3237
+ const cleanDomain = domain.replace(/\/+$/, "");
3238
+ const params = new URLSearchParams({
3239
+ title: pageMeta.h1 || pageMeta.title,
3240
+ badge: pageMeta.matrixFamily.toUpperCase(),
3241
+ desc: pageMeta.description ? pageMeta.description.slice(0, 120) : "",
3242
+ brand: brandName
3243
+ });
3244
+ if (pageMeta.location) {
3245
+ params.set("loc", `${pageMeta.location.name}, ${pageMeta.location.country}`);
3246
+ }
3247
+ return `${cleanDomain}/api/og?${params.toString()}`;
3248
+ }
3249
+ static renderDynamicOgSvg(opts) {
3250
+ const brand = opts.brandName || "LynxSEO";
3251
+ const badge = opts.badgeText || "OFFICIAL";
3252
+ const title = opts.title.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
3253
+ const loc = opts.locationName ? `\uD83D\uDCCD ${opts.locationName}` : "⚡ Instant Cloud Setup";
3254
+ const rating = opts.ratingValue ?? 4.9;
3255
+ const reviews = opts.reviewCount ?? 1280;
3256
+ const accent = opts.brandColor || "#6366F1";
3257
+ return `<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
3258
+ <defs>
3259
+ <linearGradient id="bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
3260
+ <stop offset="0%" stop-color="#090D16"/>
3261
+ <stop offset="50%" stop-color="#0F172A"/>
3262
+ <stop offset="100%" stop-color="#020617"/>
3263
+ </linearGradient>
3264
+ <linearGradient id="textGrad" x1="0%" y1="0%" x2="100%" y2="0%">
3265
+ <stop offset="0%" stop-color="#FFFFFF"/>
3266
+ <stop offset="100%" stop-color="#CBD5E1"/>
3267
+ </linearGradient>
3268
+ <filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
3269
+ <feGaussianBlur stdDeviation="80" result="blur" />
3270
+ </filter>
3271
+ </defs>
3272
+
3273
+ <!-- Background -->
3274
+ <rect width="1200" height="630" fill="url(#bgGrad)"/>
3275
+
3276
+ <!-- Subtle Ambient Glow -->
3277
+ <circle cx="200" cy="150" r="220" fill="${accent}" opacity="0.15" filter="url(#glow)"/>
3278
+ <circle cx="1000" cy="480" r="260" fill="${accent}" opacity="0.12" filter="url(#glow)"/>
3279
+
3280
+ <!-- Top Glassmorphism Badge -->
3281
+ <g transform="translate(80, 80)">
3282
+ <rect width="220" height="42" rx="21" fill="${accent}" fill-opacity="0.15" stroke="${accent}" stroke-opacity="0.4" stroke-width="1.5"/>
3283
+ <text x="110" y="26" fill="#FFFFFF" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="14" font-weight="700" text-anchor="middle" letter-spacing="1.5">${badge}</text>
3284
+ </g>
3285
+
3286
+ <!-- Location / Scope Pill -->
3287
+ <g transform="translate(320, 80)">
3288
+ <rect width="260" height="42" rx="21" fill="#1E293B" fill-opacity="0.6" stroke="#334155" stroke-width="1"/>
3289
+ <text x="130" y="26" fill="#94A3B8" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="14" font-weight="600" text-anchor="middle">${loc}</text>
3290
+ </g>
3291
+
3292
+ <!-- Giant Title -->
3293
+ <text x="80" y="250" fill="url(#textGrad)" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="52" font-weight="900" letter-spacing="-1.5">
3294
+ <tspan x="80" dy="0">${title.slice(0, 38)}</tspan>
3295
+ ${title.length > 38 ? `<tspan x="80" dy="68">${title.slice(38, 80)}</tspan>` : ""}
3296
+ </text>
3297
+
3298
+ <!-- Trust Stars & Social Proof -->
3299
+ <g transform="translate(80, 470)">
3300
+ <text x="0" y="32" fill="#FBBF24" font-size="24">★★★★★</text>
3301
+ <text x="140" y="30" fill="#F8FAFC" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="20" font-weight="800">${rating} / 5</text>
3302
+ <text x="210" y="30" fill="#64748B" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="16" font-weight="500">(${reviews.toLocaleString()} verified reviews)</text>
3303
+ </g>
3304
+
3305
+ <!-- Footer Brand -->
3306
+ <g transform="translate(80, 540)">
3307
+ <line x1="0" y1="0" x2="1040" y2="0" stroke="#1E293B" stroke-width="1.5"/>
3308
+ <text x="0" y="42" fill="#FFFFFF" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="20" font-weight="800">${brand}</text>
3309
+ <text x="1040" y="42" fill="#64748B" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif" font-size="16" font-weight="500" text-anchor="end">Engineered with @lynxflow/seo-engine</text>
3310
+ </g>
3311
+ </svg>`;
3312
+ }
3313
+ }
3314
+
3234
3315
  // src/matrix-engine.ts
3235
3316
  class PseoMatrixEngine {
3236
3317
  legalEngine;
@@ -3735,6 +3816,11 @@ class PseoMatrixEngine {
3735
3816
  if (data.calculators) {
3736
3817
  allPages.push(...this.generateCalculatorMatrix(domain, data.calculators, options));
3737
3818
  }
3819
+ for (const p of allPages) {
3820
+ if (!p.ogImageUrl) {
3821
+ p.ogImageUrl = OgImageGenerator.generateOgImageUrl(domain, p, options.brandName);
3822
+ }
3823
+ }
3738
3824
  return allPages;
3739
3825
  }
3740
3826
  resolvePage(slugOrPath, domain, data, options) {
@@ -3978,6 +4064,119 @@ function renderBrandIconSvg(input, className = "w-5 h-5 inline-block") {
3978
4064
  return "";
3979
4065
  return `<svg class="${className}" viewBox="${icon.viewBox}" fill="currentColor" aria-hidden="true"><path d="${icon.svgPath}"/></svg>`;
3980
4066
  }
4067
+ // src/ui-icons.ts
4068
+ var UI_ICONS = {
4069
+ zap: {
4070
+ name: "Zap / Lightning",
4071
+ viewBox: "0 0 24 24",
4072
+ svgPath: '<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>'
4073
+ },
4074
+ shield: {
4075
+ name: "Shield / Security",
4076
+ viewBox: "0 0 24 24",
4077
+ svgPath: '<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>'
4078
+ },
4079
+ star: {
4080
+ name: "Star / Rating",
4081
+ viewBox: "0 0 24 24",
4082
+ svgPath: '<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" fill="currentColor"/>'
4083
+ },
4084
+ chart: {
4085
+ name: "Chart / Analytics",
4086
+ viewBox: "0 0 24 24",
4087
+ svgPath: '<line x1="18" y1="20" x2="18" y2="10" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><line x1="12" y1="20" x2="12" y2="4" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><line x1="6" y1="20" x2="6" y2="14" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>'
4088
+ },
4089
+ calendar: {
4090
+ name: "Calendar / Scheduling",
4091
+ viewBox: "0 0 24 24",
4092
+ svgPath: '<rect x="3" y="4" width="18" height="18" rx="2" ry="2" fill="none" stroke="currentColor" stroke-width="2"/><line x1="16" y1="2" x2="16" y2="6" stroke="currentColor" stroke-width="2"/><line x1="8" y1="2" x2="8" y2="6" stroke="currentColor" stroke-width="2"/><line x1="3" y1="10" x2="21" y2="10" stroke="currentColor" stroke-width="2"/>'
4093
+ },
4094
+ users: {
4095
+ name: "Users / Team",
4096
+ viewBox: "0 0 24 24",
4097
+ svgPath: '<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" fill="none" stroke="currentColor" stroke-width="2"/><circle cx="9" cy="7" r="4" fill="none" stroke="currentColor" stroke-width="2"/><path d="M23 21v-2a4 4 0 0 0-3-3.87" fill="none" stroke="currentColor" stroke-width="2"/><path d="M16 3.13a4 4 0 0 1 0 7.75" fill="none" stroke="currentColor" stroke-width="2"/>'
4098
+ },
4099
+ rocket: {
4100
+ name: "Rocket / Speed",
4101
+ viewBox: "0 0 24 24",
4102
+ svgPath: '<path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z" fill="none" stroke="currentColor" stroke-width="2"/><path d="m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z" fill="none" stroke="currentColor" stroke-width="2"/>'
4103
+ },
4104
+ sparkles: {
4105
+ name: "Sparkles / AI",
4106
+ viewBox: "0 0 24 24",
4107
+ svgPath: '<path d="m12 3-1.9 5.8a2 2 0 0 1-1.3 1.3L3 12l5.8 1.9a2 2 0 0 1 1.3 1.3L12 21l1.9-5.8a2 2 0 0 1 1.3-1.3L21 12l-5.8-1.9a2 2 0 0 1-1.3-1.3L12 3z" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round"/>'
4108
+ },
4109
+ check: {
4110
+ name: "Check / Success",
4111
+ viewBox: "0 0 24 24",
4112
+ svgPath: '<polyline points="20 6 9 17 4 12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>'
4113
+ },
4114
+ lock: {
4115
+ name: "Lock / Privacy",
4116
+ viewBox: "0 0 24 24",
4117
+ svgPath: '<rect x="3" y="11" width="18" height="11" rx="2" ry="2" fill="none" stroke="currentColor" stroke-width="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4" fill="none" stroke="currentColor" stroke-width="2"/>'
4118
+ },
4119
+ clock: {
4120
+ name: "Clock / 24-7",
4121
+ viewBox: "0 0 24 24",
4122
+ svgPath: '<circle cx="12" cy="12" r="10" fill="none" stroke="currentColor" stroke-width="2"/><polyline points="12 6 12 12 16 14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>'
4123
+ },
4124
+ phone: {
4125
+ name: "Phone / Contact",
4126
+ viewBox: "0 0 24 24",
4127
+ svgPath: '<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z" fill="none" stroke="currentColor" stroke-width="2"/>'
4128
+ },
4129
+ mapPin: {
4130
+ name: "Map Pin / Local",
4131
+ viewBox: "0 0 24 24",
4132
+ svgPath: '<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z" fill="none" stroke="currentColor" stroke-width="2"/><circle cx="12" cy="10" r="3" fill="none" stroke="currentColor" stroke-width="2"/>'
4133
+ },
4134
+ euro: {
4135
+ name: "Euro / Pricing",
4136
+ viewBox: "0 0 24 24",
4137
+ svgPath: '<path d="M4 10h12M4 14h9M19 6a7.7 7.7 0 0 0-5.2-2A7.9 7.9 0 0 0 6 12a7.9 7.9 0 0 0 7.8 8 7.7 7.7 0 0 0 5.2-2" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/>'
4138
+ },
4139
+ arrowRight: {
4140
+ name: "Arrow Right",
4141
+ viewBox: "0 0 24 24",
4142
+ svgPath: '<line x1="5" y1="12" x2="19" y2="12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><polyline points="12 5 19 12 12 19" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>'
4143
+ }
4144
+ };
4145
+ function renderUiIconSvg(iconName, className = "w-5 h-5 inline-block") {
4146
+ const icon = UI_ICONS[iconName.toLowerCase()] || UI_ICONS.check;
4147
+ return `<svg class="${className}" viewBox="${icon.viewBox}" aria-hidden="true">${icon.svgPath}</svg>`;
4148
+ }
4149
+ function resolveFeatureIcon(featureText) {
4150
+ const lower = featureText.toLowerCase();
4151
+ if (lower.includes("secur") || lower.includes("rgpd") || lower.includes("gdpr") || lower.includes("protect") || lower.includes("bank")) {
4152
+ return "shield";
4153
+ }
4154
+ if (lower.includes("sync") || lower.includes("speed") || lower.includes("instant") || lower.includes("real-time") || lower.includes("fast") || lower.includes("rapide")) {
4155
+ return "zap";
4156
+ }
4157
+ if (lower.includes("ai") || lower.includes("ia") || lower.includes("auto") || lower.includes("smart") || lower.includes("intel")) {
4158
+ return "sparkles";
4159
+ }
4160
+ if (lower.includes("chart") || lower.includes("analyt") || lower.includes("report") || lower.includes("stat") || lower.includes("roi") || lower.includes("kpi")) {
4161
+ return "chart";
4162
+ }
4163
+ if (lower.includes("schedul") || lower.includes("calen") || lower.includes("plan") || lower.includes("agenda")) {
4164
+ return "calendar";
4165
+ }
4166
+ if (lower.includes("user") || lower.includes("team") || lower.includes("collab") || lower.includes("client") || lower.includes("contact")) {
4167
+ return "users";
4168
+ }
4169
+ if (lower.includes("price") || lower.includes("tarif") || lower.includes("cost") || lower.includes("devis") || lower.includes("factur")) {
4170
+ return "euro";
4171
+ }
4172
+ if (lower.includes("local") || lower.includes("city") || lower.includes("ville") || lower.includes("map") || lower.includes("gps")) {
4173
+ return "mapPin";
4174
+ }
4175
+ if (lower.includes("24/7") || lower.includes("support") || lower.includes("hour") || lower.includes("time") || lower.includes("temps")) {
4176
+ return "clock";
4177
+ }
4178
+ return "zap";
4179
+ }
3981
4180
  // src/urlytics-engine.ts
3982
4181
  class UrlyticsEngine {
3983
4182
  static parseUrl(rawUrl) {
@@ -4327,13 +4526,14 @@ import { matrixEngine, SEO_CONFIG, PSEO_DATASET } from "@/lib/seo";
4327
4526
 
4328
4527
  export default function sitemap(): MetadataRoute.Sitemap {
4329
4528
  const domain = process.env.NEXT_PUBLIC_SITE_URL || "https://example.com";
4330
- const pages = matrixEngine.generateAllMatrices(domain, PSEO_DATASET, SEO_CONFIG);
4331
- return pages.filter((p) => p.robots.includes("index")).map((p) => ({
4332
- url: p.canonicalUrl,
4333
- lastModified: new Date(),
4334
- changeFrequency: "weekly",
4335
- priority: 0.8,
4336
- }));
4529
+ return matrixEngine.generateAllMatrices(domain, PSEO_DATASET, SEO_CONFIG)
4530
+ .filter((p) => p.robots.includes("index"))
4531
+ .map((p) => ({
4532
+ url: p.canonicalUrl,
4533
+ lastModified: new Date(),
4534
+ changeFrequency: "weekly",
4535
+ priority: 0.8,
4536
+ }));
4337
4537
  }
4338
4538
  \`\`\`
4339
4539
 
@@ -4344,49 +4544,75 @@ import { matrixEngine, SEO_CONFIG, PSEO_DATASET } from "@/lib/seo";
4344
4544
 
4345
4545
  export async function GET() {
4346
4546
  const domain = process.env.NEXT_PUBLIC_SITE_URL || "https://example.com";
4347
- const pages = matrixEngine.generateAllMatrices(domain, PSEO_DATASET, SEO_CONFIG);
4348
- const markdown = [
4349
- \`# \${SEO_CONFIG.brandName} Solutions Index\`,
4350
- \`> Structured knowledge feed for LLMs and AI search engines (ChatGPT, Perplexity).\`,
4351
- \`\`,
4352
- \`## Solutions & Matrices\`,
4353
- ...pages.map((p) => \`- [\${p.h1}](\${p.canonicalUrl}): \${p.description}\`),
4354
- ].join("\\n");
4547
+ // 1-Line high-density Markdown feed for ChatGPT Search & Perplexity
4548
+ const markdown = matrixEngine.generateLlmsTxt(domain, PSEO_DATASET, SEO_CONFIG);
4355
4549
  return new NextResponse(markdown, { headers: { "Content-Type": "text/plain; charset=utf-8" } });
4356
4550
  }
4357
4551
  \`\`\`
4358
4552
 
4553
+ #### File 5: Dynamic AI Search & Bot Rules (\`app/robots.ts\` or \`public/robots.txt\`)
4554
+ \`\`\`typescript
4555
+ import { MetadataRoute } from "next";
4556
+ import { matrixEngine } from "@/lib/seo";
4557
+
4558
+ export default function robots(): MetadataRoute.Robots {
4559
+ const domain = process.env.NEXT_PUBLIC_SITE_URL || "https://example.com";
4560
+ return {
4561
+ rules: [
4562
+ { userAgent: "*", allow: "/", disallow: ["/api/", "/admin/"] },
4563
+ { userAgent: ["GPTBot", "ClaudeBot", "PerplexityBot", "Applebot"], allow: "/" },
4564
+ ],
4565
+ sitemap: \`\${domain}/sitemap.xml\`,
4566
+ };
4567
+ }
4568
+ \`\`\`
4569
+
4359
4570
  ---
4360
4571
 
4361
- ### \uD83C\uDFDB️ 5. MATRIX ARCHITECTURE: 10 ROOT PILLARS & 50+ SPECIALIZED SUB-MATRICES
4572
+ ### \uD83E\uDDF0 6. THE COMPLETE LYNXSEO STUDIO ENGINE & TOOL SUITE
4362
4573
 
4363
- 1. **10 Canonical Root Pillars:**
4364
- - Comparisons: \`/vs/{competitor}\`
4365
- - Alternatives: \`/alternatives/{competitor}\` (Zero keyword stuttering)
4366
- - Pricing: \`/pricing/{competitor}\`
4367
- - Audiences: \`/for/{target}\` (Unified industry/role mapping, anti-cannibalization)
4368
- - Integrations: \`/integrations/{app}\` (Clean slug without stop words)
4369
- - Use Cases: \`/use-cases/{useCase}\` (Actionable workflows with HowTo JSON-LD)
4370
- - Templates: \`/templates/{slug}\` (High-converting spreadsheet/notion lead magnets)
4371
- - Glossary: \`/glossary/{term}\` (Topic authority cluster hub)
4372
- - Tools: \`/tools/{calculator}\` (Interactive ROI & value estimators)
4373
- - Local Geo: \`/solutions/{service}/{country}/{city}\` (Tiered Indexing & Mesh Links)
4574
+ The SDK equips applications with 9 enterprise-grade SEO engines:
4374
4575
 
4375
- 2. **50+ Specialized Sub-Matrix Dimensions:**
4376
- - **Industry & Regulatory (12):** Sector × Compliance (e.g., GDPR Law Firm), Sector × Team Size.
4377
- - **Role & Workflow (10):** Role × Core KPI (e.g., Sales Director Revenue), Role × Daily Toolchain.
4378
- - **Multi-Format Templates (8):** Subject × Format (Excel .xlsx, Notion, Google Sheets, Word, PDF).
4379
- - **Ecosystem & Integrations (10):** Module × App (e.g., CRM × Shopify), Connector × Webhook Trigger.
4380
- - **Problem Playbooks (8):** Pain Point × Step-by-Step Playbook, Bottleneck × ROI.
4381
- - **Interactive Calculators (6):** Time-Saved Estimator, Revenue Uplift Simulator.
4382
- - **Topic Authority Clusters (6):** Financial Metrics (MRR, LTV), Technical Protocols (OAuth, Webhook).
4576
+ 1. **⚡ In-Memory Programmatic Matrix Engine (\`matrixEngine\`):**
4577
+ - \`resolvePage(slug, domain, data, config)\`: Resolves full programmatic pages in < 0.05ms in local RAM.
4578
+ - \`resolveServicePage(serviceSlug, citySlug, ...)\`: Dedicated routing for \`app/[service]/[city]/page.tsx\`.
4579
+ - \`generateSitemapXml()\`, \`generateLlmsTxt()\`, \`generateRobotsTxt()\`.
4383
4580
 
4384
- ---
4581
+ 2. **\uD83C\uDF0D Built-in Global Demographics (\`built-in-locations.ts\`):**
4582
+ - Automatically provisions verified cities, populations, GPS coordinates, and currencies across France, Spain, Germany, UK, US, Belgium, Switzerland, Italy, Canada, Europe, and International markets. Zero manual city typing.
4583
+
4584
+ 3. **\uD83C\uDF10 Dynamic i18n Detector (\`I18nDetector\`):**
4585
+ - Seamless auto-detection and normalization across \`next-intl\`, \`i18next\`, \`paraglide\`, and \`astro:i18n\`. Adapts Google schemas and local currencies automatically.
4586
+
4587
+ 4. **\uD83C\uDFA8 Vector Brand & Social Icons (\`renderBrandIconSvg\`):**
4588
+ - Zero-dependency official SVG vectors for 30+ brands (Facebook, Instagram, LinkedIn, Shopify, Slack, WhatsApp, Google, GitHub, TikTok, YouTube).
4589
+
4590
+ 5. **✨ Standard UI & Feature Icons (\`renderUiIconSvg\`, \`resolveFeatureIcon\`):**
4591
+ - Zero-dependency Lucide-style vector icons (shield, zap, chart, calendar, users, rocket, sparkles, check, lock, clock, phone, mapPin, euro).
4592
+ - Semantic keyword auto-resolver: Automatically maps feature copy to the most relevant icon.
4593
+
4594
+ 6. **\uD83D\uDDBC️ Dynamic OpenGraph (OG) Image Generator (\`OgImageGenerator\`):**
4595
+ - \`renderDynamicOgSvg(opts)\`: Generates high-converting 1200x630 SVG social cards with glassmorphism badges, star ratings, and gradient backdrops.
4596
+ - \`generateOgImageUrl(domain, pageMeta, brandName)\`: Edge-ready query URL for \`app/api/og/route.ts\`.
4597
+
4598
+ 7. **\uD83C\uDFDB️ Google Schema.org Rich Graphs (\`ExtendedSchemaGraphBuilder\`):**
4599
+ - \`buildAggregateRating\` (Google Gold Stars 4.9★), \`buildAggregateOffer\` (price ranges), \`buildLocalBusiness\` (GPS & opening hours), \`buildSoftwareApplication\`, \`buildHowTo\`, \`buildFAQPage\`, \`buildBreadcrumbs\`.
4600
+
4601
+ 8. **\uD83D\uDD0D URL Decomposition & Analysis (\`UrlyticsEngine\`):**
4602
+ - Deep structural directory decomposition, depth tracking, query parameter analysis, and slug tokenization (inspired by advertools).
4603
+
4604
+ 9. **⚡ SEM Keyword Combinator (\`KeywordPermutatorEngine\`):**
4605
+ - Combinatorial matrix generation: Products × Modifiers × Locations with match types (\`[exact]\`, \`"phrase"\`, \`+broad\`) and intent classification.
4606
+
4607
+ 10. **⚖️ Legal & Editorial Compliance (\`LegalDisclaimerEngine\`):**
4608
+ - 7 SeedRank-grade disclaimer templates, 90-day staleness verification, and multi-language anti-disparagement guardian.
4385
4609
 
4386
- ### \uD83E\uDDF9 6. URL SLUG INTEGRITY & SCHEMA.ORG
4610
+ 11. **\uD83D\uDCCA Telemetry & Cloud Metering (\`matrixEngine.getTelemetryPayload\` & \`LynxAnalyticsClient\`):**
4611
+ - Synchronizes total programmatic pages, indexed hubs, and AI bot crawl hits (GPTBot, ClaudeBot, PerplexityBot) with the LynxSEO Studio dashboard.
4387
4612
 
4388
- - Use \`cleanSeoSlug(text, { language })\` to strip accents, dates, and stop words.
4389
- - Use \`ExtendedSchemaGraphBuilder\` to output valid JSON-LD graphs (\`SoftwareApplication\`, \`LocalBusiness\`, \`HowTo\`, \`FAQPage\`, \`BreadcrumbList\`, \`Organization\`).
4613
+ 12. **\uD83E\uDDF9 URL Slug Engine & Schema.org Graphs:**
4614
+ - \`cleanSeoSlug(text, { language })\`: Strips accents, stop words across 10+ languages, and non-alphanumeric noise.
4615
+ - Outputs Google-validated Schema.org JSON-LD graphs with 0 syntax errors.
4390
4616
  `.trim();
4391
4617
  function getSeoAgentPrompt(customContext) {
4392
4618
  if (!customContext)
@@ -6533,8 +6759,10 @@ var LynxSeo = {
6533
6759
  var src_default = LynxSeo;
6534
6760
  export {
6535
6761
  validateSeoSlug,
6762
+ resolveFeatureIcon,
6536
6763
  resolveBuiltInLocations,
6537
6764
  resolveBrandIcon,
6765
+ renderUiIconSvg,
6538
6766
  renderBrandIconSvg,
6539
6767
  getSeoAgentPrompt,
6540
6768
  src_default as default,
@@ -6542,6 +6770,7 @@ export {
6542
6770
  cleanSeoSlug,
6543
6771
  YoastParityEngine,
6544
6772
  UrlyticsEngine,
6773
+ UI_ICONS,
6545
6774
  TokenQuotaManager,
6546
6775
  TechnicalRulesAuditor,
6547
6776
  TeamRbacEngine,
@@ -6561,6 +6790,7 @@ export {
6561
6790
  RankMathParityEngine,
6562
6791
  PseoMatrixEngine,
6563
6792
  PSEO_AGENT_SYSTEM_PROMPT,
6793
+ OgImageGenerator,
6564
6794
  NGramDensityAnalyzer,
6565
6795
  McpSeoServerHub,
6566
6796
  MasterMarketingEngine,
@@ -110,6 +110,7 @@ export interface GeneratedPageMeta {
110
110
  robots: "index, follow" | "noindex, follow";
111
111
  schemaGraph: SchemaOrgGraph;
112
112
  disclaimerText?: string;
113
+ ogImageUrl?: string;
113
114
  neighboringLinks?: {
114
115
  name: string;
115
116
  url: string;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * 🖼️ Dynamic OpenGraph (OG) & Social Card Image Generator
3
+ * Generates high-converting 1200x630 SVG social preview cards and URL queries
4
+ * with zero heavy headless browser dependencies (Puppeteer/Playwright free).
5
+ */
6
+ import { GeneratedPageMeta } from "./matrix-engine";
7
+ export interface OgImageOptions {
8
+ brandName: string;
9
+ title: string;
10
+ badgeText?: string;
11
+ subtitle?: string;
12
+ locationName?: string;
13
+ ratingValue?: number;
14
+ reviewCount?: number;
15
+ brandColor?: string;
16
+ }
17
+ export declare class OgImageGenerator {
18
+ /**
19
+ * Generates a fully formatted URL for dynamic Edge / API OG image generation.
20
+ * e.g. /api/og?title=...&badge=...&city=...
21
+ */
22
+ static generateOgImageUrl(domain: string, pageMeta: GeneratedPageMeta, brandName: string): string;
23
+ /**
24
+ * Generates an ultra-crisp 1200x630 pure SVG image string for social previews.
25
+ */
26
+ static renderDynamicOgSvg(opts: OgImageOptions): string;
27
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * 🎨 Universal Zero-Dependency UI & Feature SVG Icons
3
+ * Provides crisp, modern Lucide-style vector icons for features, trust badges, and UI components.
4
+ * Includes automatic semantic keyword-to-icon detection for feature descriptions.
5
+ */
6
+ export interface UiIcon {
7
+ name: string;
8
+ viewBox: string;
9
+ svgPath: string;
10
+ }
11
+ export declare const UI_ICONS: Record<string, UiIcon>;
12
+ /**
13
+ * Returns raw inline SVG markup for a standard UI icon.
14
+ */
15
+ export declare function renderUiIconSvg(iconName: string, className?: string): string;
16
+ /**
17
+ * Semantically resolves the most relevant UI icon based on feature text keywords.
18
+ */
19
+ export declare function resolveFeatureIcon(featureText: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynxflow/seo-engine",
3
- "version": "1.6.0",
3
+ "version": "1.6.2",
4
4
  "description": "High-Performance Multilingual Programmatic SEO & AI Search Engine SDK",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -8,6 +8,8 @@ import { UrlyticsEngine } from "./urlytics-engine";
8
8
  import { KeywordPermutatorEngine } from "./keyword-permutator";
9
9
  import { renderBrandIconSvg } from "./brand-icons";
10
10
  import { I18nDetector } from "./i18n-detector";
11
+ import { renderUiIconSvg, resolveFeatureIcon } from "./ui-icons";
12
+ import { OgImageGenerator } from "./og-image-generator";
11
13
 
12
14
  describe("Multilingual SEO Slug Engine (10+ Languages)", () => {
13
15
  it("English: Strips stop words and years", () => {
@@ -265,4 +267,43 @@ describe("Audited Reference Engines (Advertools, Santifer, Seonaut)", () => {
265
267
  expect(telemetry.brandName).toBe("Acme");
266
268
  expect(telemetry.servicesCount).toBe(1);
267
269
  });
270
+
271
+ it("UI Icons: Renders standard Lucide-style SVG and resolves semantic feature icons", () => {
272
+ const shieldSvg = renderUiIconSvg("shield");
273
+ expect(shieldSvg).toContain("<svg");
274
+ expect(shieldSvg).toContain("viewBox");
275
+
276
+ expect(resolveFeatureIcon("Bank-grade RGPD Security")).toBe("shield");
277
+ expect(resolveFeatureIcon("Real-time automated sync")).toBe("zap");
278
+ expect(resolveFeatureIcon("Analytics dashboard & KPI tracker")).toBe("chart");
279
+ expect(resolveFeatureIcon("Smart AI content generator")).toBe("sparkles");
280
+ });
281
+
282
+ it("OgImageGenerator: Generates dynamic 1200x630 SVG and Edge URL query", () => {
283
+ const ogSvg = OgImageGenerator.renderDynamicOgSvg({
284
+ brandName: "Acme Cloud",
285
+ title: "Autopost Facebook & Instagram in Paris",
286
+ badgeText: "SOCIAL MEDIA",
287
+ locationName: "Paris, France",
288
+ ratingValue: 4.9,
289
+ reviewCount: 1280,
290
+ });
291
+ expect(ogSvg).toContain("<svg width=\"1200\" height=\"630\"");
292
+ expect(ogSvg).toContain("Autopost Facebook");
293
+ expect(ogSvg).toContain("4.9 / 5");
294
+ expect(ogSvg).toContain("Paris, France");
295
+
296
+ const engine = new PseoMatrixEngine();
297
+ const page = engine.resolvePage(
298
+ ["autopost-facebook", "paris"],
299
+ "https://acme.com",
300
+ {
301
+ services: [{ slug: "autopost-facebook", name: "Autopost Facebook", category: "Social" }],
302
+ },
303
+ { brandName: "Acme", countries: ["france"] },
304
+ );
305
+ expect(page?.ogImageUrl).toBeDefined();
306
+ expect(page?.ogImageUrl).toContain("/api/og?");
307
+ expect(page?.ogImageUrl).toContain("brand=Acme");
308
+ });
268
309
  });
package/src/index.ts CHANGED
@@ -17,6 +17,8 @@ export * from "./matrix-engine";
17
17
  export * from "./built-in-locations";
18
18
  export * from "./i18n-detector";
19
19
  export * from "./brand-icons";
20
+ export * from "./ui-icons";
21
+ export * from "./og-image-generator";
20
22
  export * from "./urlytics-engine";
21
23
  export * from "./keyword-permutator";
22
24
  export * from "./llm-prompt";
package/src/llm-prompt.ts CHANGED
@@ -214,13 +214,14 @@ import { matrixEngine, SEO_CONFIG, PSEO_DATASET } from "@/lib/seo";
214
214
 
215
215
  export default function sitemap(): MetadataRoute.Sitemap {
216
216
  const domain = process.env.NEXT_PUBLIC_SITE_URL || "https://example.com";
217
- const pages = matrixEngine.generateAllMatrices(domain, PSEO_DATASET, SEO_CONFIG);
218
- return pages.filter((p) => p.robots.includes("index")).map((p) => ({
219
- url: p.canonicalUrl,
220
- lastModified: new Date(),
221
- changeFrequency: "weekly",
222
- priority: 0.8,
223
- }));
217
+ return matrixEngine.generateAllMatrices(domain, PSEO_DATASET, SEO_CONFIG)
218
+ .filter((p) => p.robots.includes("index"))
219
+ .map((p) => ({
220
+ url: p.canonicalUrl,
221
+ lastModified: new Date(),
222
+ changeFrequency: "weekly",
223
+ priority: 0.8,
224
+ }));
224
225
  }
225
226
  \`\`\`
226
227
 
@@ -231,49 +232,75 @@ import { matrixEngine, SEO_CONFIG, PSEO_DATASET } from "@/lib/seo";
231
232
 
232
233
  export async function GET() {
233
234
  const domain = process.env.NEXT_PUBLIC_SITE_URL || "https://example.com";
234
- const pages = matrixEngine.generateAllMatrices(domain, PSEO_DATASET, SEO_CONFIG);
235
- const markdown = [
236
- \`# \${SEO_CONFIG.brandName} Solutions Index\`,
237
- \`> Structured knowledge feed for LLMs and AI search engines (ChatGPT, Perplexity).\`,
238
- \`\`,
239
- \`## Solutions & Matrices\`,
240
- ...pages.map((p) => \`- [\${p.h1}](\${p.canonicalUrl}): \${p.description}\`),
241
- ].join("\\n");
235
+ // 1-Line high-density Markdown feed for ChatGPT Search & Perplexity
236
+ const markdown = matrixEngine.generateLlmsTxt(domain, PSEO_DATASET, SEO_CONFIG);
242
237
  return new NextResponse(markdown, { headers: { "Content-Type": "text/plain; charset=utf-8" } });
243
238
  }
244
239
  \`\`\`
245
240
 
246
- ---
241
+ #### File 5: Dynamic AI Search & Bot Rules (\`app/robots.ts\` or \`public/robots.txt\`)
242
+ \`\`\`typescript
243
+ import { MetadataRoute } from "next";
244
+ import { matrixEngine } from "@/lib/seo";
247
245
 
248
- ### 🏛️ 5. MATRIX ARCHITECTURE: 10 ROOT PILLARS & 50+ SPECIALIZED SUB-MATRICES
249
-
250
- 1. **10 Canonical Root Pillars:**
251
- - Comparisons: \`/vs/{competitor}\`
252
- - Alternatives: \`/alternatives/{competitor}\` (Zero keyword stuttering)
253
- - Pricing: \`/pricing/{competitor}\`
254
- - Audiences: \`/for/{target}\` (Unified industry/role mapping, anti-cannibalization)
255
- - Integrations: \`/integrations/{app}\` (Clean slug without stop words)
256
- - Use Cases: \`/use-cases/{useCase}\` (Actionable workflows with HowTo JSON-LD)
257
- - Templates: \`/templates/{slug}\` (High-converting spreadsheet/notion lead magnets)
258
- - Glossary: \`/glossary/{term}\` (Topic authority cluster hub)
259
- - Tools: \`/tools/{calculator}\` (Interactive ROI & value estimators)
260
- - Local Geo: \`/solutions/{service}/{country}/{city}\` (Tiered Indexing & Mesh Links)
261
-
262
- 2. **50+ Specialized Sub-Matrix Dimensions:**
263
- - **Industry & Regulatory (12):** Sector × Compliance (e.g., GDPR Law Firm), Sector × Team Size.
264
- - **Role & Workflow (10):** Role × Core KPI (e.g., Sales Director Revenue), Role × Daily Toolchain.
265
- - **Multi-Format Templates (8):** Subject × Format (Excel .xlsx, Notion, Google Sheets, Word, PDF).
266
- - **Ecosystem & Integrations (10):** Module × App (e.g., CRM × Shopify), Connector × Webhook Trigger.
267
- - **Problem Playbooks (8):** Pain Point × Step-by-Step Playbook, Bottleneck × ROI.
268
- - **Interactive Calculators (6):** Time-Saved Estimator, Revenue Uplift Simulator.
269
- - **Topic Authority Clusters (6):** Financial Metrics (MRR, LTV), Technical Protocols (OAuth, Webhook).
246
+ export default function robots(): MetadataRoute.Robots {
247
+ const domain = process.env.NEXT_PUBLIC_SITE_URL || "https://example.com";
248
+ return {
249
+ rules: [
250
+ { userAgent: "*", allow: "/", disallow: ["/api/", "/admin/"] },
251
+ { userAgent: ["GPTBot", "ClaudeBot", "PerplexityBot", "Applebot"], allow: "/" },
252
+ ],
253
+ sitemap: \`\${domain}/sitemap.xml\`,
254
+ };
255
+ }
256
+ \`\`\`
270
257
 
271
258
  ---
272
259
 
273
- ### 🧹 6. URL SLUG INTEGRITY & SCHEMA.ORG
260
+ ### 🧰 6. THE COMPLETE LYNXSEO STUDIO ENGINE & TOOL SUITE
261
+
262
+ The SDK equips applications with 9 enterprise-grade SEO engines:
263
+
264
+ 1. **⚡ In-Memory Programmatic Matrix Engine (\`matrixEngine\`):**
265
+ - \`resolvePage(slug, domain, data, config)\`: Resolves full programmatic pages in < 0.05ms in local RAM.
266
+ - \`resolveServicePage(serviceSlug, citySlug, ...)\`: Dedicated routing for \`app/[service]/[city]/page.tsx\`.
267
+ - \`generateSitemapXml()\`, \`generateLlmsTxt()\`, \`generateRobotsTxt()\`.
268
+
269
+ 2. **🌍 Built-in Global Demographics (\`built-in-locations.ts\`):**
270
+ - Automatically provisions verified cities, populations, GPS coordinates, and currencies across France, Spain, Germany, UK, US, Belgium, Switzerland, Italy, Canada, Europe, and International markets. Zero manual city typing.
271
+
272
+ 3. **🌐 Dynamic i18n Detector (\`I18nDetector\`):**
273
+ - Seamless auto-detection and normalization across \`next-intl\`, \`i18next\`, \`paraglide\`, and \`astro:i18n\`. Adapts Google schemas and local currencies automatically.
274
+
275
+ 4. **🎨 Vector Brand & Social Icons (\`renderBrandIconSvg\`):**
276
+ - Zero-dependency official SVG vectors for 30+ brands (Facebook, Instagram, LinkedIn, Shopify, Slack, WhatsApp, Google, GitHub, TikTok, YouTube).
277
+
278
+ 5. **✨ Standard UI & Feature Icons (\`renderUiIconSvg\`, \`resolveFeatureIcon\`):**
279
+ - Zero-dependency Lucide-style vector icons (shield, zap, chart, calendar, users, rocket, sparkles, check, lock, clock, phone, mapPin, euro).
280
+ - Semantic keyword auto-resolver: Automatically maps feature copy to the most relevant icon.
281
+
282
+ 6. **🖼️ Dynamic OpenGraph (OG) Image Generator (\`OgImageGenerator\`):**
283
+ - \`renderDynamicOgSvg(opts)\`: Generates high-converting 1200x630 SVG social cards with glassmorphism badges, star ratings, and gradient backdrops.
284
+ - \`generateOgImageUrl(domain, pageMeta, brandName)\`: Edge-ready query URL for \`app/api/og/route.ts\`.
285
+
286
+ 7. **🏛️ Google Schema.org Rich Graphs (\`ExtendedSchemaGraphBuilder\`):**
287
+ - \`buildAggregateRating\` (Google Gold Stars 4.9★), \`buildAggregateOffer\` (price ranges), \`buildLocalBusiness\` (GPS & opening hours), \`buildSoftwareApplication\`, \`buildHowTo\`, \`buildFAQPage\`, \`buildBreadcrumbs\`.
288
+
289
+ 8. **🔍 URL Decomposition & Analysis (\`UrlyticsEngine\`):**
290
+ - Deep structural directory decomposition, depth tracking, query parameter analysis, and slug tokenization (inspired by advertools).
291
+
292
+ 9. **⚡ SEM Keyword Combinator (\`KeywordPermutatorEngine\`):**
293
+ - Combinatorial matrix generation: Products × Modifiers × Locations with match types (\`[exact]\`, \`"phrase"\`, \`+broad\`) and intent classification.
294
+
295
+ 10. **⚖️ Legal & Editorial Compliance (\`LegalDisclaimerEngine\`):**
296
+ - 7 SeedRank-grade disclaimer templates, 90-day staleness verification, and multi-language anti-disparagement guardian.
297
+
298
+ 11. **📊 Telemetry & Cloud Metering (\`matrixEngine.getTelemetryPayload\` & \`LynxAnalyticsClient\`):**
299
+ - Synchronizes total programmatic pages, indexed hubs, and AI bot crawl hits (GPTBot, ClaudeBot, PerplexityBot) with the LynxSEO Studio dashboard.
274
300
 
275
- - Use \`cleanSeoSlug(text, { language })\` to strip accents, dates, and stop words.
276
- - Use \`ExtendedSchemaGraphBuilder\` to output valid JSON-LD graphs (\`SoftwareApplication\`, \`LocalBusiness\`, \`HowTo\`, \`FAQPage\`, \`BreadcrumbList\`, \`Organization\`).
301
+ 12. **🧹 URL Slug Engine & Schema.org Graphs:**
302
+ - \`cleanSeoSlug(text, { language })\`: Strips accents, stop words across 10+ languages, and non-alphanumeric noise.
303
+ - Outputs Google-validated Schema.org JSON-LD graphs with 0 syntax errors.
277
304
  `.trim();
278
305
 
279
306
  /**