← Retour au lexique
⚙️ SEO Technique

Sitemap XML

Fichier XML listant les URLs importantes d'un site web pour faciliter leur découverte et indexation par les moteurs de recherche.

Définition

Un sitemap XML est un fichier structuré au format XML qui répertorie les URLs importantes d’un site web, accompagnées de métadonnées comme la date de dernière modification, la fréquence de mise à jour et la priorité relative. Ce fichier aide les robots des moteurs de recherche à découvrir et indexer efficacement le contenu d’un site.

Structure et syntaxe

Format XML standard

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  
  <url>
    <loc>https://example.com/</loc>
    <lastmod>2024-01-20T10:30:00Z</lastmod>
    <changefreq>weekly</changefreq>
    <priority>1.0</priority>
  </url>
  
  <url>
    <loc>https://example.com/about</loc>
    <lastmod>2024-01-15T14:20:00Z</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.8</priority>
  </url>
  
  <url>
    <loc>https://example.com/blog/article-seo</loc>
    <lastmod>2024-01-22T09:15:00Z</lastmod>
    <changefreq>never</changefreq>
    <priority>0.6</priority>
  </url>
  
</urlset>

Balises obligatoires et optionnelles

# Structure sitemap XML
sitemap_elements = {
    'required': {
        'urlset': 'Élément racine avec namespace',
        'url': 'Container pour chaque URL',
        'loc': 'URL complète de la page'
    },
    
    'optional': {
        'lastmod': 'Date dernière modification (ISO 8601)',
        'changefreq': 'Fréquence mise à jour estimée',
        'priority': 'Priorité relative (0.0 à 1.0)'
    },
    
    'changefreq_values': [
        'always',   # Modifié à chaque accès
        'hourly',   # Toutes les heures
        'daily',    # Quotidien
        'weekly',   # Hebdomadaire
        'monthly',  # Mensuel
        'yearly',   # Annuel
        'never'     # Archivé, jamais modifié
    ]
}

Types de sitemaps

Sitemap général

<!-- Sitemap principal pour contenu standard -->
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://site.com/</loc>
    <priority>1.0</priority>
    <changefreq>weekly</changefreq>
  </url>
  <url>
    <loc>https://site.com/services/</loc>
    <priority>0.9</priority>
    <changefreq>monthly</changefreq>
  </url>
</urlset>

Sitemap images

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
  
  <url>
    <loc>https://site.com/galerie/</loc>
    <image:image>
      <image:loc>https://site.com/images/photo1.jpg</image:loc>
      <image:caption>Description de l'image</image:caption>
      <image:title>Titre de l'image</image:title>
    </image:image>
    <image:image>
      <image:loc>https://site.com/images/photo2.jpg</image:loc>
      <image:caption>Autre description</image:caption>
    </image:image>
  </url>
  
</urlset>

Sitemap vidéos

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
  
  <url>
    <loc>https://site.com/video-page/</loc>
    <video:video>
      <video:thumbnail_loc>https://site.com/thumb.jpg</video:thumbnail_loc>
      <video:title>Titre de la vidéo</video:title>
      <video:description>Description détaillée</video:description>
      <video:content_loc>https://site.com/video.mp4</video:content_loc>
      <video:duration>600</video:duration>
      <video:publication_date>2024-01-20T10:00:00Z</video:publication_date>
    </video:video>
  </url>
  
</urlset>

Génération automatique

Script PHP basique

