Explorar o código

feat: Implement SEO and sitemap improvements

gpt-engineer-app[bot] hai 1 mes
pai
achega
b521224b16
Modificáronse 4 ficheiros con 142 adicións e 7 borrados
  1. 41 7
      index.html
  2. 2 0
      public/robots.txt
  3. 27 0
      public/sitemap.xml
  4. 72 0
      src/components/SEO.tsx

+ 41 - 7
index.html

@@ -1,20 +1,54 @@
 <!DOCTYPE html>
-<html lang="en">
+<html lang="fr">
   <head>
     <meta charset="UTF-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <title>Feeds.Duhaz.fr</title>
-    <meta name="description" content="Votre flux d&#x27;informations personnalisé, simplifié." />
-    <meta name="author" content="Lovable" />
+    <title>Feeds.Duhaz.fr - Agrégateur de flux RSS personnalisé</title>
+    <meta name="description" content="Votre flux d'informations personnalisé, simplifié. Agrégez vos flux RSS, YouTube et actualités préférés en un seul endroit." />
+    <meta name="keywords" content="RSS, agrégateur, flux d'informations, actualités, news feed, personnalisé, YouTube, agrégateur RSS" />
+    <meta name="author" content="Duhaz.fr" />
+    <meta name="robots" content="index, follow" />
+    <meta name="theme-color" content="#1a1a1a" />
+    <link rel="canonical" href="https://feeds.duhaz.fr/" />
 
-    <meta property="og:title" content="Feeds.Duhaz.fr" />
-    <meta property="og:description" content="Votre flux d&#x27;informations personnalisé, simplifié." />
+    <!-- Open Graph / Facebook -->
     <meta property="og:type" content="website" />
+    <meta property="og:url" content="https://feeds.duhaz.fr/" />
+    <meta property="og:title" content="Feeds.Duhaz.fr - Agrégateur de flux RSS personnalisé" />
+    <meta property="og:description" content="Votre flux d'informations personnalisé, simplifié. Agrégez vos flux RSS, YouTube et actualités préférés en un seul endroit." />
     <meta property="og:image" content="https://feeds.duhaz.fr/static/favicon.ico" />
+    <meta property="og:site_name" content="Feeds.Duhaz.fr" />
+    <meta property="og:locale" content="fr_FR" />
 
+    <!-- Twitter -->
     <meta name="twitter:card" content="summary_large_image" />
-    <meta name="twitter:site" content="@lovable_dev" />
+    <meta name="twitter:url" content="https://feeds.duhaz.fr/" />
+    <meta name="twitter:title" content="Feeds.Duhaz.fr - Agrégateur de flux RSS personnalisé" />
+    <meta name="twitter:description" content="Votre flux d'informations personnalisé, simplifié. Agrégez vos flux RSS, YouTube et actualités préférés en un seul endroit." />
     <meta name="twitter:image" content="https://feeds.duhaz.fr/static/favicon.ico" />
+
+    <!-- Structured Data (JSON-LD) -->
+    <script type="application/ld+json">
+    {
+      "@context": "https://schema.org",
+      "@type": "WebApplication",
+      "name": "Feeds.Duhaz.fr",
+      "description": "Votre flux d'informations personnalisé, simplifié. Agrégez vos flux RSS, YouTube et actualités préférés en un seul endroit.",
+      "url": "https://feeds.duhaz.fr/",
+      "applicationCategory": "NewsApplication",
+      "operatingSystem": "Any",
+      "browserRequirements": "Requires JavaScript. Requires HTML5.",
+      "offers": {
+        "@type": "Offer",
+        "price": "0",
+        "priceCurrency": "EUR"
+      },
+      "author": {
+        "@type": "Organization",
+        "name": "Duhaz.fr"
+      }
+    }
+    </script>
   </head>
 
   <body>

+ 2 - 0
public/robots.txt

@@ -12,3 +12,5 @@ Allow: /
 
 User-agent: *
 Allow: /
