muhammad-nawlo/filament-sitemap-generator
Installation
composer require muhammad-nawlo/filament-sitemap-generator
Publish the config:
php artisan vendor:publish --provider="MuhammadNawlo\FilamentSitemapGenerator\FilamentSitemapGeneratorServiceProvider" --tag="config"
Register Plugin
Add to app/Providers/Filament/AdminPanelProvider.php:
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
\MuhammadNawlo\FilamentSitemapGenerator\FilamentSitemapGeneratorPlugin::make(),
]);
}
First Use Case
Configure a basic sitemap in config/filament-sitemap-generator.php:
'sitemaps' => [
'default' => [
'url' => '/sitemap.xml',
'items' => [
\App\Sitemap\PostSitemap::class,
],
],
],
Create a sitemap class (e.g., app/Sitemap/PostSitemap.php):
use Spatie\Sitemap\Sitemap;
use Spatie\Sitemap\Tags\Url;
class PostSitemap extends Sitemap
{
public function index(): array
{
return \App\Models\Post::query()
->get()
->map(fn ($post) => Url::create($post->path)
->setLastModificationDate($post->updated_at)
->setChangeFrequency(Url::CHANGE_FREQUENCY_DAILY));
}
}
Access the Plugin
Visit /admin/sitemaps in your Filament admin panel to generate and manage sitemaps.
Dynamic Sitemap Generation Use the plugin’s Filament UI to trigger sitemap generation via:
// In a Filament action or controller
$this->call(SitemapGenerator::class);
Or via CLI:
php artisan sitemap:generate
Sitemap Splitting
Configure chunked sitemaps in config/filament-sitemap-generator.php:
'sitemaps' => [
'posts' => [
'url' => '/sitemap-posts.xml',
'items' => [\App\Sitemap\PostSitemap::class],
'split' => [
'enabled' => true,
'chunk_size' => 500,
'index_url' => '/sitemap-posts-index.xml',
],
],
],
Advanced Sitemap Features
Sitemap and use NewsUrl:
use Spatie\Sitemap\Tags\NewsUrl;
public function index(): array
{
return NewsUrl::create('/news/1')
->setLastModificationDate(now())
->setPublicationDate(now()->subDays(1))
->setArticleEngagement([
'total_engagement' => 100,
'likes' => 50,
]);
}
ImageUrl:
use Spatie\Sitemap\Tags\ImageUrl;
public function index(): array
{
return ImageUrl::create('/post/1')
->addImage('/images/post-1.jpg', 500, 500, 'image/jpeg');
}
AlternateUrl:
use Spatie\Sitemap\Tags\AlternateUrl;
public function index(): array
{
return Url::create('/post/1')
->addAlternate(AlternateUrl::create('/es/post/1', 'es'));
}
Search Engine Ping Automatically ping search engines after generation by configuring:
'ping_search_engines' => true,
in the config. Customize pings in the SitemapGenerator service.
Caching Leverage Laravel’s cache for performance:
'cache' => [
'enabled' => true,
'ttl' => 60, // minutes
],
Filament Resource Integration Attach sitemap generation to a Filament resource’s action:
public static function getActions(): array
{
return [
SitemapGenerateAction::make(),
];
}
Event-Based Generation
Trigger sitemap updates on model events (e.g., saved):
// In PostObserver.php
public function saved(Post $post)
{
event(new SitemapRegenerateEvent());
}
Customizing the Filament UI Override the plugin’s views by publishing assets:
php artisan vendor:publish --provider="MuhammadNawlo\FilamentSitemapGenerator\FilamentSitemapGeneratorServiceProvider" --tag="views"
Then modify resources/views/vendor/filament-sitemap-generator/....
API-Driven Generation Expose an API endpoint for programmatic generation:
Route::post('/api/sitemap/generate', function () {
$generator = app(SitemapGenerator::class);
return response()->json($generator->generate());
});
Compatibility Issues
spatie/laravel-sitemap may have version constraints. Check the Spatie docs for compatibility.Sitemap Indexing
split, ensure the index_url is correctly configured to avoid broken links. Test with:
php artisan sitemap:generate --sitemap=posts
Caching Quirks
php artisan cache:clear
php artisan sitemap:clear-cache
URL Generation
setAbsoluteUrl(false) in Url::create() for relative paths if needed:
Url::create('/post/1')->setAbsoluteUrl(false)
Search Engine Ping Failures
'ping_search_engines' => [
'enabled' => true,
'log_pings' => true, // Add this to config
],
Log Sitemap Contents Temporarily log the generated XML for validation:
// In your Sitemap class
public function toXml(): string
{
$xml = parent::toXml();
Log::debug('Sitemap XML:', ['xml' => $xml]);
return $xml;
}
Validate XML
Use an online validator (e.g., XML Validation) to check the generated sitemap.xml.
Check File Permissions
Ensure the storage directory (storage/app/sitemaps) is writable:
chmod -R 755 storage/app/sitemaps
Debug Splitting
If splits aren’t working, verify the chunk_size and test with a small number (e.g., 10) to isolate issues.
Custom Sitemap Generators
Extend the base SitemapGenerator class to add logic:
class CustomSitemapGenerator extends \MuhammadNawlo\FilamentSitemapGenerator\SitemapGenerator
{
public function generate(): void
{
// Custom logic before/after generation
parent::generate();
$this->notifyAdmins();
}
}
Bind it in AppServiceProvider:
$this->app->bind(SitemapGenerator::class, CustomSitemapGenerator::class);
Dynamic Sitemap Configuration Load sitemap configurations from a database or API:
// In a custom generator
$configs = \App\Models\SitemapConfig::all()->toArray();
$this->setSitemaps($configs);
Webhook Triggers Integrate
How can I help you explore Laravel packages today?