<?php
function generateSitemap($urls) {
    $xml = new DOMDocument('1.0', 'UTF-8');
    $xml->formatOutput = true;
    
    // Élément racine
    $urlset = $xml->createElement('urlset');
    $urlset->setAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
    $xml->appendChild($urlset);
    
    foreach ($urls as $urlData) {
        $url = $xml->createElement('url');
        
        // URL obligatoire
        $loc = $xml->createElement('loc', htmlspecialchars($urlData['loc']));
        $url->appendChild($loc);
        
        // Métadonnées optionnelles
        if (isset($urlData['lastmod'])) {
            $lastmod = $xml->createElement('lastmod', $urlData['lastmod']);
            $url->appendChild($lastmod);
        }
        
        if (isset($urlData['changefreq'])) {
            $changefreq = $xml->createElement('changefreq', $urlData['changefreq']);
            $url->appendChild($changefreq);
        }
        
        if (isset($urlData['priority'])) {
            $priority = $xml->createElement('priority', $urlData['priority']);
            $url->appendChild($priority);
        }
        
        $urlset->appendChild($url);
    }
    
    return $xml->saveXML();
}

// Utilisation
$urls = [
    [
        'loc' => 'https://site.com/',
        'lastmod' => date('c'),
        'changefreq' => 'weekly',
        'priority' => '1.0'
    ],
    [
        'loc' => 'https://site.com/about/',
        'lastmod' => '2024-01-15T10:00:00Z',
        'changefreq' => 'monthly',
        'priority' => '0.8'
    ]
];

$sitemapXML = generateSitemap($urls);
file_put_contents('sitemap.xml', $sitemapXML);
?>

Automatisation CMS

# Génération sitemap WordPress
def generate_wordpress_sitemap():
    """
    Génère sitemap XML pour WordPress via API
    """
    sitemap_config = {
        'post_types': ['post', 'page', 'product'],
        'taxonomies': ['category', 'product_cat'],
        'exclude_ids': [1, 5, 12],  # Pages privées
        'max_urls': 50000,
        'image_sitemap': True,
        'news_sitemap': True
    }
    
    urls = []
    
    # Pages et articles
    for post_type in sitemap_config['post_types']:
        posts = wp_query({
            'post_type': post_type,
            'post_status': 'publish',
            'posts_per_page': -1,
            'exclude': sitemap_config['exclude_ids']
        })
        
        for post in posts:
            urls.append({
                'loc': post['permalink'],
                'lastmod': post['modified_date'],
                'changefreq': get_changefreq(post_type),
                'priority': get_priority(post_type, post['meta'])
            })
    
    return build_xml_sitemap(urls)

def get_changefreq(post_type):
    """
    Détermine fréquence selon type contenu
    """
    frequencies = {
        'post': 'monthly',
        'page': 'yearly', 
        'product': 'weekly'
    }
    return frequencies.get(post_type, 'monthly')

Index de sitemaps

Sitemap index

<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  
  <sitemap>
    <loc>https://site.com/sitemap-posts.xml</loc>
    <lastmod>2024-01-20T10:00:00Z</lastmod>
  </sitemap>
  
  <sitemap>
    <loc>https://site.com/sitemap-pages.xml</loc>
    <lastmod>2024-01-15T14:30:00Z</lastmod>
  </sitemap>
  
  <sitemap>
    <loc>https://site.com/sitemap-images.xml</loc>
    <lastmod>2024-01-22T09:00:00Z</lastmod>
  </sitemap>
  
  <sitemap>
    <loc>https://site.com/sitemap-videos.xml</loc>
    <lastmod>2024-01-18T16:45:00Z</lastmod>
  </sitemap>
  
</sitemapindex>

Organisation multi-sitemaps

// Structure optimale grands sites
const sitemapOrganization = {
    main_index: 'sitemap.xml',
    
    sub_sitemaps: {
        content_type: [
            'sitemap-posts.xml',
            'sitemap-pages.xml', 
            'sitemap-products.xml'
        ],
        
        media: [
            'sitemap-images.xml',
            'sitemap-videos.xml'
        ],
        
        time_based: [
            'sitemap-2024.xml',
            'sitemap-2023.xml'
        ],
        
        language: [
            'sitemap-fr.xml',
            'sitemap-en.xml'
        ]
    },
    
    limits: {
        max_urls_per_sitemap: 50000,
        max_file_size: '50MB',
        max_sitemaps_in_index: 50000
    }
};

