@lynxflow/seo-engine 1.8.29 → 2.0.0
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/README.md +47 -93
- package/dist/ai-copilot-client.d.ts +2 -0
- package/dist/built-in-locations.d.ts +18 -0
- package/dist/content-ai-arsenal.d.ts +28 -0
- package/dist/existing-media-harvester.d.ts +33 -0
- package/dist/extended-schemas.d.ts +84 -0
- package/dist/features-knowledge-harvester.d.ts +56 -0
- package/dist/geo-citation-scorer.d.ts +34 -0
- package/dist/i18n-detector.d.ts +1 -1
- package/dist/index.d.ts +32 -7
- package/dist/index.js +538 -82
- package/dist/index.mjs +2028 -163
- package/dist/internal-pagerank-graph.d.ts +59 -0
- package/dist/knowledge-bank-builder.d.ts +91 -0
- package/dist/marketing-skills-engine.d.ts +74 -0
- package/dist/matrix-engine.d.ts +26 -0
- package/dist/power-words-psychology.d.ts +27 -15
- package/dist/public-manifest-engine.d.ts +58 -0
- package/dist/rag-knowledge-engine.d.ts +50 -0
- package/dist/rate-limited-translator.d.ts +19 -0
- package/dist/token-quota-manager.d.ts +4 -0
- package/package.json +11 -3
- package/TUTORIEL_INTEGRATION_SITE.md +0 -283
- package/connectors/cloudflare-worker/worker.js +0 -106
- package/connectors/laravel/LynxSeoController.php +0 -37
- package/connectors/wordpress/lynxseo-admin-app.js +0 -2618
- package/connectors/wordpress/lynxseo-connector.php +0 -1712
- package/connectors/wordpress/lynxseo-connector.zip +0 -0
- package/lynxflow-seo-engine-1.2.0.tgz +0 -0
- package/src/ad-intelligence-cro.ts +0 -140
- package/src/ai-bots-log-analyzer.ts +0 -127
- package/src/ai-copilot-client.ts +0 -99
- package/src/analytics-client.ts +0 -315
- package/src/auth-key.ts +0 -262
- package/src/backlinks-client.ts +0 -85
- package/src/brand-dna-calendar.ts +0 -120
- package/src/brand-icons.ts +0 -138
- package/src/built-in-locations.ts +0 -170
- package/src/content-ai-arsenal.ts +0 -268
- package/src/copy-frameworks-master.ts +0 -89
- package/src/cro-copywriting-engine.ts +0 -105
- package/src/crosslink-scorer.ts +0 -101
- package/src/embeddable-seo-widget.ts +0 -57
- package/src/engine.test.ts +0 -386
- package/src/engine.ts +0 -813
- package/src/existing-media-harvester.ts +0 -98
- package/src/extended-schemas.ts +0 -589
- package/src/features-knowledge-harvester.ts +0 -190
- package/src/free-public-tools.ts +0 -224
- package/src/geo-mesh-linking.ts +0 -93
- package/src/google-business-profile.ts +0 -280
- package/src/i18n-detector.ts +0 -98
- package/src/i18n-dictionary.ts +0 -422
- package/src/index.ts +0 -164
- package/src/indexnow-client.ts +0 -94
- package/src/instant-matrix-search.ts +0 -48
- package/src/isr-cache-manager.ts +0 -78
- package/src/keyword-permutator.ts +0 -118
- package/src/knowledge-bank-builder.ts +0 -299
- package/src/knowledge-graph-linker.ts +0 -81
- package/src/lago-token-meter.ts +0 -120
- package/src/legal-disclaimers.ts +0 -407
- package/src/llm-content-cleaner.ts +0 -64
- package/src/llm-prompt.ts +0 -323
- package/src/master-marketing-engine.ts +0 -314
- package/src/matrix-engine.ts +0 -1204
- package/src/mcp-seo-server.ts +0 -108
- package/src/ngram-density-analyzer.ts +0 -108
- package/src/og-image-generator.ts +0 -109
- package/src/power-words-psychology.ts +0 -369
- package/src/public-manifest-engine.ts +0 -109
- package/src/rag-knowledge-engine.ts +0 -163
- package/src/rank-math-parity.ts +0 -235
- package/src/rate-limited-translator.ts +0 -110
- package/src/real-reviews-sync.ts +0 -207
- package/src/rss-syndication-feed.ts +0 -56
- package/src/schema-builder.ts +0 -134
- package/src/seo-opportunities-decay.ts +0 -154
- package/src/serp-client.ts +0 -89
- package/src/serp-history-alerts.ts +0 -75
- package/src/site-auditor.ts +0 -83
- package/src/site-crawler.ts +0 -406
- package/src/slug-engine.ts +0 -183
- package/src/social-ads-seo.ts +0 -211
- package/src/social-growth-suite.ts +0 -310
- package/src/social-trend-seo.ts +0 -103
- package/src/social-video-seo.ts +0 -100
- package/src/team-rbac.ts +0 -61
- package/src/technical-rules-auditor.ts +0 -171
- package/src/token-quota-manager.ts +0 -91
- package/src/types.ts +0 -143
- package/src/ui-icons.ts +0 -134
- package/src/urlytics-engine.ts +0 -97
- package/src/video-youtube-analyzer.ts +0 -81
- package/src/yoast-parity.ts +0 -161
- package/tsconfig.json +0 -15
|
@@ -1,283 +0,0 @@
|
|
|
1
|
-
# 📘 Master Integration Tutorial — Programmatic SEO SDK
|
|
2
|
-
|
|
3
|
-
> **Designed for software engineers and autonomous AI coding agents (Claude, Cursor, Copilot, ChatGPT, Antigravity).**
|
|
4
|
-
> Explains how to integrate `@lynxflow/seo-engine` into **ANY WEB APPLICATION** to generate programmatic landing pages, sitemaps, `robots.txt`, and `/llms.txt`.
|
|
5
|
-
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## 🎯 4 Files to Deploy 100% of Your Programmatic SEO
|
|
9
|
-
|
|
10
|
-
```text
|
|
11
|
-
your-project/
|
|
12
|
-
├── lib/
|
|
13
|
-
│ └── seo.ts ➔ 1. Declare your product modules, targets, and integrations
|
|
14
|
-
└── app/
|
|
15
|
-
├── [...slug]/
|
|
16
|
-
│ └── page.tsx ➔ 2. Unified route rendering all 10 matrix families (< 0.05ms)
|
|
17
|
-
├── sitemap.ts ➔ 3. Partitioned XML Sitemap generator (45k chunks)
|
|
18
|
-
├── robots.ts ➔ 4. robots.txt with optimal AI bot allowances (GPTBot, ClaudeBot)
|
|
19
|
-
└── llms.txt/
|
|
20
|
-
└── route.ts ➔ 5. Clean Markdown feed for ChatGPT Search & Perplexity
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## 🛠️ Step 1: Declare Product Services & Matrices (`lib/seo.ts`)
|
|
26
|
-
|
|
27
|
-
Create `lib/seo.ts` to define your product configuration:
|
|
28
|
-
|
|
29
|
-
```typescript
|
|
30
|
-
// lib/seo.ts
|
|
31
|
-
import { PseoMatrixEngine } from "@lynxflow/seo-engine";
|
|
32
|
-
|
|
33
|
-
export const matrixEngine = new PseoMatrixEngine({
|
|
34
|
-
companyName: "Acme Cloud",
|
|
35
|
-
correctionsEmail: "compliance@acme.com",
|
|
36
|
-
language: "en", // "en" default, supports "fr", "de", "es", etc.
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
export const SEO_CONFIG = {
|
|
40
|
-
brandName: "Acme",
|
|
41
|
-
language: "en",
|
|
42
|
-
minPopulationToIndex: 15_000,
|
|
43
|
-
organizationSameAs: [
|
|
44
|
-
"https://twitter.com/acme",
|
|
45
|
-
"https://linkedin.com/company/acme",
|
|
46
|
-
"https://wikidata.org/wiki/Q12345",
|
|
47
|
-
],
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export const PSEO_DATASET = {
|
|
51
|
-
// 1. Product features / Services
|
|
52
|
-
services: [
|
|
53
|
-
{
|
|
54
|
-
slug: "crm-pipeline",
|
|
55
|
-
name: "Omnichannel CRM & Pipeline",
|
|
56
|
-
category: "Sales",
|
|
57
|
-
description: "Visual pipeline and automated lead scoring.",
|
|
58
|
-
keyFeatures: ["Visual Kanban", "Lead scoring", "Automated follow-ups"],
|
|
59
|
-
priceMonthly: 49,
|
|
60
|
-
},
|
|
61
|
-
],
|
|
62
|
-
|
|
63
|
-
// 2. Verified Competitor Data (VS, Alternatives, Pricing)
|
|
64
|
-
competitors: [
|
|
65
|
-
{
|
|
66
|
-
slug: "hubspot",
|
|
67
|
-
name: "HubSpot",
|
|
68
|
-
category: "CRM",
|
|
69
|
-
drawbacks: ["High onboarding fee", "Contact tier limits"],
|
|
70
|
-
advantagesOver: ["No seat lock-in", "Native automated workflows"],
|
|
71
|
-
startingPrice: 50,
|
|
72
|
-
lastVerifiedDate: "2026-08-01",
|
|
73
|
-
},
|
|
74
|
-
],
|
|
75
|
-
|
|
76
|
-
// 3. Unified Industry & Role Targets (Anti-cannibalization)
|
|
77
|
-
targets: [
|
|
78
|
-
{
|
|
79
|
-
slug: "law-firms",
|
|
80
|
-
name: "Law Firms & Attorneys",
|
|
81
|
-
type: "industry" as const,
|
|
82
|
-
painPoints: ["Client confidentiality", "Billing tracking"],
|
|
83
|
-
benefits: ["End-to-end encryption", "Automated retainer invoices"],
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
slug: "sales-directors",
|
|
87
|
-
name: "Sales Directors & VP of Sales",
|
|
88
|
-
type: "role" as const,
|
|
89
|
-
painPoints: ["Pipeline visibility", "Team quota tracking"],
|
|
90
|
-
benefits: ["Real-time revenue forecast", "Instant rep activity logs"],
|
|
91
|
-
},
|
|
92
|
-
],
|
|
93
|
-
|
|
94
|
-
// 4. Integrations & Connectors
|
|
95
|
-
integrations: [
|
|
96
|
-
{
|
|
97
|
-
slug: "shopify",
|
|
98
|
-
name: "Shopify",
|
|
99
|
-
category: "E-Commerce",
|
|
100
|
-
syncFeatures: ["Real-time order sync", "Customer lifetime value"],
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
slug: "slack",
|
|
104
|
-
name: "Slack",
|
|
105
|
-
category: "Communication",
|
|
106
|
-
syncFeatures: ["Instant deal alerts", "Pipeline command bot"],
|
|
107
|
-
},
|
|
108
|
-
],
|
|
109
|
-
|
|
110
|
-
// 5. Actionable Use Cases
|
|
111
|
-
useCases: [
|
|
112
|
-
{
|
|
113
|
-
slug: "automated-quote-followup",
|
|
114
|
-
title: "Automate Quote Follow-ups",
|
|
115
|
-
problem: "45% of sent quotes go cold without systematic follow-ups.",
|
|
116
|
-
solutionWorkflow: [
|
|
117
|
-
"Detect unanswered proposal after 48 hours",
|
|
118
|
-
"Send personalized multi-channel reminder",
|
|
119
|
-
"Notify account executive upon client view",
|
|
120
|
-
],
|
|
121
|
-
expectedRoi: "+28% close rate",
|
|
122
|
-
},
|
|
123
|
-
],
|
|
124
|
-
|
|
125
|
-
// 6. Lead Magnet Templates
|
|
126
|
-
templates: [
|
|
127
|
-
{
|
|
128
|
-
slug: "sales-pipeline-excel",
|
|
129
|
-
title: "Sales Pipeline Tracker",
|
|
130
|
-
topic: "Sales Management",
|
|
131
|
-
format: "excel" as const,
|
|
132
|
-
benefits: ["Pre-built formula calculations", "Weighted deal probability"],
|
|
133
|
-
},
|
|
134
|
-
],
|
|
135
|
-
|
|
136
|
-
// 7. Topic Authority Glossary
|
|
137
|
-
glossaryTerms: [
|
|
138
|
-
{
|
|
139
|
-
slug: "mrr",
|
|
140
|
-
term: "MRR (Monthly Recurring Revenue)",
|
|
141
|
-
shortDefinition: "Predictable monthly revenue generated by active subscriptions.",
|
|
142
|
-
},
|
|
143
|
-
],
|
|
144
|
-
};
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
---
|
|
148
|
-
|
|
149
|
-
## 🛠️ Step 2: Dynamic Catch-All Route (`app/[...slug]/page.tsx`)
|
|
150
|
-
|
|
151
|
-
```tsx
|
|
152
|
-
// app/[...slug]/page.tsx
|
|
153
|
-
import { notFound } from "next/navigation";
|
|
154
|
-
import { matrixEngine, SEO_CONFIG, PSEO_DATASET } from "@/lib/seo";
|
|
155
|
-
|
|
156
|
-
export async function generateMetadata({ params }: { params: { slug: string[] } }) {
|
|
157
|
-
const path = "/" + params.slug.join("/");
|
|
158
|
-
const domain = process.env.NEXT_PUBLIC_SITE_URL || "https://acme.com";
|
|
159
|
-
const pages = matrixEngine.generateAllMatrices(domain, PSEO_DATASET, SEO_CONFIG);
|
|
160
|
-
const page = pages.find((p) => p.urlPath === path);
|
|
161
|
-
|
|
162
|
-
if (!page) return {};
|
|
163
|
-
|
|
164
|
-
return {
|
|
165
|
-
title: page.title,
|
|
166
|
-
description: page.description,
|
|
167
|
-
alternates: { canonical: page.canonicalUrl },
|
|
168
|
-
robots: page.robots,
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export default async function ProgrammaticPage({ params }: { params: { slug: string[] } }) {
|
|
173
|
-
const path = "/" + params.slug.join("/");
|
|
174
|
-
const domain = process.env.NEXT_PUBLIC_SITE_URL || "https://acme.com";
|
|
175
|
-
const pages = matrixEngine.generateAllMatrices(domain, PSEO_DATASET, SEO_CONFIG);
|
|
176
|
-
const page = pages.find((p) => p.urlPath === path);
|
|
177
|
-
|
|
178
|
-
if (!page) notFound();
|
|
179
|
-
|
|
180
|
-
return (
|
|
181
|
-
<article className="max-w-4xl mx-auto py-12 px-6">
|
|
182
|
-
{/* Schema.org Rich Graph */}
|
|
183
|
-
<script
|
|
184
|
-
type="application/ld+json"
|
|
185
|
-
dangerouslySetInnerHTML={{ __html: JSON.stringify(page.schemaGraph) }}
|
|
186
|
-
/>
|
|
187
|
-
|
|
188
|
-
<h1 className="text-4xl font-extrabold tracking-tight text-gray-900">{page.h1}</h1>
|
|
189
|
-
<p className="mt-4 text-xl text-gray-600 leading-relaxed">{page.description}</p>
|
|
190
|
-
|
|
191
|
-
{/* Legal & Editorial Disclaimer */}
|
|
192
|
-
{page.disclaimerText && (
|
|
193
|
-
<aside className="mt-8 p-4 bg-gray-50 border border-gray-200 rounded-lg text-xs text-gray-500">
|
|
194
|
-
{page.disclaimerText}
|
|
195
|
-
</aside>
|
|
196
|
-
)}
|
|
197
|
-
</article>
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
---
|
|
203
|
-
|
|
204
|
-
## 🛠️ Step 3: Partitioned XML Sitemap (`app/sitemap.ts`)
|
|
205
|
-
|
|
206
|
-
```typescript
|
|
207
|
-
// app/sitemap.ts
|
|
208
|
-
import { MetadataRoute } from "next";
|
|
209
|
-
import { matrixEngine, SEO_CONFIG, PSEO_DATASET } from "@/lib/seo";
|
|
210
|
-
|
|
211
|
-
export default function sitemap(): MetadataRoute.Sitemap {
|
|
212
|
-
const domain = process.env.NEXT_PUBLIC_SITE_URL || "https://acme.com";
|
|
213
|
-
const pages = matrixEngine.generateAllMatrices(domain, PSEO_DATASET, SEO_CONFIG);
|
|
214
|
-
|
|
215
|
-
return pages
|
|
216
|
-
.filter((p) => p.robots.includes("index"))
|
|
217
|
-
.map((p) => ({
|
|
218
|
-
url: p.canonicalUrl,
|
|
219
|
-
lastModified: new Date(),
|
|
220
|
-
changeFrequency: "weekly",
|
|
221
|
-
priority: 0.8,
|
|
222
|
-
}));
|
|
223
|
-
}
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
---
|
|
227
|
-
|
|
228
|
-
## 🛠️ Step 4: AI Bots `robots.txt` (`app/robots.ts`)
|
|
229
|
-
|
|
230
|
-
```typescript
|
|
231
|
-
// app/robots.ts
|
|
232
|
-
import { MetadataRoute } from "next";
|
|
233
|
-
|
|
234
|
-
export default function robots(): MetadataRoute.Robots {
|
|
235
|
-
const domain = process.env.NEXT_PUBLIC_SITE_URL || "https://acme.com";
|
|
236
|
-
|
|
237
|
-
return {
|
|
238
|
-
rules: [
|
|
239
|
-
{
|
|
240
|
-
userAgent: "*",
|
|
241
|
-
allow: "/",
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
userAgent: ["GPTBot", "ChatGPT-User", "ClaudeBot", "PerplexityBot"],
|
|
245
|
-
allow: "/",
|
|
246
|
-
},
|
|
247
|
-
],
|
|
248
|
-
sitemap: `${domain}/sitemap.xml`,
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
---
|
|
254
|
-
|
|
255
|
-
## 🛠️ Step 5: Clean Markdown for AI Search (`app/llms.txt/route.ts`)
|
|
256
|
-
|
|
257
|
-
```typescript
|
|
258
|
-
// app/llms.txt/route.ts
|
|
259
|
-
import { NextResponse } from "next/server";
|
|
260
|
-
import { matrixEngine, SEO_CONFIG, PSEO_DATASET } from "@/lib/seo";
|
|
261
|
-
|
|
262
|
-
export async function GET() {
|
|
263
|
-
const domain = process.env.NEXT_PUBLIC_SITE_URL || "https://acme.com";
|
|
264
|
-
const pages = matrixEngine.generateAllMatrices(domain, PSEO_DATASET, SEO_CONFIG);
|
|
265
|
-
|
|
266
|
-
const markdown = [
|
|
267
|
-
`# ${SEO_CONFIG.brandName} Knowledge Base`,
|
|
268
|
-
`> Direct structured index for LLMs and AI Agents.`,
|
|
269
|
-
``,
|
|
270
|
-
`## Solutions & Use Cases`,
|
|
271
|
-
...pages.map((p) => `- [${p.h1}](${p.canonicalUrl}): ${p.description}`),
|
|
272
|
-
].join("\n");
|
|
273
|
-
|
|
274
|
-
return new NextResponse(markdown, {
|
|
275
|
-
headers: { "Content-Type": "text/plain; charset=utf-8" },
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
---
|
|
281
|
-
|
|
282
|
-
## 🚀 That's it!
|
|
283
|
-
Your application now deploys thousands of high-converting, compliant programmatic pages in **under 0.05ms** response time.
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ⚡ Cloudflare Worker Universal Reverse-Proxy Connector
|
|
3
|
-
*
|
|
4
|
-
* Works for: Shopify, Webflow, Wix, Squarespace, Framer, Astro, and any static site.
|
|
5
|
-
* Intercepts all 8 Programmatic Matrices with sub-20ms edge caching across 300+ PoPs:
|
|
6
|
-
* 1. 📍 /solutions/* (Local / GEO)
|
|
7
|
-
* 2. 🥊 /comparatif/*, /comparison/*, /vs/* (Comparatifs)
|
|
8
|
-
* 3. 🔄 /alternatives/* (Alternatives)
|
|
9
|
-
* 4. 🏢 /secteurs/*, /industries/* (Secteurs Métiers)
|
|
10
|
-
* 5. 🔌 /integrations/* (Intégrations Tech)
|
|
11
|
-
* 6. 👤 /metiers/*, /roles/* (Personas)
|
|
12
|
-
* 7. 🎯 /cas-usage/*, /use-cases/* (Cas d'Usage)
|
|
13
|
-
* 8. 🧮 /outils/*, /tools/* (Outils ROI)
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
const LYNXFLOW_LICENSE_KEY = "lynx_growth_votre_cle_ici";
|
|
17
|
-
const LYNXFLOW_ENGINE_URL = "https://lynxintel.io/api/v1/render-page";
|
|
18
|
-
|
|
19
|
-
const INTERCEPT_PATTERNS = [
|
|
20
|
-
"/solutions/",
|
|
21
|
-
"/comparatif/",
|
|
22
|
-
"/comparison/",
|
|
23
|
-
"/vs/",
|
|
24
|
-
"/alternatives/",
|
|
25
|
-
"/secteurs/",
|
|
26
|
-
"/industries/",
|
|
27
|
-
"/integrations/",
|
|
28
|
-
"/metiers/",
|
|
29
|
-
"/roles/",
|
|
30
|
-
"/cas-usage/",
|
|
31
|
-
"/use-cases/",
|
|
32
|
-
"/outils/",
|
|
33
|
-
"/tools/"
|
|
34
|
-
];
|
|
35
|
-
|
|
36
|
-
export default {
|
|
37
|
-
async fetch(request, env, ctx) {
|
|
38
|
-
const url = new URL(request.url);
|
|
39
|
-
const cleanPath = url.pathname.toLowerCase();
|
|
40
|
-
|
|
41
|
-
// Check if path or localized path matches any of the 8 matrices
|
|
42
|
-
const isProgrammaticRoute = INTERCEPT_PATTERNS.some((pattern) =>
|
|
43
|
-
cleanPath.includes(pattern)
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
if (isProgrammaticRoute) {
|
|
47
|
-
const cache = caches.default;
|
|
48
|
-
let response = await cache.match(request);
|
|
49
|
-
|
|
50
|
-
if (!response) {
|
|
51
|
-
const payload = {
|
|
52
|
-
licenseKey: LYNXFLOW_LICENSE_KEY,
|
|
53
|
-
path: url.pathname,
|
|
54
|
-
domain: url.origin,
|
|
55
|
-
brandName: "Votre Entreprise"
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const res = await fetch(LYNXFLOW_ENGINE_URL, {
|
|
59
|
-
method: "POST",
|
|
60
|
-
headers: { "Content-Type": "application/json" },
|
|
61
|
-
body: JSON.stringify(payload)
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
if (res.ok) {
|
|
65
|
-
const data = await res.json();
|
|
66
|
-
const html = `<!DOCTYPE html>
|
|
67
|
-
<html lang="${data.locale || 'fr'}">
|
|
68
|
-
<head>
|
|
69
|
-
<meta charset="UTF-8">
|
|
70
|
-
<title>${data.title}</title>
|
|
71
|
-
<meta name="description" content="${data.description}">
|
|
72
|
-
<script type="application/ld+json">${JSON.stringify(data.jsonLd)}</script>
|
|
73
|
-
<style>
|
|
74
|
-
body { font-family: system-ui, -apple-system, sans-serif; max-width: 900px; margin: 40px auto; padding: 0 20px; line-height: 1.6; color: #1e293b; }
|
|
75
|
-
h1 { font-size: 2.25rem; font-weight: 800; color: #0f172a; }
|
|
76
|
-
.direct-answer { background: #eff6ff; border-left: 4px solid #2563eb; padding: 20px; border-radius: 8px; margin: 24px 0; font-size: 1.1rem; }
|
|
77
|
-
</style>
|
|
78
|
-
</head>
|
|
79
|
-
<body>
|
|
80
|
-
<h1>${data.h1}</h1>
|
|
81
|
-
<p>${data.description}</p>
|
|
82
|
-
<div class="direct-answer"><strong>En Résumé :</strong> ${data.directAnswer}</div>
|
|
83
|
-
<article>${data.htmlBody}</article>
|
|
84
|
-
</body>
|
|
85
|
-
</html>`;
|
|
86
|
-
|
|
87
|
-
response = new Response(html, {
|
|
88
|
-
status: 200,
|
|
89
|
-
headers: {
|
|
90
|
-
"Content-Type": "text/html; charset=utf-8",
|
|
91
|
-
"Cache-Control": "public, max-age=604800, s-maxage=604800", // 7 jours de cache Edge
|
|
92
|
-
"X-Lynx-Engine": "Powered-by-LynxFlow",
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
ctx.waitUntil(cache.put(request, response.clone()));
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (response) return response;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Fallthrough to standard website (Shopify/Webflow/Wix)
|
|
104
|
-
return fetch(request);
|
|
105
|
-
}
|
|
106
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
<?php
|
|
2
|
-
|
|
3
|
-
namespace App\Http\Controllers;
|
|
4
|
-
|
|
5
|
-
use Illuminate\Http\Request;
|
|
6
|
-
use Illuminate\Support\Facades\Http;
|
|
7
|
-
use Illuminate\Support\Facades\Cache;
|
|
8
|
-
|
|
9
|
-
class LynxSeoController extends Controller
|
|
10
|
-
{
|
|
11
|
-
/**
|
|
12
|
-
* Universal Programmatic Controller: Serves all 8 Programmatic Matrix types
|
|
13
|
-
* with 24h local Redis/file caching.
|
|
14
|
-
*/
|
|
15
|
-
public function resolve(Request $request)
|
|
16
|
-
{
|
|
17
|
-
$path = $request->path();
|
|
18
|
-
$cacheKey = "lynx_page_" . md5($path);
|
|
19
|
-
|
|
20
|
-
$pageData = Cache::remember($cacheKey, 86400, function () use ($path, $request) {
|
|
21
|
-
$response = Http::timeout(3)->post(config('services.lynxflow.endpoint', 'https://lynxintel.io/api/v1/render-page'), [
|
|
22
|
-
'licenseKey' => config('services.lynxflow.license_key'),
|
|
23
|
-
'path' => $path,
|
|
24
|
-
'domain' => $request->root(),
|
|
25
|
-
'brandName' => config('app.name'),
|
|
26
|
-
]);
|
|
27
|
-
|
|
28
|
-
return $response->successful() ? $response->json() : null;
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
if (!$pageData) {
|
|
32
|
-
abort(404);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return view('lynx-seo.landing', ['page' => $pageData]);
|
|
36
|
-
}
|
|
37
|
-
}
|