+
+Sitemap: https://feeds.duhaz.fr/sitemap.xml

+ 27 - 0
public/sitemap.xml

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
+  <url>
+    <loc>https://feeds.duhaz.fr/</loc>
+    <lastmod>2025-01-20</lastmod>
+    <changefreq>daily</changefreq>
+    <priority>1.0</priority>
+  </url>
+  <url>
+    <loc>https://feeds.duhaz.fr/feeds</loc>
+    <lastmod>2025-01-20</lastmod>
+    <changefreq>weekly</changefreq>
+    <priority>0.8</priority>
+  </url>
+  <url>
+    <loc>https://feeds.duhaz.fr/pinned</loc>
+    <lastmod>2025-01-20</lastmod>
+    <changefreq>daily</changefreq>
+    <priority>0.7</priority>
+  </url>
+  <url>
+    <loc>https://feeds.duhaz.fr/auth</loc>
+    <lastmod>2025-01-20</lastmod>
+    <changefreq>monthly</changefreq>
+    <priority>0.5</priority>
+  </url>
+</urlset>

+ 72 - 0
src/components/SEO.tsx

@@ -0,0 +1,72 @@
+import { useEffect } from 'react';
+import { useLocation } from 'react-router-dom';
+
+interface SEOProps {
+  title?: string;
+  description?: string;
+  keywords?: string;
+  ogImage?: string;
+  canonical?: string;
+}
+
+/**
+ * SEO Component - Dynamically updates meta tags for each page
+ * Usage: <SEO title="Page Title" description="Page description" />
+ */
+export const SEO = ({ 
+  title = 'Feeds.Duhaz.fr - Agrégateur de flux RSS personnalisé',
+  description = "Votre flux d'informations personnalisé, simplifié. Agrégez vos flux RSS, YouTube et actualités préférés en un seul endroit.",
+  keywords = 'RSS, agrégateur, flux d\'informations, actualités, news feed, personnalisé, YouTube, agrégateur RSS',
+  ogImage = 'https://feeds.duhaz.fr/static/favicon.ico',
+  canonical
+}: SEOProps) => {
+  const location = useLocation();
+  const currentUrl = `https://feeds.duhaz.fr${location.pathname}`;
+  const canonicalUrl = canonical || currentUrl;
+
+  useEffect(() => {
+    // Update title
+    document.title = title;
+
+    // Update or create meta tags
+    const updateMetaTag = (property: string, content: string, isProperty = false) => {
+      const attribute = isProperty ? 'property' : 'name';
+      let element = document.querySelector(`meta[${attribute}="${property}"]`);
+      
+      if (!element) {
+        element = document.createElement('meta');
+        element.setAttribute(attribute, property);
+        document.head.appendChild(element);
+      }
+      
+      element.setAttribute('content', content);
+    };
+
+    // Update standard meta tags
+    updateMetaTag('description', description);
+    updateMetaTag('keywords', keywords);
+
+    // Update Open Graph tags
+    updateMetaTag('og:title', title, true);
+    updateMetaTag('og:description', description, true);
+    updateMetaTag('og:url', currentUrl, true);
+    updateMetaTag('og:image', ogImage, true);
+
+    // Update Twitter tags
+    updateMetaTag('twitter:title', title);
+    updateMetaTag('twitter:description', description);
+    updateMetaTag('twitter:url', currentUrl);
+    updateMetaTag('twitter:image', ogImage);
+
+    // Update canonical link
+    let canonicalLink = document.querySelector('link[rel="canonical"]');
+    if (!canonicalLink) {
+      canonicalLink = document.createElement('link');
+      canonicalLink.setAttribute('rel', 'canonical');
+      document.head.appendChild(canonicalLink);
+    }
+    canonicalLink.setAttribute('href', canonicalUrl);
+  }, [title, description, keywords, ogImage, currentUrl, canonicalUrl]);
+
+  return null;
+};