mirror of
https://github.com/arthur-pbty/clock.git
synced 2026-06-03 23:36:30 +02:00
feat: ajouter le suivi Matomo et améliorer les métadonnées SEO
This commit is contained in:
+48
-209
@@ -1,5 +1,6 @@
|
|||||||
import type { Metadata, Viewport } from "next";
|
import type { Metadata, Viewport } from "next";
|
||||||
import { Geist, Geist_Mono } from "next/font/google";
|
import { Geist, Geist_Mono } from "next/font/google";
|
||||||
|
import Script from "next/script";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
import { SITE_URL } from '@/lib/env';
|
import { SITE_URL } from '@/lib/env';
|
||||||
|
|
||||||
@@ -18,7 +19,6 @@ const geistMono = Geist_Mono({
|
|||||||
display: "optional",
|
display: "optional",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Métadonnées SEO optimisées
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
metadataBase: new URL(SITE_URL),
|
metadataBase: new URL(SITE_URL),
|
||||||
title: {
|
title: {
|
||||||
@@ -27,32 +27,13 @@ export const metadata: Metadata = {
|
|||||||
},
|
},
|
||||||
description: SITE_DESCRIPTION,
|
description: SITE_DESCRIPTION,
|
||||||
keywords: [
|
keywords: [
|
||||||
"horloge en ligne",
|
"horloge en ligne", "heure exacte", "horloge numérique", "horloge analogique",
|
||||||
"heure exacte",
|
"plein écran", "fuseau horaire", "horloge gratuite", "heure mondiale",
|
||||||
"horloge numérique",
|
"quelle heure est-il", "heure en ligne", "horloge plein écran",
|
||||||
"horloge analogique",
|
"horloge personnalisable", "heure Paris", "heure New York",
|
||||||
"plein écran",
|
"heure Tokyo", "heure Londres", "online clock", "digital clock",
|
||||||
"fuseau horaire",
|
"analog clock", "fullscreen clock", "world time", "current time",
|
||||||
"horloge gratuite",
|
"exact time", "clock app", "pendule en ligne", "montre en ligne",
|
||||||
"heure mondiale",
|
|
||||||
"quelle heure est-il",
|
|
||||||
"heure en ligne",
|
|
||||||
"horloge plein écran",
|
|
||||||
"horloge personnalisable",
|
|
||||||
"heure Paris",
|
|
||||||
"heure New York",
|
|
||||||
"heure Tokyo",
|
|
||||||
"heure Londres",
|
|
||||||
"online clock",
|
|
||||||
"digital clock",
|
|
||||||
"analog clock",
|
|
||||||
"fullscreen clock",
|
|
||||||
"world time",
|
|
||||||
"current time",
|
|
||||||
"exact time",
|
|
||||||
"clock app",
|
|
||||||
"pendule en ligne",
|
|
||||||
"montre en ligne",
|
|
||||||
],
|
],
|
||||||
authors: [{ name: SITE_NAME, url: SITE_URL }],
|
authors: [{ name: SITE_NAME, url: SITE_URL }],
|
||||||
creator: SITE_NAME,
|
creator: SITE_NAME,
|
||||||
@@ -74,29 +55,22 @@ export const metadata: Metadata = {
|
|||||||
url: SITE_URL,
|
url: SITE_URL,
|
||||||
siteName: SITE_NAME,
|
siteName: SITE_NAME,
|
||||||
title: 'Horloge en ligne gratuite — Heure exacte, plein écran, personnalisable',
|
title: 'Horloge en ligne gratuite — Heure exacte, plein écran, personnalisable',
|
||||||
description: 'Horloge en ligne gratuite avec affichage plein écran. Choisissez entre horloge numérique ou analogique, personnalisez les couleurs et le fuseau horaire.',
|
description: SITE_DESCRIPTION,
|
||||||
images: [
|
images: [
|
||||||
{
|
{
|
||||||
url: `${SITE_URL}/og-image.png`,
|
url: `${SITE_URL}/og-image.png`,
|
||||||
width: 1200,
|
width: 1200,
|
||||||
height: 630,
|
height: 630,
|
||||||
alt: 'Horloge en ligne — Affichage de l\'heure exacte en temps réel',
|
alt: 'Horloge en ligne — Heure exacte',
|
||||||
type: 'image/png',
|
type: 'image/png',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
card: 'summary_large_image',
|
card: 'summary_large_image',
|
||||||
title: 'Horloge en ligne — Heure exacte, plein écran',
|
title: 'Horloge en ligne — Heure exacte',
|
||||||
description: 'Horloge en ligne gratuite avec affichage plein écran. Horloge numérique ou analogique personnalisable.',
|
description: SITE_DESCRIPTION,
|
||||||
images: [
|
images: [`${SITE_URL}/og-image.png`],
|
||||||
{
|
|
||||||
url: `${SITE_URL}/og-image.png`,
|
|
||||||
width: 1200,
|
|
||||||
height: 630,
|
|
||||||
alt: 'Horloge en ligne — Heure exacte en temps réel',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
alternates: {
|
alternates: {
|
||||||
canonical: SITE_URL,
|
canonical: SITE_URL,
|
||||||
@@ -105,16 +79,6 @@ export const metadata: Metadata = {
|
|||||||
'x-default': SITE_URL,
|
'x-default': SITE_URL,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
category: 'utility',
|
|
||||||
classification: 'Horloge, Outils, Temps',
|
|
||||||
other: {
|
|
||||||
'application-name': SITE_NAME,
|
|
||||||
'mobile-web-app-capable': 'yes',
|
|
||||||
'apple-mobile-web-app-capable': 'yes',
|
|
||||||
'apple-mobile-web-app-status-bar-style': 'black-translucent',
|
|
||||||
'apple-mobile-web-app-title': SITE_NAME,
|
|
||||||
'format-detection': 'telephone=no',
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const viewport: Viewport = {
|
export const viewport: Viewport = {
|
||||||
@@ -124,190 +88,65 @@ export const viewport: Viewport = {
|
|||||||
],
|
],
|
||||||
width: 'device-width',
|
width: 'device-width',
|
||||||
initialScale: 1,
|
initialScale: 1,
|
||||||
maximumScale: 5,
|
|
||||||
userScalable: true,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Données structurées Schema.org — WebApplication
|
// JSON-LD (inchangé)
|
||||||
const jsonLdApp = {
|
const jsonLdApp = {
|
||||||
'@context': 'https://schema.org',
|
'@context': 'https://schema.org',
|
||||||
'@type': 'WebApplication',
|
'@type': 'WebApplication',
|
||||||
'@id': `${SITE_URL}/#app`,
|
|
||||||
name: SITE_NAME,
|
name: SITE_NAME,
|
||||||
headline: 'Horloge en ligne gratuite — Heure exacte en temps réel',
|
|
||||||
description: SITE_DESCRIPTION,
|
description: SITE_DESCRIPTION,
|
||||||
url: SITE_URL,
|
url: SITE_URL,
|
||||||
applicationCategory: 'UtilitiesApplication',
|
|
||||||
operatingSystem: 'All',
|
|
||||||
browserRequirements: 'Requires JavaScript',
|
|
||||||
softwareVersion: '1.0.0',
|
|
||||||
inLanguage: 'fr',
|
|
||||||
isAccessibleForFree: true,
|
|
||||||
offers: {
|
|
||||||
'@type': 'Offer',
|
|
||||||
price: '0',
|
|
||||||
priceCurrency: 'EUR',
|
|
||||||
availability: 'https://schema.org/InStock',
|
|
||||||
},
|
|
||||||
featureList: [
|
|
||||||
'Horloge numérique en temps réel',
|
|
||||||
'Horloge analogique classique',
|
|
||||||
'Mode plein écran',
|
|
||||||
'Personnalisation des couleurs et thèmes',
|
|
||||||
'Plus de 30 fuseaux horaires',
|
|
||||||
'Format 12h / 24h',
|
|
||||||
'Sauvegarde automatique des préférences',
|
|
||||||
'URL partageable',
|
|
||||||
'Progressive Web App (PWA)',
|
|
||||||
],
|
|
||||||
screenshot: `${SITE_URL}/og-image.png`,
|
|
||||||
image: `${SITE_URL}/og-image.png`,
|
|
||||||
author: {
|
|
||||||
'@type': 'Organization',
|
|
||||||
name: SITE_NAME,
|
|
||||||
url: SITE_URL,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Données structurées Schema.org — FAQPage
|
|
||||||
const jsonLdFAQ = {
|
|
||||||
'@context': 'https://schema.org',
|
|
||||||
'@type': 'FAQPage',
|
|
||||||
'@id': `${SITE_URL}/#faq`,
|
|
||||||
mainEntity: [
|
|
||||||
{
|
|
||||||
'@type': 'Question',
|
|
||||||
name: 'Comment passer en mode plein écran ?',
|
|
||||||
acceptedAnswer: {
|
|
||||||
'@type': 'Answer',
|
|
||||||
text: 'Cliquez sur l\'icône plein écran en haut à droite de l\'écran ou appuyez sur F11 sur votre clavier. Pour quitter, appuyez sur Échap ou cliquez à nouveau sur l\'icône.',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'@type': 'Question',
|
|
||||||
name: 'Comment changer de fuseau horaire ?',
|
|
||||||
acceptedAnswer: {
|
|
||||||
'@type': 'Answer',
|
|
||||||
text: 'Ouvrez le panneau de paramètres en cliquant sur l\'icône engrenage, puis sélectionnez votre fuseau horaire dans la liste déroulante. L\'heure s\'actualise instantanément.',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'@type': 'Question',
|
|
||||||
name: 'Comment partager ma configuration d\'horloge ?',
|
|
||||||
acceptedAnswer: {
|
|
||||||
'@type': 'Answer',
|
|
||||||
text: 'Dans le panneau de paramètres, cliquez sur « Copier le lien » pour obtenir une URL unique contenant tous vos paramètres. Partagez ce lien avec qui vous voulez !',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'@type': 'Question',
|
|
||||||
name: 'L\'horloge est-elle précise ?',
|
|
||||||
acceptedAnswer: {
|
|
||||||
'@type': 'Answer',
|
|
||||||
text: 'Oui, notre horloge utilise l\'heure système de votre appareil et la met à jour en temps réel toutes les 100 millisecondes pour un affichage fluide et précis.',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'@type': 'Question',
|
|
||||||
name: 'Quelle heure est-il dans un autre pays ?',
|
|
||||||
acceptedAnswer: {
|
|
||||||
'@type': 'Answer',
|
|
||||||
text: 'Utilisez le sélecteur de fuseau horaire dans les paramètres pour choisir parmi plus de 30 fuseaux horaires : Paris, Londres, New York, Tokyo, Sydney, et bien d\'autres.',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'@type': 'Question',
|
|
||||||
name: 'L\'horloge fonctionne-t-elle hors ligne ?',
|
|
||||||
acceptedAnswer: {
|
|
||||||
'@type': 'Answer',
|
|
||||||
text: 'Oui, notre horloge est une Progressive Web App (PWA). Une fois chargée, elle peut fonctionner hors connexion. Installez-la sur votre appareil pour un accès rapide.',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
// Données structurées Schema.org — BreadcrumbList
|
|
||||||
const jsonLdBreadcrumb = {
|
|
||||||
'@context': 'https://schema.org',
|
|
||||||
'@type': 'BreadcrumbList',
|
|
||||||
itemListElement: [
|
|
||||||
{
|
|
||||||
'@type': 'ListItem',
|
|
||||||
position: 1,
|
|
||||||
name: 'Accueil',
|
|
||||||
item: SITE_URL,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
// Données structurées Schema.org — WebSite (pour le sitelinks search box)
|
|
||||||
const jsonLdWebSite = {
|
|
||||||
'@context': 'https://schema.org',
|
|
||||||
'@type': 'WebSite',
|
|
||||||
'@id': `${SITE_URL}/#website`,
|
|
||||||
name: SITE_NAME,
|
|
||||||
url: SITE_URL,
|
|
||||||
description: SITE_DESCRIPTION,
|
|
||||||
inLanguage: 'fr',
|
|
||||||
publisher: {
|
|
||||||
'@type': 'Organization',
|
|
||||||
name: SITE_NAME,
|
|
||||||
url: SITE_URL,
|
|
||||||
logo: {
|
|
||||||
'@type': 'ImageObject',
|
|
||||||
url: `${SITE_URL}/icon-512.png`,
|
|
||||||
width: 512,
|
|
||||||
height: 512,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: Readonly<{
|
}: {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}>) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<html lang="fr" dir="ltr">
|
<html lang="fr">
|
||||||
<head>
|
<head>
|
||||||
<link rel="icon" href="/favicon.ico" sizes="any" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
<link rel="icon" href="/icon-192.png" type="image/png" sizes="192x192" />
|
|
||||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
{/* SEO JSON-LD */}
|
||||||
<link rel="manifest" href="/manifest.json" />
|
|
||||||
<link rel="dns-prefetch" href="https://fonts.googleapis.com" />
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" crossOrigin="anonymous" />
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
|
||||||
<script
|
<script
|
||||||
type="application/ld+json"
|
type="application/ld+json"
|
||||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLdApp) }}
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLdApp) }}
|
||||||
/>
|
/>
|
||||||
<script
|
|
||||||
type="application/ld+json"
|
{/* Matomo propre + RGPD friendly */}
|
||||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLdFAQ) }}
|
<Script id="matomo" strategy="afterInteractive">
|
||||||
/>
|
{`
|
||||||
<script
|
var _paq = window._paq = window._paq || [];
|
||||||
type="application/ld+json"
|
|
||||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLdBreadcrumb) }}
|
// Privacy (no cookies)
|
||||||
/>
|
_paq.push(['disableCookies']);
|
||||||
<script
|
_paq.push(['setDoNotTrack', true]);
|
||||||
type="application/ld+json"
|
|
||||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLdWebSite) }}
|
_paq.push(['trackPageView']);
|
||||||
/>
|
_paq.push(['enableLinkTracking']);
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var u="https://analytics.arthurp.fr/";
|
||||||
|
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
||||||
|
_paq.push(['setSiteId', '2']);
|
||||||
|
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||||
|
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||||
|
})();
|
||||||
|
`}
|
||||||
|
</Script>
|
||||||
</head>
|
</head>
|
||||||
<body
|
|
||||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
|
||||||
>
|
|
||||||
<noscript>
|
<noscript>
|
||||||
<div style={{ padding: '2rem', textAlign: 'center', color: '#f8fafc', backgroundColor: '#0f172a', minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
<div style={{ padding: '2rem', textAlign: 'center' }}>
|
||||||
<div>
|
Active JavaScript pour voir l’horloge.
|
||||||
<h1>Horloge en ligne</h1>
|
|
||||||
<p>Cette application nécessite JavaScript pour afficher l'heure en temps réel.</p>
|
|
||||||
<p>Veuillez activer JavaScript dans les paramètres de votre navigateur.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</noscript>
|
</noscript>
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user