@lynxflow/seo-engine 1.8.2 → 1.8.3

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
@@ -3084,10 +3084,13 @@ class ExtendedSchemaGraphBuilder {
3084
3084
  };
3085
3085
  }
3086
3086
  static buildAggregateRating(opts) {
3087
+ if (!opts.ratingValue || !opts.reviewCount || opts.reviewCount <= 0) {
3088
+ return null;
3089
+ }
3087
3090
  return {
3088
3091
  "@type": "AggregateRating",
3089
- ratingValue: opts.ratingValue ?? 4.9,
3090
- reviewCount: opts.reviewCount ?? 1280,
3092
+ ratingValue: opts.ratingValue,
3093
+ reviewCount: opts.reviewCount,
3091
3094
  bestRating: opts.bestRating ?? 5,
3092
3095
  worstRating: opts.worstRating ?? 1,
3093
3096
  itemReviewed: {
@@ -3305,8 +3308,8 @@ class OgImageGenerator {
3305
3308
  const badge = opts.badgeText || "OFFICIAL";
3306
3309
  const title = opts.title.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
3307
3310
  const loc = opts.locationName ? `\uD83D\uDCCD ${opts.locationName}` : "⚡ Instant Cloud Setup";
3308
- const rating = opts.ratingValue ?? 4.9;
3309
- const reviews = opts.reviewCount ?? 1280;
3311
+ const rating = opts.ratingValue;
3312
+ const reviews = opts.reviewCount;
3310
3313
  const accent = opts.brandColor || "#6366F1";
3311
3314
  return `<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
3312
3315
  <defs>
@@ -3349,12 +3352,12 @@ class OgImageGenerator {
3349
3352
  ${title.length > 38 ? `<tspan x="80" dy="68">${title.slice(38, 80)}</tspan>` : ""}
3350
3353
  </text>
3351
3354
 
3352
- <!-- Trust Stars & Social Proof -->
3353
- <g transform="translate(80, 470)">
3355
+ <!-- Trust Stars & Social Proof (Only if real verified reviews exist) -->
3356
+ ${rating && reviews ? `<g transform="translate(80, 470)">
3354
3357
  <text x="0" y="32" fill="#FBBF24" font-size="24">★★★★★</text>
3355
3358
  <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>
3356
3359
  <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>
3357
- </g>
3360
+ </g>` : ""}
3358
3361
 
3359
3362
  <!-- Footer Brand -->
3360
3363
  <g transform="translate(80, 540)">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynxflow/seo-engine",
3
- "version": "1.8.2",
3
+ "version": "1.8.3",
4
4
  "description": "High-Performance Multilingual Programmatic SEO & AI Search Engine SDK",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -278,7 +278,7 @@ export class ExtendedSchemaGraphBuilder {
278
278
  }
279
279
 
280
280
  /**
281
- * 7. AggregateRating (Google Gold Stars in SERPs) - Inspired by santifer-irepair
281
+ * 7. AggregateRating (Google Gold Stars in SERPs) - Strictly Dynamic (No Fake Defaults)
282
282
  */
283
283
  static buildAggregateRating(opts: {
284
284
  ratingValue?: number;
@@ -286,11 +286,15 @@ export class ExtendedSchemaGraphBuilder {
286
286
  bestRating?: number;
287
287
  worstRating?: number;
288
288
  itemReviewedName: string;
289
- }): Record<string, unknown> {
289
+ }): Record<string, unknown> | null {
290
+ // Google Strict Compliance: Never emit fake or default hardcoded reviews
291
+ if (!opts.ratingValue || !opts.reviewCount || opts.reviewCount <= 0) {
292
+ return null;
293
+ }
290
294
  return {
291
295
  "@type": "AggregateRating",
292
- ratingValue: opts.ratingValue ?? 4.9,
293
- reviewCount: opts.reviewCount ?? 1280,
296
+ ratingValue: opts.ratingValue,
297
+ reviewCount: opts.reviewCount,
294
298
  bestRating: opts.bestRating ?? 5,
295
299
  worstRating: opts.worstRating ?? 1,
296
300
  itemReviewed: {
@@ -46,8 +46,8 @@ export class OgImageGenerator {
46
46
  const badge = opts.badgeText || "OFFICIAL";
47
47
  const title = opts.title.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
48
48
  const loc = opts.locationName ? `📍 ${opts.locationName}` : "⚡ Instant Cloud Setup";
49
- const rating = opts.ratingValue ?? 4.9;
50
- const reviews = opts.reviewCount ?? 1280;
49
+ const rating = opts.ratingValue;
50
+ const reviews = opts.reviewCount;
51
51
  const accent = opts.brandColor || "#6366F1";
52
52
 
53
53
  return `<svg width="1200" height="630" viewBox="0 0 1200 630" xmlns="http://www.w3.org/2000/svg">
@@ -91,12 +91,12 @@ export class OgImageGenerator {
91
91
  ${title.length > 38 ? `<tspan x="80" dy="68">${title.slice(38, 80)}</tspan>` : ""}
92
92
  </text>
93
93
 
94
- <!-- Trust Stars & Social Proof -->
95
- <g transform="translate(80, 470)">
94
+ <!-- Trust Stars & Social Proof (Only if real verified reviews exist) -->
95
+ ${rating && reviews ? `<g transform="translate(80, 470)">
96
96
  <text x="0" y="32" fill="#FBBF24" font-size="24">★★★★★</text>
97
97
  <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>
98
98
  <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>
99
- </g>
99
+ </g>` : ""}
100
100
 
101
101
  <!-- Footer Brand -->
102
102
  <g transform="translate(80, 540)">