Optimisation et bonnes pratiques

Priorisation URLs

# Stratégie priorités sitemap
def calculate_url_priority(page_data):
    """
    Calcule priorité basée sur importance business
    """
    base_priority = 0.5
    
    # Type de page
    page_type_weights = {
        'homepage': 1.0,
        'main_category': 0.9,
        'sub_category': 0.8,
        'product': 0.7,
        'blog_post': 0.6,
        'static_page': 0.5
    }
    
    priority = page_type_weights.get(page_data['type'], 0.5)
    
    # Ajustements basés sur métriques
    if page_data.get('monthly_traffic', 0) > 1000:
        priority += 0.1
    
    if page_data.get('conversion_rate', 0) > 0.05:
        priority += 0.1
    
    if page_data.get('last_updated_days', 365) < 30:
        priority += 0.05
    
    # Limiter entre 0.0 et 1.0
    return min(1.0, max(0.0, priority))

Mise à jour automatique

# Système mise à jour sitemap
def auto_update_sitemap():
    """
    Met à jour sitemap selon modifications contenu
    """
    update_triggers = {
        'content_published': 'Nouveau contenu publié',
        'content_updated': 'Contenu existant modifié',
        'content_deleted': 'Contenu supprimé',
        'url_structure_changed': 'URLs modifiées',
        'schedule_daily': 'Mise à jour quotidienne programmée'
    }
    
    # Détection changements
    recent_changes = detect_content_changes(last_update=get_last_sitemap_date())
    
    if recent_changes:
        # Régénération sitemap
        new_sitemap = generate_sitemap_from_database()
        
        # Sauvegarde
        save_sitemap(new_sitemap)
        
        # Notification moteurs de recherche
        ping_search_engines()
        
        # Log de l'activité
        log_sitemap_update(len(recent_changes))

Soumission et monitoring

Robots.txt

# robots.txt avec sitemap
User-agent: *
Allow: /

# Référencer sitemap
Sitemap: https://site.com/sitemap.xml
Sitemap: https://site.com/sitemap-images.xml
Sitemap: https://site.com/sitemap-news.xml

Google Search Console

# Monitoring via Search Console API
def monitor_sitemap_performance():
    """
    Suit performance sitemaps dans GSC
    """
    metrics = {
        'submitted_urls': 'URLs soumises dans sitemap',
        'indexed_urls': 'URLs effectivement indexées',
        'indexation_rate': 'Pourcentage indexation',
        'errors': 'Erreurs détectées',
        'warnings': 'Avertissements'
    }
    
    # Récupération données GSC
    sitemap_data = gsc_api.get_sitemap_status('https://site.com/sitemap.xml')
    
    analysis = {
        'indexation_health': sitemap_data['indexed'] / sitemap_data['submitted'],
        'common_errors': sitemap_data['errors'][:5],
        'recommendations': generate_sitemap_recommendations(sitemap_data)
    }
    
    return analysis

Erreurs courantes

Problèmes techniques

# Erreurs fréquentes sitemaps
common_sitemap_errors = {
    'format_errors': {
        'invalid_xml': 'XML malformé ou caractères spéciaux',
        'encoding_issues': 'Problèmes encodage UTF-8',
        'namespace_missing': 'Namespace schema manquant'
    },
    
    'content_errors': {
        'urls_not_canonical': 'URLs non-canoniques incluses',
        'noindex_pages': 'Pages noindex dans sitemap',
        'redirect_chains': 'URLs qui redirigent',
        '404_errors': 'Pages inexistantes listées'
    },
    
    'size_limits': {
        'too_many_urls': '>50,000 URLs par sitemap',
        'file_too_large': '>50MB non compressé',
        'timeout_generation': 'Génération trop lente'
    }
}

Le sitemap XML reste un outil fondamental pour optimiser l’indexation, particulièrement crucial pour les gros sites avec beaucoup de contenu dynamique.