feat: refonte complète landing page - tunnel de vente + SEO optimisé
- SEO technique: sitemap.ts, robots.ts, structured data JSON-LD (Organization, Course, FAQPage) - Meta tags optimisés pour 12+ mots-clés TikTok Shop France - Hero SEO-optimisé: H1 ciblant "formation TikTok Shop" + "créateur affilié France" - Nouvelle section ResultsShowcase: stats marché TikTok Shop + timeline 8 semaines - Tableau comparatif HookLab vs alternatives - 6 témoignages avec disclaimer Google-compliant (pas de faux avis) - Pricing avec prix barré, bonus inclus, garantie satisfait ou remboursé - Badges de confiance (paiement sécurisé, RGPD, support, garantie) - Pop-up exit-intent (desktop) avec stats marché - Barre sticky CTA mobile - Notifications social proof animées - CTA final avant footer - Barre d'annonce urgence en haut - FAQ enrichie (10 questions) avec structured data FAQPage - Smooth scroll + animations CSS ajoutées https://claude.ai/code/session_01H2aRGDaKgarPvhay2HxN6Y
This commit is contained in:
@@ -29,7 +29,12 @@ body {
|
||||
font-family: var(--font-sans);
|
||||
}
|
||||
|
||||
/* Scrollbar personnalisée */
|
||||
/* Smooth scroll for anchor links */
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Scrollbar personnalisee */
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
@@ -90,3 +95,25 @@ body {
|
||||
.pulse-glow {
|
||||
animation: pulse-glow 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Scale in animation for popups */
|
||||
@keyframes scale-in {
|
||||
0% {
|
||||
transform: scale(0.9);
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.animate-scale-in {
|
||||
animation: scale-in 0.3s ease-out;
|
||||
}
|
||||
|
||||
/* Selection color */
|
||||
::selection {
|
||||
background: rgba(109, 94, 246, 0.3);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
127
app/layout.tsx
127
app/layout.tsx
@@ -1,22 +1,75 @@
|
||||
import type { Metadata } from "next";
|
||||
import "./globals.css";
|
||||
|
||||
const BASE_URL = process.env.NEXT_PUBLIC_APP_URL || "https://hooklab.eu";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "HookLab | Programme coaching TikTok Shop 8 semaines",
|
||||
metadataBase: new URL(BASE_URL),
|
||||
title: {
|
||||
default:
|
||||
"HookLab | Formation TikTok Shop France - Deviens Cr\u00e9ateur Affili\u00e9",
|
||||
template: "%s | HookLab",
|
||||
},
|
||||
description:
|
||||
"Rejoins HookLab et lance ton business TikTok Shop en 8 semaines. Programme de coaching complet pour créateurs affiliés.",
|
||||
"Formation coaching TikTok Shop en 8 semaines. Deviens cr\u00e9ateur affili\u00e9 et g\u00e9n\u00e8re des revenus avec l\u2019affiliation TikTok Shop en France. Programme complet : strat\u00e9gie, contenu, mon\u00e9tisation.",
|
||||
keywords: [
|
||||
"TikTok Shop",
|
||||
"coaching",
|
||||
"affiliation",
|
||||
"créateur",
|
||||
"formation",
|
||||
"formation TikTok Shop",
|
||||
"coaching TikTok Shop",
|
||||
"affiliation TikTok Shop France",
|
||||
"gagner de l'argent TikTok Shop",
|
||||
"cr\u00e9ateur TikTok Shop France",
|
||||
"commission TikTok Shop",
|
||||
"programme affiliation TikTok",
|
||||
"revenus TikTok Shop",
|
||||
"devenir affili\u00e9 TikTok Shop",
|
||||
"mon\u00e9tisation TikTok France",
|
||||
"tuto TikTok Shop d\u00e9butant",
|
||||
"revenus passifs TikTok",
|
||||
],
|
||||
authors: [{ name: "HookLab" }],
|
||||
creator: "HookLab",
|
||||
publisher: "HookLab",
|
||||
robots: {
|
||||
index: true,
|
||||
follow: true,
|
||||
googleBot: {
|
||||
index: true,
|
||||
follow: true,
|
||||
"max-video-preview": -1,
|
||||
"max-image-preview": "large",
|
||||
"max-snippet": -1,
|
||||
},
|
||||
},
|
||||
openGraph: {
|
||||
title: "HookLab | Programme coaching TikTok Shop",
|
||||
description:
|
||||
"Lance ton business TikTok Shop en 8 semaines avec notre programme de coaching.",
|
||||
type: "website",
|
||||
locale: "fr_FR",
|
||||
url: BASE_URL,
|
||||
siteName: "HookLab",
|
||||
title:
|
||||
"HookLab | Formation TikTok Shop France - Deviens Cr\u00e9ateur Affili\u00e9",
|
||||
description:
|
||||
"Formation coaching TikTok Shop en 8 semaines. Deviens cr\u00e9ateur affili\u00e9 et g\u00e9n\u00e8re tes premiers revenus avec l\u2019affiliation TikTok Shop en France.",
|
||||
images: [
|
||||
{
|
||||
url: "/og-image.png",
|
||||
width: 1200,
|
||||
height: 630,
|
||||
alt: "HookLab - Formation TikTok Shop France",
|
||||
},
|
||||
],
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "HookLab | Formation TikTok Shop France",
|
||||
description:
|
||||
"Deviens cr\u00e9ateur affili\u00e9 TikTok Shop et g\u00e9n\u00e8re des revenus en 8 semaines de coaching.",
|
||||
images: ["/og-image.png"],
|
||||
},
|
||||
alternates: {
|
||||
canonical: BASE_URL,
|
||||
},
|
||||
verification: {
|
||||
google: process.env.GOOGLE_SITE_VERIFICATION || undefined,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -25,8 +78,62 @@ export default function RootLayout({
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
const jsonLdOrganization = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
name: "HookLab",
|
||||
url: BASE_URL,
|
||||
logo: `${BASE_URL}/logo.png`,
|
||||
description:
|
||||
"Programme de coaching TikTok Shop pour devenir cr\u00e9ateur affili\u00e9 en France.",
|
||||
contactPoint: {
|
||||
"@type": "ContactPoint",
|
||||
contactType: "customer service",
|
||||
availableLanguage: "French",
|
||||
},
|
||||
};
|
||||
|
||||
const jsonLdCourse = {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Course",
|
||||
name: "Formation TikTok Shop - HookLab",
|
||||
description:
|
||||
"Programme de coaching intensif de 8 semaines pour devenir cr\u00e9ateur affili\u00e9 TikTok Shop. Apprenez \u00e0 cr\u00e9er du contenu, s\u00e9lectionner des produits et g\u00e9n\u00e9rer des commissions.",
|
||||
provider: {
|
||||
"@type": "Organization",
|
||||
name: "HookLab",
|
||||
url: BASE_URL,
|
||||
},
|
||||
offers: {
|
||||
"@type": "Offer",
|
||||
price: "490",
|
||||
priceCurrency: "EUR",
|
||||
availability: "https://schema.org/LimitedAvailability",
|
||||
},
|
||||
hasCourseInstance: {
|
||||
"@type": "CourseInstance",
|
||||
courseMode: "online",
|
||||
duration: "P8W",
|
||||
inLanguage: "fr",
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLdOrganization),
|
||||
}}
|
||||
/>
|
||||
<script
|
||||
type="application/ld+json"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: JSON.stringify(jsonLdCourse),
|
||||
}}
|
||||
/>
|
||||
</head>
|
||||
<body className="antialiased">{children}</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
57
app/page.tsx
57
app/page.tsx
@@ -1,23 +1,72 @@
|
||||
import AnnouncementBar from "@/components/marketing/AnnouncementBar";
|
||||
import Navbar from "@/components/marketing/Navbar";
|
||||
import Hero from "@/components/marketing/Hero";
|
||||
import Testimonials from "@/components/marketing/Testimonials";
|
||||
import PersonaCards from "@/components/marketing/PersonaCards";
|
||||
import ResultsShowcase from "@/components/marketing/ResultsShowcase";
|
||||
import Method from "@/components/marketing/Method";
|
||||
import PersonaCards from "@/components/marketing/PersonaCards";
|
||||
import ComparisonTable from "@/components/marketing/ComparisonTable";
|
||||
import Testimonials from "@/components/marketing/Testimonials";
|
||||
import Pricing from "@/components/marketing/Pricing";
|
||||
import TrustBadges from "@/components/marketing/TrustBadges";
|
||||
import FAQ from "@/components/marketing/FAQ";
|
||||
import FinalCTA from "@/components/marketing/FinalCTA";
|
||||
import Footer from "@/components/marketing/Footer";
|
||||
import SocialProofTicker from "@/components/marketing/SocialProofTicker";
|
||||
import ExitIntentPopup from "@/components/marketing/ExitIntentPopup";
|
||||
import StickyMobileCTA from "@/components/marketing/StickyMobileCTA";
|
||||
|
||||
export default function LandingPage() {
|
||||
return (
|
||||
<main className="min-h-screen">
|
||||
{/* Top announcement bar */}
|
||||
<AnnouncementBar />
|
||||
|
||||
{/* Navigation */}
|
||||
<Navbar />
|
||||
|
||||
{/* Hero with SEO-optimized H1 */}
|
||||
<Hero />
|
||||
<Testimonials />
|
||||
<PersonaCards />
|
||||
|
||||
{/* Market opportunity + timeline */}
|
||||
<section id="resultats">
|
||||
<ResultsShowcase />
|
||||
</section>
|
||||
|
||||
{/* 3-step method */}
|
||||
<Method />
|
||||
|
||||
{/* Target personas */}
|
||||
<PersonaCards />
|
||||
|
||||
{/* Comparison table */}
|
||||
<ComparisonTable />
|
||||
|
||||
{/* Testimonials with disclaimer */}
|
||||
<Testimonials />
|
||||
|
||||
{/* Pricing with urgency */}
|
||||
<Pricing />
|
||||
|
||||
{/* Trust signals */}
|
||||
<TrustBadges />
|
||||
|
||||
{/* FAQ with structured data */}
|
||||
<FAQ />
|
||||
|
||||
{/* Final CTA */}
|
||||
<FinalCTA />
|
||||
|
||||
{/* Footer */}
|
||||
<Footer />
|
||||
|
||||
{/* Social proof notifications (bottom left) */}
|
||||
<SocialProofTicker />
|
||||
|
||||
{/* Exit intent popup (desktop only) */}
|
||||
<ExitIntentPopup />
|
||||
|
||||
{/* Sticky mobile CTA bar */}
|
||||
<StickyMobileCTA />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
16
app/robots.ts
Normal file
16
app/robots.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import type { MetadataRoute } from "next";
|
||||
|
||||
const BASE_URL = process.env.NEXT_PUBLIC_APP_URL || "https://hooklab.eu";
|
||||
|
||||
export default function robots(): MetadataRoute.Robots {
|
||||
return {
|
||||
rules: [
|
||||
{
|
||||
userAgent: "*",
|
||||
allow: "/",
|
||||
disallow: ["/admin/", "/api/", "/setup-admin/", "/dashboard/", "/profil/", "/formations/"],
|
||||
},
|
||||
],
|
||||
sitemap: `${BASE_URL}/sitemap.xml`,
|
||||
};
|
||||
}
|
||||
44
app/sitemap.ts
Normal file
44
app/sitemap.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import type { MetadataRoute } from "next";
|
||||
|
||||
const BASE_URL = process.env.NEXT_PUBLIC_APP_URL || "https://hooklab.eu";
|
||||
|
||||
export default function sitemap(): MetadataRoute.Sitemap {
|
||||
return [
|
||||
{
|
||||
url: BASE_URL,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: "weekly",
|
||||
priority: 1.0,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/candidature`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: "monthly",
|
||||
priority: 0.9,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/login`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: "monthly",
|
||||
priority: 0.3,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/mentions-legales`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: "yearly",
|
||||
priority: 0.2,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/cgv`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: "yearly",
|
||||
priority: 0.2,
|
||||
},
|
||||
{
|
||||
url: `${BASE_URL}/confidentialite`,
|
||||
lastModified: new Date(),
|
||||
changeFrequency: "yearly",
|
||||
priority: 0.2,
|
||||
},
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user