@lynxflow/seo-engine 1.0.0 → 1.3.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 +333 -82
- package/connectors/cloudflare-worker/worker.js +54 -26
- package/connectors/laravel/LynxSeoController.php +8 -8
- package/connectors/wordpress/lynxseo-connector.php +296 -53
- package/dist/ai-copilot-client.d.ts +36 -0
- package/dist/analytics-client.d.ts +53 -0
- package/dist/auth-key.d.ts +57 -0
- package/dist/backlinks-client.d.ts +31 -0
- package/dist/engine.d.ts +79 -0
- package/dist/i18n-dictionary.d.ts +30 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +1561 -169
- package/dist/index.mjs +1759 -0
- package/dist/indexnow-client.d.ts +25 -0
- package/dist/lago-token-meter.d.ts +36 -0
- package/dist/schema-builder.d.ts +27 -0
- package/dist/serp-client.d.ts +42 -0
- package/dist/site-auditor.d.ts +29 -0
- package/dist/site-crawler.d.ts +76 -0
- package/dist/src/ai-copilot-client.d.ts +36 -0
- package/dist/src/analytics-client.d.ts +53 -0
- package/dist/src/auth-key.d.ts +57 -0
- package/dist/src/backlinks-client.d.ts +31 -0
- package/dist/src/engine.d.ts +72 -0
- package/dist/src/i18n-dictionary.d.ts +30 -0
- package/dist/src/index.d.ts +42 -0
- package/dist/src/indexnow-client.d.ts +25 -0
- package/dist/src/lago-token-meter.d.ts +36 -0
- package/dist/src/schema-builder.d.ts +27 -0
- package/dist/src/serp-client.d.ts +42 -0
- package/dist/src/site-auditor.d.ts +29 -0
- package/dist/src/token-quota-manager.d.ts +37 -0
- package/dist/src/types.d.ts +145 -0
- package/dist/token-quota-manager.d.ts +37 -0
- package/dist/types.d.ts +162 -0
- package/lynxflow-seo-engine-1.2.0.tgz +0 -0
- package/package.json +1 -1
- package/src/ai-copilot-client.ts +84 -0
- package/src/analytics-client.ts +141 -0
- package/src/auth-key.ts +203 -0
- package/src/backlinks-client.ts +85 -0
- package/src/engine.ts +508 -85
- package/src/i18n-dictionary.ts +362 -0
- package/src/index.ts +22 -4
- package/src/indexnow-client.ts +94 -0
- package/src/lago-token-meter.ts +7 -2
- package/src/schema-builder.ts +87 -0
- package/src/serp-client.ts +89 -0
- package/src/site-auditor.ts +83 -0
- package/src/site-crawler.ts +406 -0
- package/src/types.ts +148 -28
- package/tsconfig.json +14 -0
- package/lynxflow-seo-engine-1.0.0.tgz +0 -0
- package/src/licensing.ts +0 -138
package/README.md
CHANGED
|
@@ -1,66 +1,239 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 🦁 @lynxflow/seo-engine — Guide Complet & Documentation Développeur
|
|
2
2
|
|
|
3
|
-
> **
|
|
3
|
+
> **Le Moteur Universel de SEO Programmatique (pSEO), Optimisation Moteurs IA (AEO/GEO), Indexation Instantanée & Analytics Embarqués.**
|
|
4
4
|
|
|
5
|
-
`@lynxflow/seo-engine`
|
|
5
|
+
`@lynxflow/seo-engine` est un SDK TypeScript haute performance conçu pour générer, servir et indexer des millions de landing pages dynamiques, des avis 4.9/5★ Schema.org et des réponses directes pour les intelligences artificielles (ChatGPT Search, Perplexity, Google AI Overviews) en **moins de 0.05 milliseconde** avec **0% de charge sur votre base de données SQL**.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
## 📑 Sommaire
|
|
9
|
+
## 📑 Sommaire
|
|
10
|
+
1. [🌟 Présentation Générale](#1--présentation-générale)
|
|
11
|
+
2. [🔑 L'API Key Better Auth, Sécurité & Quotas](#2--lapi-key-better-auth-sécurité--quotas)
|
|
12
|
+
3. [🏛️ Les 8 Matrices Programmatiques & Multiplicateurs](#3--les-8-matrices-programmatiques--multiplicateurs)
|
|
13
|
+
4. [🚀 Tutoriel d'Intégration Pas-à-Pas (Next.js 15/16 & React 19)](#4--tutoriel-dintégration-pas-à-pas-nextjs-1516--react-19)
|
|
14
|
+
5. [🔌 Intégration sur Autres Frameworks (WordPress, Shopify, Cloudflare, Laravel, Astro)](#5--intégration-sur-autres-frameworks)
|
|
15
|
+
6. [🧰 Les 7 Modules Embarqués du SDK (Analytics, SERP, Backlinks, IA, IndexNow)](#6--les-7-modules-embarqués-du-sdk)
|
|
16
|
+
7. [🌍 Internationalisation & Zéro Contenu Dupliqué (10 Langues & Hreflang)](#7--internationalisation--zéro-contenu-dupliqué)
|
|
17
|
+
8. [📘 Référence Complète des Types TypeScript](#8--référence-complète-des-types-typescript)
|
|
10
18
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 1. 🌟 Présentation Générale
|
|
22
|
+
|
|
23
|
+
### Pourquoi utiliser `@lynxflow/seo-engine` ?
|
|
24
|
+
* ⚡ **Résolution Ultra-Rapide (< 0.05ms) :** Les pages et métadonnées sont résolues en mémoire vive sans requête SQL bloquante.
|
|
25
|
+
* 🤖 **Conçu pour le Search IA (AEO / GEO) :** Génère des blocs de synthèse directe optimisés pour être cités en source n°1 par **ChatGPT Search**, **Perplexity** et **Google AI Overviews**.
|
|
26
|
+
* 🛡️ **Fonctionne à 100% en Local / Sans Dépendance API Bloquante :** La validation cryptographique HMAC de votre clé d'API s'exécute directement sur votre serveur pour garantir un affichage instantané même en cas de panne réseau.
|
|
27
|
+
* 📈 **Suite Complète Embarquée :** Accédez directement à vos analytics de trafic, votre détection de bots IA, vos positions de mots-clés Google et vos backlinks sans quitter votre application.
|
|
16
28
|
|
|
17
29
|
---
|
|
18
30
|
|
|
19
|
-
##
|
|
31
|
+
## 2. 🔑 L'API Key Better Auth, Sécurité & Quotas
|
|
20
32
|
|
|
21
|
-
###
|
|
33
|
+
### Étape 1 : Obtenir votre Clé d'API
|
|
34
|
+
Rendez-vous dans votre cockpit LynxFlow dans **Paramètres ➔ Clés d'API & Sécurité** et générez votre clé (`ba_key_...` ou `lynx_api_...`).
|
|
35
|
+
|
|
36
|
+
### Étape 2 : Configuration dans votre fichier `.env` ou `.env.local`
|
|
37
|
+
```bash
|
|
38
|
+
# 🔑 Clé d'API Better Auth
|
|
39
|
+
LYNXFLOW_API_KEY=ba_key_growth_tenant_acme_a8f93e
|
|
40
|
+
|
|
41
|
+
# 🌐 Domaine de votre site web
|
|
42
|
+
NEXT_PUBLIC_SITE_URL=https://mon-entreprise.com
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Grille des Forfaits & Règles de Sécurité :
|
|
46
|
+
|
|
47
|
+
| Forfait (Tier) | Préfixe de Clé | Quota de Pages Uniques | Nombre de Domaines Autorisés | Budget Crédits IA / mois |
|
|
48
|
+
|---|---|---|---|---|
|
|
49
|
+
| **Starter** | `ba_test_*` ou `ba_key_starter_*` | **50 000 pages uniques** | **1 seul domaine** (Verrouillage Monosite) | 1 000 crédits ($10) |
|
|
50
|
+
| **Growth** | `ba_key_*` ou `ba_key_growth_*` | **500 000 pages uniques** | **Jusqu'à 3 domaines** | 10 000 crédits ($100) |
|
|
51
|
+
| **Enterprise** | `ba_admin_*` ou `lynx_enterprise_*` | **Illimité (5 000 000+)** | **Domaines illimités** | 100 000 crédits ($1 000) |
|
|
52
|
+
|
|
53
|
+
### 🧠 Comment fonctionne la Comptabilité des Pages (URLs Uniques vs Hits) ?
|
|
54
|
+
* **Une Page = Une URL Unique :** Si vous avez 500 villes pour 2 services, votre catalogue contient **1 000 pages uniques**.
|
|
55
|
+
* **Trafic / Visites Illimité & Gratuit :** Si 100 000 visiteurs visitent `/solutions/crm/paris`, cela compte pour **1 seule page unique** dans votre quota, pas 100 000 !
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 3. 🏛️ Les 8 Matrices Programmatiques & Multiplicateurs
|
|
60
|
+
|
|
61
|
+
Le moteur intègre nativement les 8 familles stratégiques de pages :
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
┌────┬───────────────────────────────────┬──────────────────────────────────────────┬────────────────────────────────────────────────────────┐
|
|
65
|
+
│ # │ FAMILLE DE MATRICE │ FORMULE D'URL PROGRAMMATIQUE │ EXEMPLE RÉSOLU EN < 0.05MS │
|
|
66
|
+
├────┼───────────────────────────────────┼──────────────────────────────────────────┼────────────────────────────────────────────────────────┤
|
|
67
|
+
│ 1 │ 📍 1. Local & GEO │ `/solutions/{module}/{ville}` │ `/solutions/crm-pipeline/lyon` │
|
|
68
|
+
│ 2 │ 🥊 2. VS Comparatifs │ `/comparatif/{module}-vs-{concurrent}` │ `/comparatif/crm-pipeline-vs-hubspot` │
|
|
69
|
+
│ 3 │ 🔄 3. Alternatives Logiciels │ `/alternatives/alternative-a-{nom}` │ `/alternatives/alternative-a-aircall` │
|
|
70
|
+
│ 4 │ 🏢 4. Secteurs & Métiers B2B │ `/secteurs/{module}-pour-{secteur}` │ `/secteurs/crm-pipeline-pour-avocats` │
|
|
71
|
+
│ 5 │ 🔌 5. Intégrations & Tech │ `/integrations/{module}-avec-{logiciel}` │ `/integrations/crm-pipeline-avec-shopify` │
|
|
72
|
+
│ 6 │ 👤 6. Personas & Décideurs │ `/metiers/{module}-pour-{role}` │ `/metiers/crm-pipeline-pour-directeur-commercial` │
|
|
73
|
+
│ 7 │ 🎯 7. Cas d'Usage Opérationnels │ `/cas-usage/{module}-{sujet}` │ `/cas-usage/crm-pipeline-relance-devis` │
|
|
74
|
+
│ 8 │ 🧮 8. Calculateurs & Outils ROI │ `/outils/simulateur-roi-{module}` │ `/outils/simulateur-roi-crm-pipeline` │
|
|
75
|
+
└────┴───────────────────────────────────┴──────────────────────────────────────────┴────────────────────────────────────────────────────────┘
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 🌟 Le Lien Unique Ultra-Combiné (8 Slugs en 1 Seule URL) :
|
|
79
|
+
Si vous souhaitez cibler une requête ultra-précise combinant tous les critères dans une seule URL :
|
|
80
|
+
```
|
|
81
|
+
https://mon-entreprise.com/solutions/crm-pipeline/avocats/hubspot/gmail/directeur-commercial/paris/simulateur-roi
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 4. 🚀 Tutoriel d'Intégration Pas-à-Pas (Next.js 15/16 & React 19)
|
|
87
|
+
|
|
88
|
+
### Étape 1 : Installation
|
|
22
89
|
```bash
|
|
23
|
-
bun add @lynxflow/seo-engine
|
|
24
|
-
# ou
|
|
25
90
|
npm install @lynxflow/seo-engine
|
|
91
|
+
# ou
|
|
92
|
+
bun add @lynxflow/seo-engine
|
|
26
93
|
```
|
|
27
94
|
|
|
28
|
-
###
|
|
95
|
+
### Étape 2 : Initialisation dans `lib/seo.ts`
|
|
29
96
|
```typescript
|
|
97
|
+
// lib/seo.ts
|
|
30
98
|
import { createLynxSeoEngine } from "@lynxflow/seo-engine";
|
|
31
|
-
import type { Metadata } from "next";
|
|
32
99
|
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
domain: "https://
|
|
36
|
-
brandName: "
|
|
100
|
+
export const seoEngine = createLynxSeoEngine({
|
|
101
|
+
apiKey: process.env.LYNXFLOW_API_KEY!,
|
|
102
|
+
domain: process.env.NEXT_PUBLIC_SITE_URL || "https://mon-entreprise.com",
|
|
103
|
+
brandName: "Acme Corp",
|
|
104
|
+
defaultLocale: "fr",
|
|
105
|
+
supportedLocales: ["fr", "en", "es", "pt", "de", "ar", "ja", "zh", "ko", "hi", "id"],
|
|
37
106
|
services: [
|
|
38
|
-
{
|
|
39
|
-
|
|
107
|
+
{
|
|
108
|
+
slug: "crm-pipeline",
|
|
109
|
+
name: "CRM Pipeline Commercial",
|
|
110
|
+
pricePerMonth: 49,
|
|
111
|
+
category: "Ventes & CRM",
|
|
112
|
+
features: ["Kanban interactif", "Relances automatiques IA 24/7", "WhatsApp Sync"],
|
|
113
|
+
faqs: [
|
|
114
|
+
{ question: "Puis-je importer mes contacts existants ?", answer: "Oui, l'import CSV et Excel se fait en 1 clic." },
|
|
115
|
+
{ question: "Le support technique est-il inclus ?", answer: "Oui, support prioritaire 24/7 par chat et email." }
|
|
116
|
+
]
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
slug: "standard-vocal-ia",
|
|
120
|
+
name: "Standard Vocal Téléphonique IA",
|
|
121
|
+
pricePerMonth: 79,
|
|
122
|
+
category: "Téléphonie IA",
|
|
123
|
+
features: ["Décrochage 0 seconde 24/7", "Qualification automatique des prospects"]
|
|
124
|
+
}
|
|
40
125
|
]
|
|
41
126
|
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Étape 3 : Générateur d'Images Réseaux Sociaux Dynamiques (`app/api/og/route.tsx`)
|
|
130
|
+
```tsx
|
|
131
|
+
// app/api/og/route.tsx
|
|
132
|
+
import { ImageResponse } from "next/og";
|
|
133
|
+
import type { NextRequest } from "next/server";
|
|
134
|
+
|
|
135
|
+
export const runtime = "edge";
|
|
136
|
+
|
|
137
|
+
export async function GET(request: NextRequest) {
|
|
138
|
+
const { searchParams } = new URL(request.url);
|
|
139
|
+
const title = searchParams.get("title") || "Solution SaaS & IA";
|
|
140
|
+
const brand = searchParams.get("brand") || "LynxFlow";
|
|
141
|
+
const service = searchParams.get("service") || "Plateforme B2B";
|
|
142
|
+
|
|
143
|
+
return new ImageResponse(
|
|
144
|
+
(
|
|
145
|
+
<div style={{ height: "100%", width: "100%", display: "flex", flexDirection: "column", justifyContent: "space-between", backgroundColor: "#030712", padding: "60px 80px", fontFamily: "sans-serif" }}>
|
|
146
|
+
<div style={{ display: "flex", alignItems: "center", gap: "16px" }}>
|
|
147
|
+
<div style={{ background: "#2563eb", color: "#fff", padding: "8px 20px", borderRadius: "9999px", fontSize: 24, fontWeight: 700 }}>{brand}</div>
|
|
148
|
+
<div style={{ color: "#94a3b8", fontSize: 24 }}>• {service}</div>
|
|
149
|
+
</div>
|
|
150
|
+
<div style={{ color: "#ffffff", fontSize: 54, fontWeight: 900, lineHeight: 1.15 }}>{title}</div>
|
|
151
|
+
<div style={{ display: "flex", gap: "16px", color: "#e2e8f0", fontSize: 22 }}>
|
|
152
|
+
<span>⭐ 4.9/5 (1 280 avis vérifiés)</span>
|
|
153
|
+
<span>•</span>
|
|
154
|
+
<span>Mise en service immédiate</span>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
),
|
|
158
|
+
{ width: 1200, height: 630 }
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Étape 4 : La Route Catch-All Universelle (`app/[...slug]/page.tsx`)
|
|
164
|
+
```tsx
|
|
165
|
+
// app/[...slug]/page.tsx
|
|
166
|
+
import { seoEngine } from "@/lib/seo";
|
|
167
|
+
import { notFound } from "next/navigation";
|
|
168
|
+
import type { Metadata } from "next";
|
|
169
|
+
|
|
170
|
+
interface PageProps {
|
|
171
|
+
params: Promise<{ slug: string[] }>;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// 1. Métadonnées SEO, Balises Hreflang et Image Sociale
|
|
175
|
+
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
|
|
176
|
+
const { slug } = await params;
|
|
177
|
+
const path = "/" + (slug || []).join("/");
|
|
178
|
+
const page = seoEngine.resolve(path);
|
|
42
179
|
|
|
43
|
-
export async function generateMetadata({ params }: { params: { service: string; country: string; city: string } }): Promise<Metadata> {
|
|
44
|
-
const page = engine.resolve(`/solutions/${params.service}/${params.country}/${params.city}`);
|
|
45
180
|
if (!page) return {};
|
|
181
|
+
|
|
46
182
|
return {
|
|
47
|
-
title: page.
|
|
48
|
-
description: page.
|
|
49
|
-
alternates: {
|
|
50
|
-
|
|
183
|
+
title: page.title,
|
|
184
|
+
description: page.description,
|
|
185
|
+
alternates: {
|
|
186
|
+
canonical: page.url,
|
|
187
|
+
languages: page.hreflangs?.reduce((acc, h) => ({ ...acc, [h.lang]: h.url }), {})
|
|
188
|
+
},
|
|
189
|
+
openGraph: {
|
|
190
|
+
title: page.title,
|
|
191
|
+
description: page.description,
|
|
192
|
+
images: [{ url: page.meta?.openGraphImageUrl || `${page.url}/api/og` }]
|
|
193
|
+
}
|
|
51
194
|
};
|
|
52
195
|
}
|
|
53
196
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
197
|
+
// 2. Rendu Server Component Ultra-Rapide (< 0.05ms)
|
|
198
|
+
export default async function UniversalCatchAllPage({ params }: PageProps) {
|
|
199
|
+
const { slug } = await params;
|
|
200
|
+
const path = "/" + (slug || []).join("/");
|
|
201
|
+
const page = seoEngine.resolve(path);
|
|
202
|
+
|
|
203
|
+
if (!page) notFound();
|
|
204
|
+
|
|
205
|
+
// Enregistrer la visite pour les analytics et la détection de bots IA
|
|
206
|
+
await seoEngine.analytics.trackPageView({ path });
|
|
57
207
|
|
|
58
208
|
return (
|
|
59
|
-
<main className="max-w-4xl mx-auto py-12 px-
|
|
60
|
-
|
|
61
|
-
<
|
|
62
|
-
|
|
63
|
-
|
|
209
|
+
<main className="max-w-4xl mx-auto py-12 px-6">
|
|
210
|
+
{/* 🌟 Graphe Schema.org 4.9★ (Product + FAQPage + Speakable) */}
|
|
211
|
+
<script
|
|
212
|
+
type="application/ld+json"
|
|
213
|
+
dangerouslySetInnerHTML={{ __html: JSON.stringify(page.jsonLd) }}
|
|
214
|
+
/>
|
|
215
|
+
|
|
216
|
+
<h1 className="text-4xl font-black text-gray-900 tracking-tight">{page.h1}</h1>
|
|
217
|
+
<p className="mt-4 text-lg text-gray-600 leading-relaxed">{page.description}</p>
|
|
218
|
+
|
|
219
|
+
{/* 🤖 Bloc AEO de Réponse Directe pour ChatGPT / Perplexity */}
|
|
220
|
+
<div className="my-8 rounded-2xl bg-blue-50 border-l-4 border-blue-600 p-6">
|
|
221
|
+
<h3 className="text-xs font-bold uppercase tracking-wider text-blue-900">En Résumé (Réponse Directe IA) :</h3>
|
|
222
|
+
<p className="mt-2 text-base text-blue-950 font-medium leading-relaxed">{page.directAnswer}</p>
|
|
223
|
+
</div>
|
|
224
|
+
|
|
225
|
+
{/* ❓ Section FAQ Interactive */}
|
|
226
|
+
<section className="mt-12">
|
|
227
|
+
<h2 className="text-2xl font-bold text-gray-900">Questions Fréquentes</h2>
|
|
228
|
+
<div className="mt-6 space-y-4">
|
|
229
|
+
{page.faqs.map((faq, idx) => (
|
|
230
|
+
<details key={idx} className="rounded-xl border border-gray-200 p-5 bg-white shadow-xs">
|
|
231
|
+
<summary className="cursor-pointer font-semibold text-gray-900">{faq.question}</summary>
|
|
232
|
+
<p className="mt-3 text-gray-700 leading-relaxed">{faq.answer}</p>
|
|
233
|
+
</details>
|
|
234
|
+
))}
|
|
235
|
+
</div>
|
|
236
|
+
</section>
|
|
64
237
|
</main>
|
|
65
238
|
);
|
|
66
239
|
}
|
|
@@ -68,74 +241,152 @@ export default async function SolutionPage({ params }: { params: { service: stri
|
|
|
68
241
|
|
|
69
242
|
---
|
|
70
243
|
|
|
71
|
-
##
|
|
244
|
+
## 5. 🔌 Intégration sur Autres Frameworks
|
|
245
|
+
|
|
246
|
+
### WordPress (Plugin 100% Autonome)
|
|
247
|
+
1. Téléchargez l'archive [`packages/lynx-seo-engine/connectors/wordpress/lynxseo-connector.zip`](file:///Users/mahjoubhamid/Documents/01-projet_lynxflow/packages/lynx-seo-engine/connectors/wordpress/lynxseo-connector.zip).
|
|
248
|
+
2. Téléversez-la dans vos extensions WordPress (`wp-admin ➔ Extensions ➔ Ajouter`).
|
|
249
|
+
3. Connectez-vous en 1 clic via Better Auth ou renseignez votre `LYNXFLOW_API_KEY`.
|
|
250
|
+
4. Vos 8 matrices et votre sitemap dynamique `/sitemap-solutions.xml` sont immédiatement actifs avec **0% de charge sur votre base MySQL**.
|
|
251
|
+
|
|
252
|
+
### Cloudflare Edge Worker (Shopify, Webflow, Wix, Squarespace)
|
|
253
|
+
Déployez `connectors/cloudflare-worker/worker.js` sur votre compte Cloudflare pour intercepter et servir vos pages programmatiques au niveau du réseau Edge en moins de 20ms dans plus de 300 villes à travers le monde.
|
|
254
|
+
|
|
255
|
+
### Laravel / PHP
|
|
256
|
+
```php
|
|
257
|
+
// routes/web.php
|
|
258
|
+
Route::get('/{any}', [LynxSeoController::class, 'resolve'])->where('any', '.*');
|
|
259
|
+
```
|
|
72
260
|
|
|
73
|
-
### Route : `src/pages/solutions/[service]/[country]/[city].astro`
|
|
74
|
-
```astro
|
|
75
261
|
---
|
|
76
|
-
import { createLynxSeoEngine } from "@lynxflow/seo-engine";
|
|
77
262
|
|
|
78
|
-
|
|
263
|
+
## 6. 🧰 Les 7 Modules Embarqués du SDK
|
|
79
264
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
265
|
+
Vous pouvez utiliser n'importe quel module du SDK de manière autonome dans votre propre code :
|
|
266
|
+
|
|
267
|
+
### 1. 📊 `engine.analytics` : Trafic Web & Détection des Robots IA
|
|
268
|
+
```typescript
|
|
269
|
+
// Enregistrer un événement de visite
|
|
270
|
+
await seoEngine.analytics.trackPageView({
|
|
271
|
+
path: "/solutions/crm-pipeline/paris",
|
|
272
|
+
userAgent: request.headers.get("user-agent") || ""
|
|
87
273
|
});
|
|
88
274
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
275
|
+
// Récupérer le rapport de trafic et les visites des robots IA
|
|
276
|
+
const stats = await seoEngine.analytics.getSummary("30d");
|
|
277
|
+
console.log("Visiteurs Uniques :", stats.uniqueVisitors);
|
|
278
|
+
console.log("Robots IA détectés :", stats.aiBotVisits); // ChatGPT, Perplexity, Googlebot
|
|
279
|
+
```
|
|
92
280
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
<body>
|
|
100
|
-
<h1>{page.meta.h1}</h1>
|
|
101
|
-
<div set:html={page.content.directAnswerGeoHtml} />
|
|
102
|
-
<article>{page.content.markdownBody}</article>
|
|
103
|
-
</body>
|
|
104
|
-
</html>
|
|
281
|
+
### 2. 🔎 `engine.serp` : Suivi des Positions Google & Mots-Clés
|
|
282
|
+
```typescript
|
|
283
|
+
const ranking = await seoEngine.serp.trackKeyword("crm pipeline commercial", "FR");
|
|
284
|
+
console.log("Position Google :", ranking.position);
|
|
285
|
+
console.log("Volume Mensuel :", ranking.searchVolume);
|
|
286
|
+
console.log("Présence IA Overview :", ranking.hasAiOverview);
|
|
105
287
|
```
|
|
106
288
|
|
|
107
|
-
|
|
289
|
+
### 3. 🔗 `engine.backlinks` : Suivi des Liens Entrants & Domain Authority
|
|
290
|
+
```typescript
|
|
291
|
+
const backlinks = await seoEngine.backlinks.getProfile("mon-entreprise.com");
|
|
292
|
+
console.log("Domain Authority (DA) :", backlinks.domainAuthority);
|
|
293
|
+
console.log("Total Backlinks :", backlinks.totalBacklinks);
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### 4. 🤖 `engine.ai` : Copilote de Rédaction de Contenus IA
|
|
297
|
+
```typescript
|
|
298
|
+
const article = await seoEngine.ai.generateArticle({
|
|
299
|
+
topic: "Automatisation du CRM pour Avocats",
|
|
300
|
+
targetKeywords: ["crm avocats", "logiciel cabinet d'avocat"],
|
|
301
|
+
wordCount: 1500
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
console.log("Titre :", article.title);
|
|
305
|
+
console.log("Contenu Markdown :", article.markdownContent);
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### 5. ⚡ `engine.indexNow` : Indexation Immédiate sur Bing, Yandex, Seznam
|
|
309
|
+
```typescript
|
|
310
|
+
await seoEngine.indexNow.submitUrls([
|
|
311
|
+
"https://mon-entreprise.com/solutions/crm-pipeline/paris",
|
|
312
|
+
"https://mon-entreprise.com/solutions/crm-pipeline/lyon"
|
|
313
|
+
]);
|
|
314
|
+
```
|
|
108
315
|
|
|
109
|
-
|
|
316
|
+
### 6. 🔍 `engine.auditor` : Audit Qualité SEO & Validation Meta
|
|
317
|
+
```typescript
|
|
318
|
+
const audit = seoEngine.auditor.inspectMeta({
|
|
319
|
+
title: "CRM Ventes pour PME | Acme Corp",
|
|
320
|
+
description: "Accélérez vos ventes grâce à notre CRM automatisé. Essai gratuit.",
|
|
321
|
+
h1: "Le CRM pensé pour vos commerciaux",
|
|
322
|
+
directAnswer: "Acme Corp propose le meilleur CRM automatisé pour PME dès 49€/mois."
|
|
323
|
+
});
|
|
110
324
|
|
|
111
|
-
|
|
325
|
+
console.log("Score SEO :", audit.score); // 100/100
|
|
326
|
+
```
|
|
112
327
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
328
|
+
### 7. 🌟 `engine.schema` : Constructeur de Graphe Schema.org 4.9★
|
|
329
|
+
```typescript
|
|
330
|
+
const schemaJson = seoEngine.schema.buildGraph({
|
|
331
|
+
url: "https://mon-entreprise.com/ma-page",
|
|
332
|
+
name: "CRM Pipeline Commercial",
|
|
333
|
+
brandName: "Acme Corp",
|
|
334
|
+
price: 49
|
|
335
|
+
});
|
|
336
|
+
```
|
|
117
337
|
|
|
118
338
|
---
|
|
119
339
|
|
|
120
|
-
##
|
|
340
|
+
## 7. 🌍 Internationalisation & Zéro Contenu Dupliqué
|
|
121
341
|
|
|
122
|
-
|
|
342
|
+
Le moteur génère automatiquement les traductions et l'interconnexion `hreflang` officielle pour **10 langues mondiales** :
|
|
123
343
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
344
|
+
* 🇫🇷 **Français (`fr`) :** `/fr/solutions/crm-pipeline/paris`
|
|
345
|
+
* 🇬🇧 **Anglais (`en`) :** `/en/solutions/crm-pipeline/london`
|
|
346
|
+
* 🇧🇷 **Portugais Brésil (`pt`) :** `/pt/solutions/crm-pipeline/sao-paulo`
|
|
347
|
+
* 🇪🇸 **Espagnol LatAm (`es`) :** `/es/solutions/crm-pipeline/mexico`
|
|
348
|
+
* 🇩🇪 **Allemand (`de`) :** `/de/solutions/crm-pipeline/berlin`
|
|
349
|
+
* 🇸🇦 **Arabe (`ar` RTL) :** `/ar/solutions/crm-pipeline/riyadh`
|
|
350
|
+
* 🇯🇵 **Japonais (`ja`) :** `/ja/solutions/crm-pipeline/tokyo`
|
|
351
|
+
* 🇨🇳 **Chinois (`zh`) :** `/zh/solutions/crm-pipeline/shanghai`
|
|
352
|
+
* 🇰🇷 **Coréen (`ko`) :** `/ko/solutions/crm-pipeline/seoul`
|
|
353
|
+
* 🇮🇳 **Hindi (`hi`) :** `/hi/solutions/crm-pipeline/mumbai`
|
|
127
354
|
|
|
128
355
|
---
|
|
129
356
|
|
|
130
|
-
##
|
|
357
|
+
## 8. 📘 Référence Complète des Types TypeScript
|
|
131
358
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
359
|
+
```typescript
|
|
360
|
+
import {
|
|
361
|
+
createLynxSeoEngine,
|
|
362
|
+
LynxSeoEngine,
|
|
363
|
+
ApiKeyGuardian,
|
|
364
|
+
LagoTokenMeter,
|
|
365
|
+
HyperswitchGateway,
|
|
366
|
+
IndexNowClient,
|
|
367
|
+
SiteAuditor,
|
|
368
|
+
SchemaGraphBuilder,
|
|
369
|
+
LynxAnalyticsClient,
|
|
370
|
+
SerpClient,
|
|
371
|
+
BacklinksClient,
|
|
372
|
+
AiCopilotClient,
|
|
373
|
+
type LynxSeoConfig,
|
|
374
|
+
type LynxResolvedPage,
|
|
375
|
+
type LynxServiceDefinition,
|
|
376
|
+
type PseoIndustry,
|
|
377
|
+
type PseoCompetitor,
|
|
378
|
+
type PseoIntegration,
|
|
379
|
+
type PseoUseCase,
|
|
380
|
+
type PseoPersona,
|
|
381
|
+
type SeoAuditReport,
|
|
382
|
+
type AnalyticsSummaryReport,
|
|
383
|
+
type KeywordRankingItem,
|
|
384
|
+
type BacklinkProfileSummary,
|
|
385
|
+
type GeneratedArticleResult
|
|
386
|
+
} from "@lynxflow/seo-engine";
|
|
387
|
+
```
|
|
137
388
|
|
|
138
389
|
---
|
|
139
390
|
|
|
140
|
-
##
|
|
141
|
-
|
|
391
|
+
## 📄 Licence & Propriété
|
|
392
|
+
Propriétaire © LynxFlow Technologies. Tous droits réservés.
|
|
@@ -1,34 +1,56 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ⚡ Cloudflare Worker Universal Reverse-Proxy Connector
|
|
3
3
|
*
|
|
4
|
-
* Works for: Shopify, Webflow, Wix, Squarespace, Framer, and any static site.
|
|
5
|
-
*
|
|
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)
|
|
6
14
|
*/
|
|
7
15
|
|
|
8
|
-
const LYNXFLOW_LICENSE_KEY = "
|
|
16
|
+
const LYNXFLOW_LICENSE_KEY = "lynx_growth_votre_cle_ici";
|
|
9
17
|
const LYNXFLOW_ENGINE_URL = "https://lynxintel.io/api/v1/render-page";
|
|
10
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
|
+
|
|
11
36
|
export default {
|
|
12
37
|
async fetch(request, env, ctx) {
|
|
13
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
|
+
);
|
|
14
45
|
|
|
15
|
-
|
|
16
|
-
if (url.pathname.startsWith("/solutions/")) {
|
|
46
|
+
if (isProgrammaticRoute) {
|
|
17
47
|
const cache = caches.default;
|
|
18
48
|
let response = await cache.match(request);
|
|
19
49
|
|
|
20
50
|
if (!response) {
|
|
21
|
-
const parts = url.pathname.split("/").filter(Boolean);
|
|
22
|
-
// e.g. /solutions/droit-immobilier/fr/lyon
|
|
23
|
-
const service = parts[1];
|
|
24
|
-
const country = parts[2];
|
|
25
|
-
const city = parts[3];
|
|
26
|
-
|
|
27
51
|
const payload = {
|
|
28
52
|
licenseKey: LYNXFLOW_LICENSE_KEY,
|
|
29
|
-
|
|
30
|
-
country,
|
|
31
|
-
city,
|
|
53
|
+
path: url.pathname,
|
|
32
54
|
domain: url.origin,
|
|
33
55
|
brandName: "Votre Entreprise"
|
|
34
56
|
};
|
|
@@ -42,29 +64,35 @@ export default {
|
|
|
42
64
|
if (res.ok) {
|
|
43
65
|
const data = await res.json();
|
|
44
66
|
const html = `<!DOCTYPE html>
|
|
45
|
-
<html lang="fr">
|
|
67
|
+
<html lang="${data.locale || 'fr'}">
|
|
46
68
|
<head>
|
|
47
69
|
<meta charset="UTF-8">
|
|
48
|
-
<title>${data.
|
|
49
|
-
<meta name="description" content="${data.
|
|
50
|
-
<script type="application/ld+json">${JSON.stringify(data.
|
|
51
|
-
<style>
|
|
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>
|
|
52
78
|
</head>
|
|
53
79
|
<body>
|
|
54
|
-
<h1>${data.
|
|
55
|
-
|
|
56
|
-
<
|
|
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>
|
|
57
84
|
</body>
|
|
58
85
|
</html>`;
|
|
59
86
|
|
|
60
87
|
response = new Response(html, {
|
|
88
|
+
status: 200,
|
|
61
89
|
headers: {
|
|
62
|
-
"Content-Type": "text/html; charset=
|
|
63
|
-
"Cache-Control": "public, max-age=
|
|
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",
|
|
64
93
|
}
|
|
65
94
|
});
|
|
66
95
|
|
|
67
|
-
// Cache on Cloudflare Edge globally
|
|
68
96
|
ctx.waitUntil(cache.put(request, response.clone()));
|
|
69
97
|
}
|
|
70
98
|
}
|
|
@@ -72,7 +100,7 @@ export default {
|
|
|
72
100
|
if (response) return response;
|
|
73
101
|
}
|
|
74
102
|
|
|
75
|
-
//
|
|
103
|
+
// Fallthrough to standard website (Shopify/Webflow/Wix)
|
|
76
104
|
return fetch(request);
|
|
77
105
|
}
|
|
78
106
|
};
|
|
@@ -9,18 +9,18 @@ use Illuminate\Support\Facades\Cache;
|
|
|
9
9
|
class LynxSeoController extends Controller
|
|
10
10
|
{
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Universal Programmatic Controller: Serves all 8 Programmatic Matrix types
|
|
13
|
+
* with 24h local Redis/file caching.
|
|
13
14
|
*/
|
|
14
|
-
public function
|
|
15
|
+
public function resolve(Request $request)
|
|
15
16
|
{
|
|
16
|
-
$
|
|
17
|
+
$path = $request->path();
|
|
18
|
+
$cacheKey = "lynx_page_" . md5($path);
|
|
17
19
|
|
|
18
|
-
$pageData = Cache::remember($cacheKey, 86400, function () use ($
|
|
19
|
-
$response = Http::timeout(
|
|
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'), [
|
|
20
22
|
'licenseKey' => config('services.lynxflow.license_key'),
|
|
21
|
-
'
|
|
22
|
-
'country' => $country,
|
|
23
|
-
'city' => $city,
|
|
23
|
+
'path' => $path,
|
|
24
24
|
'domain' => $request->root(),
|
|
25
25
|
'brandName' => config('app.name'),
|
|
26
26
|
]);
|