feat: add favicon, structured data & SEO optimization for Google sitelinks

- Add SVG favicon (H logo navy+orange) for all sizes (32, 180, 192, 512)
- Add web manifest (site.webmanifest) for PWA compatibility
- Add theme-color meta tag (#1B2A4A navy)
- Add 3 structured data schemas: LocalBusiness, WebSite, SiteNavigationElement
- WebSite schema enables Google to show site name + search box
- SiteNavigationElement signals main pages for sitelinks display
- Add canonical URLs to all pages (macon, paysagiste, plombier, legal pages)
- Add metadata to pages missing it (mentions-legales, confidentialite, cgv)
- Add candidature/layout.tsx for metadata on client component page
- Optimize sitemap with consistent BASE_URL and candidature/cgv pages
- Add telephone, email, opening hours to LocalBusiness schema

https://claude.ai/code/session_01V8YAjpqRQ3bfBYsABYsEgo
This commit is contained in:
Claude
2026-02-16 19:33:23 +00:00
parent 9cb49af079
commit a057f1901f
14 changed files with 225 additions and 25 deletions

View File

@@ -0,0 +1,18 @@
import type { Metadata } from "next";
export const metadata: Metadata = {
title: "Candidature Formation HookLab",
description:
"Postulez à la formation HookLab pour apprendre à créer des sites web professionnels pour artisans du bâtiment. Formation complète et accompagnement personnalisé.",
alternates: {
canonical: "https://hooklab.eu/candidature",
},
};
export default function CandidatureLayout({
children,
}: {
children: React.ReactNode;
}) {
return children;
}

View File

@@ -1,5 +1,15 @@
import type { Metadata } from "next";
import Link from "next/link";
export const metadata: Metadata = {
title: "Conditions Générales de Vente",
description:
"CGV de HookLab - Conditions générales de vente pour les prestations de création de sites internet et référencement.",
alternates: {
canonical: "https://hooklab.eu/cgv",
},
};
export default function CGV() {
return (
<main className="min-h-screen py-20 md:py-32">

View File

@@ -1,5 +1,15 @@
import type { Metadata } from "next";
import Link from "next/link";
export const metadata: Metadata = {
title: "Politique de Confidentialité",
description:
"Politique de confidentialité et protection des données personnelles du site HookLab.eu, conformément au RGPD.",
alternates: {
canonical: "https://hooklab.eu/confidentialite",
},
};
export default function Confidentialite() {
return (
<main className="min-h-screen py-20 md:py-32">

View File

@@ -25,6 +25,10 @@ export const metadata: Metadata = {
"site web Valenciennes",
"agence web Orchies",
"site pro artisan Nord",
"HookLab",
"hooklab.eu",
"cr\u00e9ation site internet Nord",
"site internet artisan 59",
],
authors: [{ name: "HookLab - Enguerrand Ozano" }],
creator: "HookLab",
@@ -40,6 +44,15 @@ export const metadata: Metadata = {
"max-snippet": -1,
},
},
icons: {
icon: [
{ url: "/favicon.svg", type: "image/svg+xml" },
],
apple: [
{ url: "/apple-touch-icon.svg", type: "image/svg+xml", sizes: "180x180" },
],
},
manifest: "/site.webmanifest",
openGraph: {
type: "website",
locale: "fr_FR",
@@ -78,20 +91,25 @@ export default function RootLayout({
}: Readonly<{
children: React.ReactNode;
}>) {
// Schema.org LocalBusiness
const jsonLdOrganization = {
"@context": "https://schema.org",
"@type": "LocalBusiness",
"@id": `${BASE_URL}/#organization`,
name: "HookLab",
url: BASE_URL,
logo: `${BASE_URL}/logo.png`,
logo: `${BASE_URL}/icon-512.svg`,
image: `${BASE_URL}/og-image.png`,
description:
"Agence web sp\u00e9cialis\u00e9e dans la cr\u00e9ation de sites et la visibilit\u00e9 Google pour les artisans du b\u00e2timent dans le Nord.",
telephone: "+33604408157",
email: "contact@hooklab.eu",
address: {
"@type": "PostalAddress",
streetAddress: "35 rue Mo\u00efse Lambert",
addressLocality: "Flines-lez-Raches",
postalCode: "59148",
addressRegion: "Nord",
addressRegion: "Hauts-de-France",
addressCountry: "FR",
},
geo: {
@@ -105,22 +123,104 @@ export default function RootLayout({
{ "@type": "City", name: "Valenciennes" },
{ "@type": "City", name: "Arleux" },
{ "@type": "City", name: "Flines-lez-Raches" },
{ "@type": "City", name: "Saint-Amand-les-Eaux" },
{ "@type": "City", name: "Denain" },
],
priceRange: "$$",
openingHoursSpecification: {
"@type": "OpeningHoursSpecification",
dayOfWeek: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
opens: "09:00",
closes: "18:00",
},
contactPoint: {
"@type": "ContactPoint",
telephone: "+33604408157",
contactType: "customer service",
availableLanguage: "French",
},
sameAs: [],
};
// Schema.org WebSite - aide Google à afficher le nom du site et les sitelinks
const jsonLdWebSite = {
"@context": "https://schema.org",
"@type": "WebSite",
"@id": `${BASE_URL}/#website`,
name: "HookLab",
alternateName: "HookLab Tech",
url: BASE_URL,
description:
"Cr\u00e9ation de sites internet et r\u00e9f\u00e9rencement Google pour artisans du b\u00e2timent dans le Nord (59).",
publisher: {
"@id": `${BASE_URL}/#organization`,
},
inLanguage: "fr-FR",
potentialAction: {
"@type": "SearchAction",
target: {
"@type": "EntryPoint",
urlTemplate: `${BASE_URL}/?q={search_term_string}`,
},
"query-input": "required name=search_term_string",
},
};
// Schema.org SiteNavigationElement - signale les pages principales à Google
const jsonLdNavigation = {
"@context": "https://schema.org",
"@type": "SiteNavigationElement",
"@id": `${BASE_URL}/#navigation`,
name: "Navigation principale",
hasPart: [
{
"@type": "WebPage",
name: "Accueil",
url: BASE_URL,
},
{
"@type": "WebPage",
name: "D\u00e9mo Ma\u00e7on / Couvreur",
url: `${BASE_URL}/macon`,
},
{
"@type": "WebPage",
name: "D\u00e9mo Paysagiste",
url: `${BASE_URL}/paysagiste`,
},
{
"@type": "WebPage",
name: "D\u00e9mo Plombier",
url: `${BASE_URL}/plombier`,
},
{
"@type": "WebPage",
name: "Candidature Formation",
url: `${BASE_URL}/candidature`,
},
{
"@type": "WebPage",
name: "Mentions L\u00e9gales",
url: `${BASE_URL}/mentions-legales`,
},
{
"@type": "WebPage",
name: "Politique de Confidentialit\u00e9",
url: `${BASE_URL}/confidentialite`,
},
],
};
return (
<html lang="fr">
<head>
<meta name="theme-color" content="#1B2A4A" />
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/apple-touch-icon.svg" />
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify(jsonLdOrganization),
__html: JSON.stringify([jsonLdOrganization, jsonLdWebSite, jsonLdNavigation]),
}}
/>
</head>

View File

@@ -4,9 +4,12 @@ import Button from "@/components/ui/Button";
import MaconClient from "./MaconClient";
export const metadata: Metadata = {
title: "Démo Site Maçon / Couvreur - L'Expertise Solide | HookLab",
title: "Démo Site Maçon / Couvreur - L'Expertise Solide",
description:
"Modèle de site HookLab pour maçons, couvreurs et charpentiers. Slider Avant/Après interactif, badges garanties, formulaire intelligent, bouton urgence.",
alternates: {
canonical: "https://hooklab.eu/macon",
},
};
export default function MaconDemo() {

View File

@@ -1,5 +1,15 @@
import type { Metadata } from "next";
import Link from "next/link";
export const metadata: Metadata = {
title: "Mentions Légales",
description:
"Mentions légales du site HookLab.eu - Agence web pour artisans du bâtiment à Flines-lez-Raches (59). SIREN 994 538 932.",
alternates: {
canonical: "https://hooklab.eu/mentions-legales",
},
};
export default function MentionsLegales() {
return (
<main className="min-h-screen py-20 md:py-32 bg-dark-bg">

View File

@@ -4,9 +4,12 @@ import Button from "@/components/ui/Button";
import PaysagisteClient from "./PaysagisteClient";
export const metadata: Metadata = {
title: "Démo Site Paysagiste / Peintre - L'Artisan Créateur | HookLab",
title: "Démo Site Paysagiste / Peintre - L'Artisan Créateur",
description:
"Modèle de site HookLab pour paysagistes, peintres et décorateurs. Galerie filtrable, saisonnalité intelligente, bouton WhatsApp flottant.",
alternates: {
canonical: "https://hooklab.eu/paysagiste",
},
};
const realisations = [

View File

@@ -4,9 +4,12 @@ import Button from "@/components/ui/Button";
import PlombierClient from "./PlombierClient";
export const metadata: Metadata = {
title: "Démo Site Plombier / Électricien - L'Intervention Éclair | HookLab",
title: "Démo Site Plombier / Électricien - L'Intervention Éclair",
description:
"Modèle de site HookLab pour plombiers, électriciens et serruriers. Bouton dappel sticky, diagnostic en ligne, zone dintervention, tarifs clairs.",
"Modèle de site HookLab pour plombiers, électriciens et serruriers. Bouton d'appel sticky, diagnostic en ligne, zone d'intervention, tarifs clairs.",
alternates: {
canonical: "https://hooklab.eu/plombier",
},
};
const tarifs = [

View File

@@ -1,12 +1,12 @@
import type { MetadataRoute } from "next";
const BASE_URL = "https://www.hooklab.eu";
const BASE_URL = process.env.NEXT_PUBLIC_APP_URL || "https://hooklab.eu";
export default function sitemap(): MetadataRoute.Sitemap {
const now = new Date();
return [
// Page d'accueil - priorit\u00e9 max
// Page d'accueil - priorité max
{
url: BASE_URL,
lastModified: now,
@@ -14,7 +14,7 @@ export default function sitemap(): MetadataRoute.Sitemap {
priority: 1.0,
},
// D\u00e9mos m\u00e9tiers - pages strat\u00e9giques SEO
// Démos métiers - pages stratégiques SEO
{
url: `${BASE_URL}/macon`,
lastModified: now,
@@ -34,43 +34,45 @@ export default function sitemap(): MetadataRoute.Sitemap {
priority: 0.9,
},
// Candidature - page importante
{
url: `${BASE_URL}/candidature`,
lastModified: now,
changeFrequency: "monthly",
priority: 0.8,
},
// Pages SEO locales - site internet artisan + ville
// Douai
{
url: `${BASE_URL}/site-internet-artisan-douai`,
lastModified: now,
changeFrequency: "monthly",
priority: 0.8,
},
// Orchies
{
url: `${BASE_URL}/site-internet-artisan-orchies`,
lastModified: now,
changeFrequency: "monthly",
priority: 0.8,
},
// Valenciennes
{
url: `${BASE_URL}/site-internet-artisan-valenciennes`,
lastModified: now,
changeFrequency: "monthly",
priority: 0.8,
},
// Saint-Amand-les-Eaux
{
url: `${BASE_URL}/site-internet-artisan-saint-amand-les-eaux`,
lastModified: now,
changeFrequency: "monthly",
priority: 0.8,
},
// Arleux
{
url: `${BASE_URL}/site-internet-artisan-arleux`,
lastModified: now,
changeFrequency: "monthly",
priority: 0.8,
},
// Denain
{
url: `${BASE_URL}/site-internet-artisan-denain`,
lastModified: now,
@@ -78,24 +80,24 @@ export default function sitemap(): MetadataRoute.Sitemap {
priority: 0.8,
},
// L\u00e9gal
// Légal
{
url: `${BASE_URL}/cgv`,
lastModified: now,
changeFrequency: "yearly",
priority: 0.3,
},
{
url: `${BASE_URL}/mentions-legales`,
lastModified: now,
changeFrequency: "yearly",
priority: 0.2,
priority: 0.3,
},
{
url: `${BASE_URL}/confidentialite`,
lastModified: now,
changeFrequency: "yearly",
priority: 0.2,
},
{
url: `${BASE_URL}/plan-du-site`,
lastModified: now,
changeFrequency: "yearly",
priority: 0.2,
priority: 0.3,
},
];
}

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 180 180" width="180" height="180">
<rect width="180" height="180" rx="32" fill="#1B2A4A"/>
<text x="90" y="130" text-anchor="middle" font-family="Inter, Arial, sans-serif" font-weight="800" font-size="120" fill="#FFFFFF">H</text>
<rect x="105" y="35" width="22" height="22" rx="5" fill="#E8772E"/>
</svg>

After

Width:  |  Height:  |  Size: 364 B

5
public/favicon.svg Normal file
View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" width="32" height="32">
<rect width="32" height="32" rx="6" fill="#1B2A4A"/>
<text x="16" y="23" text-anchor="middle" font-family="Inter, Arial, sans-serif" font-weight="800" font-size="20" fill="#FFFFFF">H</text>
<rect x="18" y="7" width="4" height="4" rx="1" fill="#E8772E"/>
</svg>

After

Width:  |  Height:  |  Size: 351 B

5
public/icon-192.svg Normal file
View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 192" width="192" height="192">
<rect width="192" height="192" rx="32" fill="#1B2A4A"/>
<text x="96" y="137" text-anchor="middle" font-family="Inter, Arial, sans-serif" font-weight="800" font-size="128" fill="#FFFFFF">H</text>
<rect x="112" y="37" width="24" height="24" rx="5" fill="#E8772E"/>
</svg>

After

Width:  |  Height:  |  Size: 364 B

5
public/icon-512.svg Normal file
View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
<rect width="512" height="512" rx="64" fill="#1B2A4A"/>
<text x="256" y="365" text-anchor="middle" font-family="Inter, Arial, sans-serif" font-weight="800" font-size="340" fill="#FFFFFF">H</text>
<rect x="295" y="95" width="60" height="60" rx="12" fill="#E8772E"/>
</svg>

After

Width:  |  Height:  |  Size: 366 B

21
public/site.webmanifest Normal file
View File

@@ -0,0 +1,21 @@
{
"name": "HookLab - Sites web pour artisans du Nord",
"short_name": "HookLab",
"description": "Création de sites internet et référencement Google pour artisans du bâtiment dans le Nord (59).",
"start_url": "/",
"display": "standalone",
"background_color": "#F7F8FA",
"theme_color": "#1B2A4A",
"icons": [
{
"src": "/icon-192.svg",
"sizes": "192x192",
"type": "image/svg+xml"
},
{
"src": "/icon-512.svg",
"sizes": "512x512",
"type": "image/svg+xml"
}
]
}