@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.d.ts +2 -0
- package/dist/index.js +269 -39
- package/dist/index.mjs +269 -39
- package/dist/matrix-engine.d.ts +1 -0
- package/dist/og-image-generator.d.ts +27 -0
- package/dist/ui-icons.d.ts +19 -0
- package/package.json +1 -1
- package/src/engine.test.ts +41 -0
- package/src/index.ts +2 -0
- package/src/llm-prompt.ts +68 -41
- package/src/matrix-engine.ts +8 -0
- package/src/og-image-generator.ts +109 -0
- package/src/ui-icons.ts +134 -0
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, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
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
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
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
|
-
|
|
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
|
-
### \
|
|
4572
|
+
### \uD83E\uDDF0 6. THE COMPLETE LYNXSEO STUDIO ENGINE & TOOL SUITE
|
|
4362
4573
|
|
|
4363
|
-
|
|
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
|
-
|
|
4376
|
-
-
|
|
4377
|
-
-
|
|
4378
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
4389
|
-
-
|
|
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,
|
package/dist/matrix-engine.d.ts
CHANGED
|
@@ -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
package/src/engine.test.ts
CHANGED
|
@@ -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
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
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
|
-
|
|
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
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
276
|
-
-
|
|
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
|
/**
|