PHPackages                             ernestdefoe/seo - 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. ernestdefoe/seo

ActiveFlarum-extension[Utility &amp; Helpers](/categories/utility)

ernestdefoe/seo
===============

SEO meta tags, OpenGraph, Twitter Cards, JSON-LD structured data, bundled sitemap.xml generator, and search-console verification for Flarum 2.

2.0.11(1w ago)0126↑233.3%MITPHPPHP ^8.3CI passing

Since Oct 13Pushed 1w agoCompare

[ Source](https://github.com/ernestdefoe/seo)[ Packagist](https://packagist.org/packages/ernestdefoe/seo)[ Docs](https://github.com/ernestdefoe/seo)[ RSS](/packages/ernestdefoe-seo/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (10)Dependencies (5)Versions (13)Used By (0)

SEO for Flarum 2
================

[](#seo-for-flarum-2)

[![Floxum](https://camo.githubusercontent.com/3247d9c5a2dc83872349264747c031ad125e0b4d135f657f035a73c76aa3326c/68747470733a2f2f666c6f78756d2e636f6d2f657874656e73696f6e2f65726e6573746465666f652f73656f2f62616467652f6e616d65)](https://floxum.com/extension/ernestdefoe/seo)[![Version](https://camo.githubusercontent.com/a2235539f9bc7fb6d925ba1545f080da0637c2dd60176bfa83590a0e2796f0c4/68747470733a2f2f666c6f78756d2e636f6d2f657874656e73696f6e2f65726e6573746465666f652f73656f2f62616467652f686967686573742d76657273696f6e)](https://floxum.com/extension/ernestdefoe/seo)[![Downloads](https://camo.githubusercontent.com/e0511e83e23c8f7cf3ee7e9a9614d2bb6ddf8cd28104ebc02a03e2d8a8b2a946/68747470733a2f2f666c6f78756d2e636f6d2f657874656e73696f6e2f65726e6573746465666f652f73656f2f62616467652f646f776e6c6f616473)](https://floxum.com/extension/ernestdefoe/seo)[![Review](https://camo.githubusercontent.com/89906aa1964e664d477bb8371f167714eee193126e9a824ed42592ca05b40512/68747470733a2f2f666c6f78756d2e636f6d2f657874656e73696f6e2f65726e6573746465666f652f73656f2f62616467652f726576696577)](https://floxum.com/extension/ernestdefoe/seo)[![License](https://camo.githubusercontent.com/67525ea6080ac01df18af0fd8c915ac42b0334c3cc7bdba836cdc41e16ec0ebf/68747470733a2f2f666c6f78756d2e636f6d2f657874656e73696f6e2f65726e6573746465666f652f73656f2f62616467652f6c6963656e7365)](https://floxum.com/extension/ernestdefoe/seo)

[![Flarum 2.0](https://camo.githubusercontent.com/478618f76f079b93e9f3c083a22f2c9424466c5407ee898cddad0faf286c3d80/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f466c6172756d2d253545322e302d6f72616e6765)](https://flarum.org/)[![License: MIT](https://camo.githubusercontent.com/08cef40a9105b6526ca22088bc514fbfdbc9aac1ddbf8d4e6c750e3a88a44dca/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e737667)](LICENSE.md)

SEO meta tags, OpenGraph, Twitter Cards, JSON-LD structured data, a bundled `sitemap.xml` generator, and search-console verification for **Flarum 2** — a maintained, v2-compatible continuation of [`v17development/flarum-seo`](https://github.com/v17development/flarum-seo).

What's different from the upstream
----------------------------------

[](#whats-different-from-the-upstream)

The upstream extension targets Flarum 1.x and the partial Flarum 2 port in `v17development/flarum-seo` left the API layer broken — it won't even boot on Flarum 2 because four core classes (`AbstractSerializer`, `AbstractListController`, `AbstractShowController`, `AbstractDeleteController`, `BasicDiscussionSerializer`, `ForumSerializer`) were removed when the core API was rewritten around `Resource` + `Endpoint` + `Schema`.

This fork:

- **Boots and runs on Flarum 2.x.** Full v2-API migration: the v1 serializer + 4 controllers became one `SeoMetaResource` with declarative `Endpoint::make()` + `Schema\*` fields + writable allowlist. v1 `ApiSerializer` + `ApiController` extenders replaced with `ApiResource(...)->fields()` callbacks mounting fields onto `DiscussionResource` and `ForumResource`. Eager-load via `endpoint(...)->eagerLoad('seoMeta')` to prevent N+1 on the discussion list.
- **Migration bug fix.** Upstream's `2023_02_01_create_seo_meta_table.php` used `$table->string('object_type', 65535)` which silently coerces to `MEDIUMTEXT` and crashes the subsequent unique-index migration with "BLOB/TEXT column used in key specification without a key length". Reduced to `varchar(60)` so the unique index lands on first run.
- **Bundled `sitemap.xml` generator.** Auto-detects `fof/sitemap` — if installed, our controller 404s and defers to fof's. Otherwise generates a single-file sitemap (capped at 50k URLs per the protocol limit) with `` from `last_posted_at`, `` derived from posting recency (hourly→yearly), and `` weighted by comment count + recency. Visibility-scoped to `Guest` so restricted tags / private groups never leak into the public sitemap. 6-hour cache via the framework cache.
- **Search-console verification meta tags.** Four admin-configurable settings: Google Search Console, Bing Webmaster, Yandex Webmaster, Pinterest. Tokens are charset-restricted before interpolation so an admin can't (intentionally or by typo) inject markup into the head. Defensive try/catch around the injector so a verification-tag bug can never block a page render.
- **`robots.txt` always references the sitemap.** Upstream only added the `Sitemap:` directive when `fof-sitemap` was enabled. Since we now always serve a sitemap (ours or theirs), the reference is unconditional.
- **Hardened `UploadSocialMediaImageController`.** Full §11 upload pipeline: size cap (4 MB), extension allowlist (png/jpg/jpeg/webp), `finfo`-based MIME re-detection, server-generated filename, PSR-3 logger wrapped in try/catch.
- **`SeoMetaResource::find()` handles dash-separated polymorphic lookups.** The admin frontend sends `GET /api/seo_meta/discussions-42`to find-or-create the SeoMeta row for a subject; the v2 Resource's Show endpoint normally requires a numeric id, so `find()` intercepts the `{type}-{id}` form and short-circuits to `SeoMeta::findByObjectTypeOrCreate`. Allowlist restricts type to `discussions`/`users`/`tags`/`pages`.

What it does on every page
--------------------------

[](#what-it-does-on-every-page)

SurfaceWhat gets emitted**OpenGraph**`og:site_name`, `og:type`, `og:title`, `og:description`, `og:url`, `og:image`**Twitter Card**`twitter:card`, `twitter:title`, `twitter:description`, `twitter:image`, `twitter:url`**Robots directives**`index/noindex`, `follow/nofollow`, `noarchive`, `noimageindex`, `nosnippet` (per-route + per-row override via SeoMeta)**JSON-LD Schema.org**`DiscussionForumPosting` (with `publisher` Organization + `author` Person), `BreadcrumbList`, `WebSite` (with `SearchAction` for the sitelinks search box). `QAPage` instead of `DiscussionForumPosting` when `fof/best-answer` flags the thread answered.**Article metadata**`article:published_time`, `article:updated_time`**Canonical**`` on every route**Verification**`google-site-verification`, `msvalidate.01`, `yandex-verification`, `p:domain_verify` (when admin has configured the token)Quick start
-----------

[](#quick-start)

```
composer require ernestdefoe/seo
php flarum migrate
php flarum cache:clear
```

Enable from **Admin → Extensions → SEO**. Open the SEO settings tab to configure:

- **Default fallback meta** — site description, keywords, default social-media image.
- **Per-row overrides** — open any discussion / tag / page and click the SEO drawer to override the auto-generated title / description / image / robots directives for that specific subject.
- **Search Console Verification** — paste the verification tokens from Google / Bing / Yandex / Pinterest; meta tags appear on every page on save.

Composer suggests
-----------------

[](#composer-suggests)

- `flarum/tags` — when present, the `Tags` page renderer emits proper category metadata + breadcrumb schema.
- `fof/pages` — when present, the `Pages` page renderer treats pages as `WebPage` schema with publisher attribution.
- `fof/best-answer` — when present, discussions flagged as answered switch from `DiscussionForumPosting` to `QAPage` schema, which search engines render as a Q&amp;A rich snippet.
- `fof/sitemap` — when present, owns `/sitemap.xml` with sitemap-index pagination for forums larger than 50k URLs. We auto-defer to it.
- `ernestdefoe/og-image` — when present, auto-generates per-discussion social images.

Compatibility &amp; status
--------------------------

[](#compatibility--status)

- **Flarum**: 2.0+ (requires `flarum/core: ^2.0`).
- **PHP**: 8.3+.
- **MySQL / MariaDB**: any version that supports `utf8mb4_unicode_ci`(every version Flarum supports).
- **License**: MIT.

Support
-------

[](#support)

Questions, bug reports, and feature requests:

- **Support forum:**
- **Issues:**

License &amp; credits
---------------------

[](#license--credits)

[MIT](LICENSE.md). Upstream credit: [`v17development/flarum-seo`](https://github.com/v17development/flarum-seo)— this extension is a maintained Flarum 2 fork. Core architecture (SeoMeta table, Page drivers, Content injector, Schema.org payload shape) preserved from upstream.

###  Health Score

48

—

FairBetter than 94% of packages

Maintenance98

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community16

Small or concentrated contributor base

Maturity57

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 75% of commits — single point of failure

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 ~21 days

Recently: every ~1 days

Total

12

Last Release

10d ago

PHP version history (2 changes)2.0.1PHP ^8.0

v2.0.0PHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/c9978664264055711c21fbcf73c937f758df771d9cb40f6a25370b10123e7abc?d=identicon)[ernestdefoe](/maintainers/ernestdefoe)

---

Top Contributors

[![jaspervriends](https://avatars.githubusercontent.com/u/4417659?v=4)](https://github.com/jaspervriends "jaspervriends (186 commits)")[![ernestdefoe](https://avatars.githubusercontent.com/u/24905286?v=4)](https://github.com/ernestdefoe "ernestdefoe (23 commits)")[![DavideIadeluca](https://avatars.githubusercontent.com/u/146922689?v=4)](https://github.com/DavideIadeluca "DavideIadeluca (9 commits)")[![rafaucau](https://avatars.githubusercontent.com/u/25438601?v=4)](https://github.com/rafaucau "rafaucau (8 commits)")[![pboschma](https://avatars.githubusercontent.com/u/25609730?v=4)](https://github.com/pboschma "pboschma (5 commits)")[![luceos](https://avatars.githubusercontent.com/u/504687?v=4)](https://github.com/luceos "luceos (4 commits)")[![ziymed](https://avatars.githubusercontent.com/u/2720164?v=4)](https://github.com/ziymed "ziymed (2 commits)")[![flarum-bot](https://avatars.githubusercontent.com/u/39334649?v=4)](https://github.com/flarum-bot "flarum-bot (2 commits)")[![os555](https://avatars.githubusercontent.com/u/4261168?v=4)](https://github.com/os555 "os555 (2 commits)")[![Gasjki](https://avatars.githubusercontent.com/u/4936352?v=4)](https://github.com/Gasjki "Gasjki (1 commits)")[![maicol07](https://avatars.githubusercontent.com/u/9463142?v=4)](https://github.com/maicol07 "maicol07 (1 commits)")[![mbakirov](https://avatars.githubusercontent.com/u/1270314?v=4)](https://github.com/mbakirov "mbakirov (1 commits)")[![ahrasis](https://avatars.githubusercontent.com/u/2795588?v=4)](https://github.com/ahrasis "ahrasis (1 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")[![davwheat](https://avatars.githubusercontent.com/u/7406822?v=4)](https://github.com/davwheat "davwheat (1 commits)")[![imorland](https://avatars.githubusercontent.com/u/16573496?v=4)](https://github.com/imorland "imorland (1 commits)")

---

Tags

JSON-LDSitemapseoopengraphflarumschema.orgflarum-extension

### Embed Badge

![Health badge](/badges/ernestdefoe-seo/health.svg)

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

###  Alternatives

[artesaos/seotools

SEO Tools for Laravel and Lumen

3.4k5.3M63](/packages/artesaos-seotools)[nystudio107/craft-seomatic

SEOmatic facilitates modern SEO best practices &amp; implementation for Craft CMS 5. It is a turnkey SEO system that is comprehensive, powerful, and flexible.

1741.5M51](/packages/nystudio107-craft-seomatic)[honeystone/laravel-seo

SEO metadata and JSON-LD package for Laravel.

35476.1k](/packages/honeystone-laravel-seo)[brotkrueml/schema

Embedding schema.org vocabulary - API and view helpers for schema.org markup

34628.4k13](/packages/brotkrueml-schema)[flarum-lang/russian

Russian language pack for Flarum.

12127.5k](/packages/flarum-lang-russian)[fof/sitemap

Generate a sitemap

1896.4k2](/packages/fof-sitemap)

PHPackages © 2026

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