Sitemap
This recipe walks you through creating a product sitemap feed using Laravel Feeds. You will: - Generate the necessary classes - Implement the feed logic - Expose the files via the file system - Optionally reference the generated sitemap from a root sitemap.xml file
Create the files
Generate the feed and its item class using the following console command:
php artisan make:feed Sitemaps/Product -t
Populate the feed
Implement the feed root element, attributes, query builder, output filename, and item mapping as shown below:
<?php
declare(strict_types=1);
namespace App\Feeds\Sitemaps;
use App\Feeds\Sitemaps\Items\ProductFeedItem;
use App\Models\Product;
use DragonCode\LaravelFeed\Data\ElementData;
use DragonCode\LaravelFeed\Feeds\Feed;
use DragonCode\LaravelFeed\Feeds\Items\FeedItem;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
class ProductFeed extends Feed
{
protected string $name = 'urlset';
protected array $attributes = [
'xmlns' => 'http://www.sitemaps.org/schemas/sitemap/0.9',
'xmlns:xhtml' => 'http://www.w3.org/1999/xhtml',
'xmlns:image' => 'http://www.google.com/schemas/sitemap-image/1.1',
'xmlns:video' => 'http://www.google.com/schemas/sitemap-video/1.1',
'xmlns:news' => 'http://www.google.com/schemas/sitemap-news/0.9',
];
public function builder(): Builder
{
return Product::query();
}
public function root(): ElementData
{
return new ElementData(
name : $this->name,
attributes: $this->attributes,
);
}
public function item(Model $model): FeedItem
{
return new ProductFeedItem($model);
}
public function filename(): string
{
return 'sitemaps/products.xml';
}
}
Populate the feed item
Define the XML element name and map your model’s properties to the corresponding sitemap tags:
<?php
declare(strict_types=1);
namespace App\Feeds\Sitemaps\Items;
use DragonCode\LaravelFeed\Feeds\Items\FeedItem;
use function route;
/** @property-read \App\Models\Product $model */
class ProductFeedItem extends FeedItem
{
public function name(): string
{
return 'url';
}
public function toArray(): array
{
return [
'loc' => route('products.show', $this->model->slug),
'lastmod' => $this->model->updated_at,
'priority' => 0.9,
];
}
}
Activate
Review the generated operation or migration file, then run the appropriate console command:
# For Laravel Deploy Operations
php artisan operations
# For Laravel Migrations
php artisan migrate
Links
Add a file system disk that points to the directory containing your sitemaps in the config/filesystems.php configuration file:
return [
'links' => [
public_path('storage') => storage_path('app/public'),
public_path('sitemaps') => storage_path('app/public/sitemaps'),
],
];
Then create the public symlink so the files are accessible in a browser:
php artisan storage:link
Generate feed
Generate the feed by running the following console command:
php artisan feed:generate
Add a link to the root sitemap.xml
If you maintain a root sitemap.xml file that references other sitemaps, add an entry like this:
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>https://example.com/sitemaps/products.xml</loc>
</sitemap>
<sitemap>
<loc>https://example.com/sitemaps/other-sitemaps.xml</loc>
</sitemap>
</sitemapindex>
Result
The generated sitemap.xml for your products will look like this:
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
<url>
<loc>https://example.com/products/quidem-tempore-nulla-repudiandae-vero</loc>
<lastmod>2025-09-04T04:08:12+00:00</lastmod>
<priority>0.9</priority>
</url>
<url>
<loc>https://example.com/products/laudantium-porro-qui-rerum-incidunt-expedita</loc>
<lastmod>2025-09-04T04:08:12+00:00</lastmod>
<priority>0.9</priority>
</url>
</urlset>
05 September 2025