PHPackages                             flagrow/sitemap - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. flagrow/sitemap

Abandoned → [fof/sitemap](/?search=fof%2Fsitemap)Flarum-extension[Utility &amp; Helpers](/categories/utility)

flagrow/sitemap
===============

Generate a sitemap

2.6.1(2w ago)189.6k18[4 issues](https://github.com/FriendsOfFlarum/sitemap/issues)[2 PRs](https://github.com/FriendsOfFlarum/sitemap/pulls)MITPHPPHP ^8.0CI failing

Since Aug 8Pushed 4d ago2 watchersCompare

[ Source](https://github.com/FriendsOfFlarum/sitemap)[ Packagist](https://packagist.org/packages/flagrow/sitemap)[ Docs](https://friendsofflarum.org)[ Fund](https://opencollective.com/fof/donate)[ RSS](/packages/flagrow-sitemap/feed)WikiDiscussions 2.x Synced 2d ago

READMEChangelog (10)Dependencies (12)Versions (52)Used By (0)

SEO &amp; Sitemap by FriendsOfFlarum
====================================

[](#seo--sitemap-by-friendsofflarum)

[![MIT license](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](https://github.com/FriendsOfFlarum/sitemap/blob/master/LICENSE.md) [![Latest Stable Version](https://camo.githubusercontent.com/764029051e048b5221078d21f3c7d5ed364b338d2fbbc1a7f0921a91b5defc76/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f666f662f736974656d61702e737667)](https://packagist.org/packages/fof/sitemap) [![Total Downloads](https://camo.githubusercontent.com/ce646333a562b2142f669460626e6efe92d4d492deff882b90a4d7e9e1786953/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f666f662f736974656d61702e737667)](https://packagist.org/packages/fof/sitemap) [![OpenCollective](https://camo.githubusercontent.com/1903c197bb0307e60d6328653532b8a6b9890b898fbc92e314ab39d699491e74/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6f70656e636f6c6c6563746976652d666f662d626c75652e737667)](https://opencollective.com/fof/donate)

A comprehensive SEO solution for Flarum that provides both XML sitemaps and robots.txt generation to help search engines discover and index your forum content effectively.

Features
--------

[](#features)

- **XML Sitemaps**: Automatically generated sitemaps with intelligent content discovery
- **Robots.txt Generation**: Standards-compliant robots.txt with dynamic path detection
- **Search Engine Compliance**: Ensures proper indexing while protecting sensitive areas
- **Extensible Architecture**: Other extensions can easily customize both sitemaps and robots.txt
- **Performance Optimized**: Multiple generation modes for forums of all sizes
- **Smart Integration**: Automatically detects and includes content from popular extensions

The extension intelligently includes content like Discussions, Users, Tags (flarum/tags), and Pages (fof/pages) while providing extensive customization options for developers.

Installation
------------

[](#installation)

This extension requires PHP 8.0 or greater.

Install manually with composer:

```
composer require fof/sitemap
```

Updating
--------

[](#updating)

```
composer update fof/sitemap
php flarum migrate
php flarum cache:clear
```

XML Sitemap Generation
----------------------

[](#xml-sitemap-generation)

The extension automatically generates XML sitemaps at `/sitemap.xml` that help search engines discover and index your forum content.

### Generation Modes

[](#generation-modes)

There are two modes available, both serving content from your main domain for search engine compliance.

#### Runtime Mode

[](#runtime-mode)

The sitemap is generated on-the-fly when requested. Individual sitemap files are served at `/sitemap-1.xml`, `/sitemap-2.xml`, etc.

**Best for**: Small to medium forums with less than **10,000 total items** (discussions, users, tags, pages combined). Most shared hosting environments.

#### Cached Multi-File Mode

[](#cached-multi-file-mode)

Sitemaps are pre-generated and updated via the Flarum scheduler. Content is stored on your configured storage (local disk, S3, CDN) but always served from your main domain.

**Best for**: Larger forums starting at 10,000+ items.

**Manual rebuild**:

```
php flarum fof:sitemap:build
```

#### Performance Optimizations

[](#performance-optimizations)

For enterprise customers with millions of items, the "Enable risky performance improvements" option reduces database response size by limiting returned columns. Only enable if generation takes over an hour or saturates your database connection.

### Search Engine Compliance

[](#search-engine-compliance)

The extension ensures full search engine compliance:

- **Domain Consistency**: All sitemaps served from your main forum domain
- **Unified URLs**: Consistent structure (`/sitemap.xml`, `/sitemap-1.xml`) regardless of storage
- **Automatic Proxying**: External storage content proxied through your domain
- **Google Search Console Compatible**: Works seamlessly with all major search engines

### Scheduling

[](#scheduling)

Cached sitemaps automatically update via the Flarum scheduler. Configure the frequency in extension settings.

Learn more about [Flarum scheduler setup](https://discuss.flarum.org/d/24118).

Robots.txt Generation
---------------------

[](#robotstxt-generation)

The extension automatically generates a standards-compliant `robots.txt` file at `/robots.txt` that works seamlessly with your sitemap configuration. It replaces any existing robots.txt functionality from other extensions like `v17development/flarum-seo`.

### Features

[](#features-1)

- **Dynamic Path Detection**: Automatically detects admin, API, and forum paths from your Flarum configuration
- **Settings Integration**: Respects your sitemap exclusion settings (excludeUsers, excludeTags)
- **Extensible System**: Other extensions can easily add, remove, or modify robots.txt entries
- **Standards Compliant**: Generates proper robots.txt format with user-agent grouping
- **Automatic Sitemap References**: Includes your sitemap URL automatically

### Default Behavior

[](#default-behavior)

The generated robots.txt includes:

```
User-agent: *
Disallow: /admin
Disallow: /admin/
Disallow: /api
Disallow: /api/
Disallow: /settings
Disallow: /notifications
Disallow: /logout
Disallow: /reset
Disallow: /confirm

Sitemap: https://yourforum.com/sitemap.xml

```

**Conditional entries** (only included when relevant):

- **User profiles** (`/u/`) - Disallowed when `excludeUsers` setting is enabled
- **Tag pages** (`/t/` and `/tags`) - Disallowed when `excludeTags` setting is enabled and flarum/tags extension is installed

### Integration with Sitemap Settings

[](#integration-with-sitemap-settings)

The robots.txt generation automatically respects your sitemap configuration:

- When **"Exclude users from sitemap"** is enabled, user profile pages (`/u/`) are disallowed
- When **"Exclude tags from sitemap"** is enabled, tag pages (`/t/`, `/tags`) are disallowed
- The sitemap URL is automatically included based on your forum's URL configuration

This ensures consistency between what's in your sitemap and what's allowed in robots.txt.

Extending the Extension
-----------------------

[](#extending-the-extension)

This extension provides comprehensive APIs for customizing both XML sitemaps and robots.txt generation.

### Extending XML Sitemaps

[](#extending-xml-sitemaps)

#### Using the Unified Sitemap Extender (Recommended)

[](#using-the-unified-sitemap-extender-recommended)

The recommended way to extend sitemaps uses the unified `Sitemap` extender with method chaining:

```
use FoF\Sitemap\Extend;

return [
    (new Extend\Sitemap())
        ->addResource(YourCustomResource::class)
        ->removeResource(\FoF\Sitemap\Resources\Tag::class)
        ->replaceResource(\FoF\Sitemap\Resources\User::class, YourCustomUserResource::class)
        ->addStaticUrl('reviews.index')
        ->forceCached(),
];
```

**Available Methods:**

- **`addResource(string $resourceClass)`**: Add a custom resource to the sitemap
- **`removeResource(string $resourceClass)`**: Remove an existing resource from the sitemap
- **`replaceResource(string $oldResourceClass, string $newResourceClass)`**: Replace an existing resource
- **`addStaticUrl(string $routeName)`**: Add a static URL by route name
- **`forceCached()`**: Force cached mode for managed hosting environments

#### Creating Custom Resources

[](#creating-custom-resources)

Create a class that extends `FoF\Sitemap\Resources\Resource`:

```
use FoF\Sitemap\Resources\Resource;
use FoF\Sitemap\Sitemap\Frequency;

class YourCustomResource extends Resource
{
    public function query(): Builder
    {
        return YourModel::query()->where('is_public', true);
    }

    public function url($model): string
    {
        return $this->generateRouteUrl('your.route', ['id' => $model->id]);
    }

    public function priority(): float
    {
        return 0.7;
    }

    public function frequency(): string
    {
        return Frequency::WEEKLY;
    }

    public function lastModifiedAt($model): Carbon
    {
        return $model->updated_at ?? $model->created_at;
    }

    // Optional: Dynamic values based on model data
    public function dynamicFrequency($model): ?string
    {
        $daysSinceActivity = $model->updated_at->diffInDays(now());

        if ($daysSinceActivity < 1) return Frequency::HOURLY;
        if ($daysSinceActivity < 7) return Frequency::DAILY;
        return Frequency::WEEKLY;
    }
}
```

### Extending Robots.txt

[](#extending-robotstxt)

#### Using the Robots Extender

[](#using-the-robots-extender)

Extensions can customize robots.txt using the `Robots` extender:

```
use FoF\Sitemap\Extend\Robots;

return [
    (new Robots())
        ->addEntry(MyCustomRobotsEntry::class)
        ->removeEntry(\FoF\Sitemap\Robots\Entries\ApiEntry::class)
        ->replace(\FoF\Sitemap\Robots\Entries\AdminEntry::class, MyCustomAdminEntry::class),
];
```

**Available Methods:**

- **`addEntry(string $entryClass)`**: Add a custom robots.txt entry
- **`removeEntry(string $entryClass)`**: Remove an existing entry
- **`replace(string $oldEntryClass, string $newEntryClass)`**: Replace an existing entry

#### Creating Custom Robots Entries

[](#creating-custom-robots-entries)

Create a class that extends `FoF\Sitemap\Robots\RobotsEntry`:

```
use FoF\Sitemap\Robots\RobotsEntry;

class MyCustomRobotsEntry extends RobotsEntry
{
    public function getRules(): array
    {
        return [
            // Use helper methods for clean, readable code
            $this->disallowForAll('/private'),
            $this->crawlDelayFor('Googlebot', 10),
            $this->allowFor('Googlebot', '/special-for-google'),
            $this->disallowFor('BadBot', '/'),
            $this->sitemap('https://example.com/news-sitemap.xml'),
        ];
    }

    public function enabled(): bool
    {
        return static::$settings->get('my-extension.enable-robots', true);
    }
}
```

**Helper Methods Available:**

- `disallowForAll(string $path)`, `disallowFor(string $userAgent, string $path)`
- `allowForAll(string $path)`, `allowFor(string $userAgent, string $path)`
- `crawlDelayForAll(int $seconds)`, `crawlDelayFor(string $userAgent, int $seconds)`
- `sitemap(string $url)`

#### Extending Default Entries

[](#extending-default-entries)

All default entries can be extended to modify their behavior:

```
class CustomAdminEntry extends \FoF\Sitemap\Robots\Entries\AdminEntry
{
    protected function buildAdminRules(string $adminPath): array
    {
        return [
            $this->disallowForAll($adminPath),
            $this->disallowForAll(rtrim($adminPath, '/') . '/'),
            // Allow Googlebot to access public admin stats
            $this->allowFor('Googlebot', $adminPath . '/public-stats'),
        ];
    }
}
```

### Legacy Extenders (Deprecated)

[](#legacy-extenders-deprecated)

The following extenders are deprecated and will be removed in Flarum 2.0:

```
// Deprecated - use unified Sitemap extender instead
new \FoF\Sitemap\Extend\RegisterResource(YourResource::class);
new \FoF\Sitemap\Extend\RemoveResource(\FoF\Sitemap\Resources\Tag::class);
new \FoF\Sitemap\Extend\RegisterStaticUrl('reviews.index');
new \FoF\Sitemap\Extend\ForceCached();
```

Configuration Options
---------------------

[](#configuration-options)

### Sitemap Elements

[](#sitemap-elements)

Control which elements are included in your XML sitemaps:

- **Include priority values**: Used by some search engines like Bing and Yandex (ignored by Google)
- **Include change frequency values**: Helps search engines schedule crawling (ignored by Google)

Both are enabled by default. When enabled, the extension uses intelligent frequency calculation based on actual content activity.

### Performance Settings

[](#performance-settings)

- **Risky Performance Improvements**: For enterprise customers with millions of items. Reduces database response size but may break custom visibility scopes or slug drivers.

Server Configuration
--------------------

[](#server-configuration)

### Nginx Configuration

[](#nginx-configuration)

If accessing `/sitemap.xml` or `/robots.txt` results in nginx 404 errors, add these rules:

```
# FoF Sitemap & Robots — Flarum handles everything
location = /sitemap.xml {
    rewrite ^ /index.php?$query_string last;
    add_header Cache-Control "max-age=0";
}

location ^~ /sitemap- {
    rewrite ^ /index.php?$query_string last;
    add_header Cache-Control "max-age=0";
}

location = /robots.txt {
    rewrite ^ /index.php?$query_string last;
    add_header Cache-Control "max-age=0";
}
```

Troubleshooting
---------------

[](#troubleshooting)

### Regenerating Sitemaps

[](#regenerating-sitemaps)

If you've updated the extension or changed storage settings:

```
php flarum fof:sitemap:build
```

### Debug Logging

[](#debug-logging)

When Flarum is in debug mode, the extension provides detailed logging for:

- Sitemap generation and serving
- Content proxying from external storage
- Route parameter extraction
- Request handling issues

Check your Flarum logs (`storage/logs/`) for detailed information.

Acknowledgments
---------------

[](#acknowledgments)

The initial version of this extension was sponsored by [profesionalreview.com](https://www.profesionalreview.com/).

Links
-----

[](#links)

- [![OpenCollective](https://camo.githubusercontent.com/8ea53c451470d1a72789d650c77e2b22eee915f7fbf2cbeeeeaa25f47301efe2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f6e6174652d667269656e64736f66666c6172756d2d3434414545353f7374796c653d666f722d7468652d6261646765266c6f676f3d6f70656e2d636f6c6c656374697665)](https://opencollective.com/fof/donate)
- [Flarum Discuss post](https://discuss.flarum.org/d/14941)
- [Source code on GitHub](https://github.com/FriendsOfFlarum/sitemap)
- [Report an issue](https://github.com/FriendsOFflarum/sitemap/issues)
- [Download via Packagist](https://packagist.org/packages/fof/sitemap)

###  Health Score

60

—

FairBetter than 99% of packages

Maintenance94

Actively maintained with recent releases

Popularity31

Limited adoption so far

Community24

Small or concentrated contributor base

Maturity80

Battle-tested with a long release history

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~65 days

Recently: every ~12 days

Total

44

Last Release

17d ago

Major Versions

2.4.3 → 3.0.0-beta.32026-01-07

2.4.4 → 3.0.0-beta.42026-01-14

2.5.0 → 3.0.0-beta.52026-01-24

1.x-dev → 2.6.12026-04-27

2.x-dev → 3.0.0-beta.62026-04-27

PHP version history (3 changes)2.0.0-beta.1PHP 8.\*

2.3.0PHP ^8.0

3.0.0-beta.1PHP ^8.2

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/504687?v=4)[Daniël Klabbers](/maintainers/Luceos)[@luceos](https://github.com/luceos)

![](https://www.gravatar.com/avatar/0538135c1debcef5602dce7ece027909cc832b7a6284ab9189a19aa8de98d60d?d=identicon)[clarkwinkelmann](/maintainers/clarkwinkelmann)

---

Top Contributors

[![imorland](https://avatars.githubusercontent.com/u/16573496?v=4)](https://github.com/imorland "imorland (32 commits)")[![clarkwinkelmann](https://avatars.githubusercontent.com/u/5264300?v=4)](https://github.com/clarkwinkelmann "clarkwinkelmann (22 commits)")[![flarum-bot](https://avatars.githubusercontent.com/u/39334649?v=4)](https://github.com/flarum-bot "flarum-bot (15 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (9 commits)")[![luceos](https://avatars.githubusercontent.com/u/504687?v=4)](https://github.com/luceos "luceos (9 commits)")[![StyleCIBot](https://avatars.githubusercontent.com/u/11048387?v=4)](https://github.com/StyleCIBot "StyleCIBot (3 commits)")[![davwheat](https://avatars.githubusercontent.com/u/7406822?v=4)](https://github.com/davwheat "davwheat (3 commits)")[![gianniguida](https://avatars.githubusercontent.com/u/53989450?v=4)](https://github.com/gianniguida "gianniguida (2 commits)")[![skmedix](https://avatars.githubusercontent.com/u/3246162?v=4)](https://github.com/skmedix "skmedix (2 commits)")[![iPurpl3x](https://avatars.githubusercontent.com/u/18526076?v=4)](https://github.com/iPurpl3x "iPurpl3x (2 commits)")[![wloot](https://avatars.githubusercontent.com/u/30223095?v=4)](https://github.com/wloot "wloot (1 commits)")[![DavideIadeluca](https://avatars.githubusercontent.com/u/146922689?v=4)](https://github.com/DavideIadeluca "DavideIadeluca (1 commits)")[![eddiewebb](https://avatars.githubusercontent.com/u/5262154?v=4)](https://github.com/eddiewebb "eddiewebb (1 commits)")[![grimur82](https://avatars.githubusercontent.com/u/9028297?v=4)](https://github.com/grimur82 "grimur82 (1 commits)")[![pierres](https://avatars.githubusercontent.com/u/977535?v=4)](https://github.com/pierres "pierres (1 commits)")[![Ralkage](https://avatars.githubusercontent.com/u/2059356?v=4)](https://github.com/Ralkage "Ralkage (1 commits)")[![spekulatius](https://avatars.githubusercontent.com/u/8433587?v=4)](https://github.com/spekulatius "spekulatius (1 commits)")[![askvortsov1](https://avatars.githubusercontent.com/u/38059171?v=4)](https://github.com/askvortsov1 "askvortsov1 (1 commits)")

---

Tags

discussionsflarumforumssitemapsitemap-filesextensionSitemapflarumflagrow

### Embed Badge

![Health badge](/badges/flagrow-sitemap/health.svg)

```
[![Health](https://phpackages.com/badges/flagrow-sitemap/health.svg)](https://phpackages.com/packages/flagrow-sitemap)
```

###  Alternatives

[fof/sitemap

Generate a sitemap

1988.7k2](/packages/fof-sitemap)[fof/mason

Add custom fields to discussions

206.0k](/packages/fof-mason)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
