turnley.dev

PHP and MySQL code for faucet operators

Tools & Calculators

SEO-001

A sitemap.xml that knows its own domain

Generated from the database at request time, so it is never stale and never has to be edited after a site is moved or sold.

A static sitemap goes out of date the first time you publish anything. Worse, on a site that gets handed to someone else, a hardcoded domain in the sitemap points a new owner's search console at the old address.

Generating it from the database and the configured base URL solves both. Rewrite /sitemap.xml to the script so the file appears at the address search engines expect.

PHP
<?php
// sitemap.php — rewrite: RewriteRule ^sitemap\.xml$ sitemap.php [L]
header('Content-Type: application/xml; charset=utf-8');

$base = rtrim(setting($pdo, 'base_url'), '/');

echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";

$emit = static function (string $loc, ?string $lastmod, string $freq, string $prio): void {
    echo "  <url>\n";
    echo '    <loc>' . htmlspecialchars($loc, ENT_XML1) . "</loc>\n";
    if ($lastmod !== null) {
        echo '    <lastmod>' . date('Y-m-d', strtotime($lastmod)) . "</lastmod>\n";
    }
    echo '    <changefreq>' . $freq . "</changefreq>\n";
    echo '    <priority>' . $prio . "</priority>\n";
    echo "  </url>\n";
};

$emit($base . '/', null, 'daily', '1.0');

foreach ($pdo->query('SELECT slug, updated_at FROM articles WHERE status = 1') as $row) {
    $emit($base . '/a/' . $row['slug'], $row['updated_at'], 'monthly', '0.7');
}

echo '</urlset>';

Using it

Point robots.txt at it with an absolute URL built from the same setting, so the two can never disagree.

Leave anything behind a login out of the sitemap entirely, and mark those pages noindex as well. A sitemap that lists pages a crawler cannot reach wastes crawl budget on a small site that does not have much to spare.

What bites people

Sitemaps cap at 50,000 URLs and 50MB uncompressed. Past that you need an index file pointing at several sitemaps.

lastmod matters only if it is true. Stamping every URL with today's date teaches crawlers to ignore the field.

Also in SEO and Frontend