Генерація динамічного XML Sitemap для сайту

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.
Розробка та обслуговування будь-яких видів сайтів:
Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Генерація динамічного XML Sitemap для сайту
Середня
від 1 робочого дня до 3 робочих днів
Часті питання
Наші компетенції:
Етапи розробки
Останні роботи
  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Динамічна генерація XML-карти сайту

Динамічний sitemap формується на льоту з бази даних — коректно відбиває актуальний стан сайту, не потребує ручного оновлення. Критично важлива для інтернет-магазинів, новинних порталів та будь-яких сайтів зі постійно мінливим контентом.

Архітектура для великих каталогів

Для сайтів із сотнями тисяч URL sitemap не можна генерувати за один запит. Використовується chunked підхід: кожен розділ — окремий файл.

// routes/web.php
Route::get('/sitemap.xml',                    [SitemapController::class, 'index']);
Route::get('/sitemap-products-{page}.xml',    [SitemapController::class, 'products']);
Route::get('/sitemap-categories.xml',         [SitemapController::class, 'categories']);
Route::get('/sitemap-articles.xml',           [SitemapController::class, 'articles']);

Індексний sitemap з підрахунком сторінок

public function index(): Response
{
    $productPages = ceil(Product::where('is_active', true)->count() / 1000);

    $sitemaps = [];
    for ($i = 1; $i <= $productPages; $i++) {
        $sitemaps[] = [
            'loc'     => route('sitemap.products', ['page' => $i]),
            'lastmod' => now()->format('Y-m-d'),
        ];
    }

    $sitemaps[] = ['loc' => route('sitemap.categories'), 'lastmod' => now()->format('Y-m-d')];
    $sitemaps[] = ['loc' => route('sitemap.articles'),   'lastmod' => now()->format('Y-m-d')];

    return response()
        ->view('sitemap.index', compact('sitemaps'))
        ->header('Content-Type', 'application/xml; charset=UTF-8');
}

Чанкована генерація товарів

public function products(int $page): Response
{
    $products = Product::where('is_active', true)
        ->select(['slug', 'updated_at', 'main_image'])
        ->orderBy('id')
        ->forPage($page, 1000)
        ->get();

    return response()
        ->view('sitemap.products', compact('products'))
        ->header('Content-Type', 'application/xml; charset=UTF-8')
        ->header('Cache-Control', 'public, max-age=3600');
}
{{-- resources/views/sitemap/products.blade.php --}}
<?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">
@foreach ($products as $product)
<url>
    <loc>{{ url('/products/' . $product->slug) }}</loc>
    <lastmod>{{ $product->updated_at->format('Y-m-d') }}</lastmod>
    <changefreq>weekly</changefreq>
    <priority>0.8</priority>
    @if ($product->main_image)
    <image:image>
        <image:loc>{{ $product->main_image }}</image:loc>
    </image:image>
    @endif
</url>
@endforeach
</urlset>

Кешування

public function products(int $page): Response
{
    $cacheKey = "sitemap:products:{$page}";

    $content = Cache::remember($cacheKey, now()->addHour(), function () use ($page) {
        $products = Product::where('is_active', true)
            ->select(['slug', 'updated_at', 'main_image'])
            ->orderBy('id')
            ->forPage($page, 1000)
            ->get();

        return view('sitemap.products', compact('products'))->render();
    });

    return response($content)->header('Content-Type', 'application/xml; charset=UTF-8');
}

Інвалідація кеша при змінах товару:

// Product observer
public function saved(Product $product): void
{
    $page = ceil($product->getKey() / 1000);
    Cache::forget("sitemap:products:{$page}");
}

Sitemap для мультимовних сайтів (hreflang)

<url>
    <loc>https://example.ru/products/laptop</loc>
    <xhtml:link rel="alternate" hreflang="ru" href="https://example.ru/products/laptop"/>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/products/laptop"/>
    <xhtml:link rel="alternate" hreflang="x-default" href="https://example.com/products/laptop"/>
</url>

Автоматична відправка в Search Console

Після кожного деплою або за розписанням:

// Artisan command
Http::get('https://www.google.com/ping', [
    'sitemap' => url('/sitemap.xml')
]);

Яндекс.Вебмастер — аналогічно через https://webmaster.yandex.ru/ping?sitemap=URL.

Виключення з sitemap

Сторінки, які не повинні індексуватися: noindex сторінки, сторінки пагінації, фільтри з параметрами, дублі. Фільтруються на рівні запиту до БД через додаткові флаги або за паттернами URL.

Час налаштування: 1–2 дні з кешуванням та підтримкою великих каталогів.