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

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

broqit/seo
==========

Simple PHP library to help developers 🍻 do better on-page SEO optimization

0.1.1(2y ago)054MITPHPPHP &gt;=7.1.16

Since Oct 20Pushed 2y agoCompare

[ Source](https://github.com/broqit/seo)[ Packagist](https://packagist.org/packages/broqit/seo)[ RSS](/packages/broqit-seo/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (1)Versions (3)Used By (0)

PHP SEO
=======

[](#php-seo)

[![Build Status](https://github.com/melbahja/seo/workflows/Test/badge.svg)](https://github.com/melbahja/seo/actions?query=workflow%3ATest) [![GitHub license](https://camo.githubusercontent.com/671db717ac0c781ae1af034a1cd4b0b70c17fec44e7d3cbba0eeec5d32886591/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6d656c6261686a612f73656f)](https://github.com/melbahja/seo/blob/master/LICENSE) [![Packagist PHP Version Support](https://camo.githubusercontent.com/3061fce706e6e1fb51235ee522a896a9e41d242725d66fc245c96acc9fd983fb/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6d656c6261686a612f73656f)](https://camo.githubusercontent.com/3061fce706e6e1fb51235ee522a896a9e41d242725d66fc245c96acc9fd983fb/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f6d656c6261686a612f73656f) [![Packagist Version](https://camo.githubusercontent.com/e45df369a87b00bd73f4c0c26cc439be9ff09d32ee0c38bbfd41167a72119acc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d656c6261686a612f73656f)](https://camo.githubusercontent.com/e45df369a87b00bd73f4c0c26cc439be9ff09d32ee0c38bbfd41167a72119acc/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6d656c6261686a612f73656f) [![Twitter](https://camo.githubusercontent.com/cac04cd45b2e95b4998cb0e26b03370623bbd47dffbf1810900d7c0e1b54ab35/68747470733a2f2f696d672e736869656c64732e696f2f747769747465722f75726c2f68747470732f6769746875622e636f6d2f6d656c6261686a612f73656f2e7376673f7374796c653d736f6369616c)](https://twitter.com/intent/tweet?url=https%3A%2F%2Fgithub.com%2Fmelbahja%2Fseo)

Simple PHP library to help developers 🍻 do better on-page SEO optimization

### PHP SEO features:

[](#php-seo-features)

- [\[👷\]](#-generate-schemaorg) **Generate schema.org ld+json**
- [\[🛀\]](#-meta-tags) **Generate meta tags with twitter and open graph support**
- [\[🌐\]](#-sitemaps) **Generate sitemaps xml and indexes (supports: 🖺 news, 🖼 images, 📽 videos)**
- [\[📤\]](#-send-sitemaps-to-search-engines) **Submit new sitemaps to search engines**
- [\[📤\]](#-indexing-api) **Indexing API**
- [\[🙈\]](https://github.com/melbahja/seo/blob/master/composer.json) **No dependencies**

Installation:
-------------

[](#installation)

```
composer require melbahja/seo
```

Usage:
------

[](#usage)

Check this simple examples. (of course the composer autoload.php file is required)

#### 👷 Generate schema.org

[](#-generate-schemaorg)

```
use Melbahja\Seo\Schema;
use Melbahja\Seo\Schema\Thing;

$schema = new Schema(
    new Thing('Organization', [
        'url'          => 'https://example.com',
        'logo'         => 'https://example.com/logo.png',
        'contactPoint' => new Thing('ContactPoint', [
            'telephone' => '+1-000-555-1212',
            'contactType' => 'customer service'
        ])
    ])
);

echo $schema;
```

**Results:** (formatted)

```

{
  "@context": "https://schema.org",
  "@graph": [
    {
      "url": "https://example.com",
      "logo": "https://example.com/logo.png",
      "contactPoint": {
        "telephone": "+1-000-555-1212",
        "contactType": "customer service",
        "@type": "ContactPoint",
        "@context": "https://schema.org/"
      },
      "@type": "Organization",
      "@context": "https://schema.org/"
    }
  ]
}

```

```
use Melbahja\Seo\Schema;
use Melbahja\Seo\Schema\Thing;

$product = new Thing('Product');
$product->name  = "Foo Bar";
$product->sku   = "sk12";
$product->image = "/image.jpeg";
$product->description = "testing";
$product->offers = new Thing('Offer', [
    'availability' => 'https://schema.org/InStock',
    'priceCurrency' => 'USD',
    "price" => "119.99",
    'url' => 'https://gool.com',
]);

$webpage = new Thing("WebPage", [
    '@id' => "https://example.com/product/#webpage",
    'url' => "https://example.com/product",
    'name' => 'Foo Bar',
]);

$schema = new Schema(
    $product,
    $webpage,
);

echo json_encode($schema, JSON_PRETTY_PRINT);
```

**Results:**

```
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "name": "Foo Bar",
      "sku": "sk12",
      "image": "/image.jpeg",
      "description": "testing",
      "offers": {
        "availability": "https://schema.org/InStock",
        "priceCurrency": "USD",
        "price": "119.99",
        "url": "https://gool.com",
        "@type": "Offer",
        "@context": "https://schema.org/"
      },
      "@type": "Product",
      "@context": "https://schema.org/"
    },
    {
      "@id": "https://example.com/product/#webpage",
      "url": "https://example.com/product",
      "name": "Foo Bar",
      "@type": "WebPage",
      "@context": "https://schema.org/"
    }
  ]
}
```

#### 🛀 Meta Tags

[](#-meta-tags)

```
use Melbahja\Seo\MetaTags;

$metatags = new MetaTags();

$metatags
        ->title('PHP SEO')
        ->description('This is my description')
        ->meta('author', 'Mohamed Elabhja')
        ->image('https://avatars3.githubusercontent.com/u/8259014')
        ->mobile('https://m.example.com')
        ->canonical('https://example.com')
        ->shortlink('https://git.io/phpseo')
        ->amp('https://apm.example.com');

echo $metatags;
```

**Results:**

```
PHP SEO

```

#### 🗺 Sitemaps

[](#-sitemaps)

```
$yourmap = new Sitemap(string $url, array $options = []): SitemapIndexInterface
```

Option nameDescriptionRequired ?Defaultsave\_pathGenerated sitemaps storage pathYESsitemaps\_urlSitemap index custom url for generated sitemapsNO$urlindex\_nameCustom sitemap index nameNOsitemap.xml##### Simple Example

[](#simple-example)

```
use Melbahja\Seo\Sitemap;

$sitemap = new Sitemap('https://example.com', ['save_path' => '/path/to_save/files']);

$sitemap->links('blog.xml', function($map)
{
    $map->loc('/blog')->freq('daily')->priority('0.8')
        ->loc('/blog/my-new-article')->freq('weekly')->lastMod('2019-03-01')
        ->loc('/اهلا-بالعالم')->freq('weekly');
    $map->loc('/blog/hello')->freq('monthly');
});

// return bool
// throws SitemapException if save_path options not exists
$sitemap->save();
```

**Results:** (📂 in: /path/to\_save/files/)

📁: sitemap.xml (formatted)

```

        https://example.com/blog.xml
        2019-03-01T14:38:02+01:00

```

📁: blog.xml (formatted)

```

      https://example.com/blog
      daily
      0.8

      https://example.com/blog/my-new-article
      weekly
      2019-03-01T00:00:00+01:00

      https://example.com/%D8%A7%D9%87%D9%84%D8%A7-%D8%A8%D8%A7%D9%84%D8%B9%D8%A7%D9%84%D9%85
      weekly

      https://example.com/blog/hello
      monthly

```

##### Multipe Sitemaps &amp;&amp; Images

[](#multipe-sitemaps--images)

```
use Melbahja\Seo\Sitemap;

$sitemap = new Sitemap('https://example.com');

// Instead of passing save_path to the factory you can set it later via setSavePath
// also $sitemap->getSavePath() method to get the current save_path
$sitemap->setSavePath('your_save/path');

// changing sitemap index name
$sitemap->setIndexName('index.xml');

// For images you need to pass a option images => true
$sitemap->links(['name' => 'blog.xml', 'images' => true], function($map)
{
    $map->loc('/blog')->freq('daily')->priority('0.8')
        ->loc('/blog/my-new-article')
            ->freq('weekly')
            ->lastMod('2019-03-01')
            ->image('/uploads/image.jpeg', ['caption' => 'My caption'])
        ->loc('/اهلا-بالعالم')->freq('weekly');

    // image(string $url, array $options = []), image options: caption, geo_location, title, license
    // see References -> images
    $map->loc('/blog/hello')->freq('monthly')->image('https://cdn.example.com/image.jpeg');
});

// another file
$sitemap->links('blog_2.xml', function($map)
{
    // Mabye you need to loop through posts form your database ?
    foreach (range(0, 4) as $i)
    {
        $map->loc("/posts/{$i}")->freq('weekly')->priority('0.7');
    }
});

$sitemap->save();
```

**Results**

📁: index.xml

```

        https://example.com/blog.xml
        2019-03-01T15:13:22+01:00

        https://example.com/blog_2.xml
        2019-03-01T15:13:22+01:00

```

📁: blog.xml

```

        https://example.com/blog
        daily
        0.8

        https://example.com/blog/my-new-article
        weekly
        2019-03-01T00:00:00+01:00

            My caption
            https://example.com/uploads/image.jpeg

        https://example.com/%D8%A7%D9%87%D9%84%D8%A7-%D8%A8%D8%A7%D9%84%D8%B9%D8%A7%D9%84%D9%85
        weekly

        https://example.com/blog/hello
        monthly

            https://cdn.example.com/image.jpeg

```

📁: blog\_2.xml

```

        https://example.com/posts/0
        weekly
        0.7

        https://example.com/posts/1
        weekly
        0.7

        https://example.com/posts/2
        weekly
        0.7

        https://example.com/posts/3
        weekly
        0.7

        https://example.com/posts/4
        weekly
        0.7

```

##### Sitemap with videos

[](#sitemap-with-videos)

```
$sitemap = (new Sitemap('https://example.com'))
                ->setSavePath('./storage/sitemaps')
                ->setSitemapsUrl('https://example.com/sitemaps')
                ->setIndexName('index.xml');

$sitemap->links(['name' => 'posts.xml', 'videos' => true], function($map)
{
    $map->loc('/posts/clickbait-video')->video('My Clickbait Video title',
    [
        // or thumbnail_loc
        'thumbnail' => 'https://example.com/thumbnail.jpeg',
        'description' => 'My description',
        // player_loc or content_loc one of them is required
        'player_loc' => 'https://example.com/embed/81287127'

        // for all available options see References -> videos
    ]);

    $map->loc('posts/bla-bla');
});

$sitemap->save();
```

**Results**

📁: index.xml

```

        https://example.com/sitemaps/posts.xml
        2019-03-01T15:30:02+01:00

```

**Note:** lastmod in sitemap index files are generated automatically

📁: posts.xml

```

        https://example.com/posts/clickbait-video

            My description
            https://example.com/embed/81287127
            My Clickbait Video title
            https://example.com/thumbnail.jpeg

        https://example.com/posts/bla-bla

```

##### News Sitemaps

[](#news-sitemaps)

```
use Melbahja\Seo\Factory;

$sitemap = Factory::sitemap('https://example.com',
[
    // You can also customize your options by passing array to the factory like this
    'save_path' => './path',
    'sitemaps_url' => 'https://example.com/maps',
    'index_name' => 'news_index.xml'
]);

$sitemap->news('my_news.xml', function($map)
{
    // publication: name, language
    // Google quote about the name: "It must exactly match the name as
    // it appears on your articles on news.google.com"
    $map->setPublication('PHP NEWS', 'en');

    $map->loc('/news/12')->news(
    [
       'title' => 'PHP 8 Released',
       'publication_date' => '2019-03-01T15:30:02+01:00',
    ]);

    $map->loc('/news/13')->news(
    [
        'title' => 'PHP 8 And High Performance',
        'publication_date' => '2019-04-01T15:30:02+01:00'
    ]);
});

$sitemap->save();
```

**Results**

📁: news\_index.xml

```

        https://example.com/maps/my_news.xml
        2019-03-01T15:57:10+01:00

```

📁: my\_news.xml

```

        https://example.com/news/12

                PHP NEWS
                en

            PHP 8 Released
            2019-03-01T15:30:02+01:00

        https://example.com/news/13

                PHP NEWS
                en

            PHP 8 And High Performance
            2019-04-01T15:30:02+01:00

```

**Google quote:** ⚠ "If you submit your News sitemap before your site has been reviewed and approved by our team, you may receive errors." ⚠

#### 🤖 Send Sitemaps To Search Engines

[](#-send-sitemaps-to-search-engines)

According to the sitemaps protocol, search engines should have a url that allow you to inform them about your new sitemap files. like: &lt;searchengine\_URL&gt;/ping?sitemap=sitemap\_url

```
use Melbahja\Seo\Ping;

$ping = new Ping;

// the void method send() will inform via CURL: google, bing and yandex about your new file
$ping->send('https://example.com/sitemap_file.xml');
```

### Indexing API

[](#indexing-api)

This is the first PHP library to support the new search engines indexing API (aka indexnow.org).

```
use Melbahja\Seo\Indexing;

$indexer = new Indexing('www.example.cpm', [
    'bing.com' => 'your_api_key_here',
    'yandex.com' => 'your_api_key_here',
]);

// index single url.
$indexer->indexUrl('https://www.example.com/page');

// index multi urls.
$indexer->indexUrls(['https://www.example.com/page']);
```

Sponsors
--------

[](#sponsors)

Special thanks to friends who support this work financially:

[![EvoluData](https://camo.githubusercontent.com/c37575050989b450198ee829287cff5525d24509c5520cf476bdc7dce9f8904f/68747470733a2f2f7777772e65766f6c75646174612e636f6d2f646973706c6179323038)](https://www.evoludata.com)

References
----------

[](#references)

- [Sitemaps protocol (https://www.sitemaps.org/protocol.html)](https://www.sitemaps.org/protocol.html)
- [Build Sitemaps (https://support.google.com/webmasters/answer/183668?hl=en)](https://support.google.com/webmasters/answer/183668?hl=en)
- [News Sitemaps (https://support.google.com/webmasters/answer/74288)](https://support.google.com/webmasters/answer/74288)
- [Image Sitemaps (https://support.google.com/webmasters/answer/178636)](https://support.google.com/webmasters/answer/178636)
- [Video Sitemaps (https://support.google.com/webmasters/answer/80471)](https://support.google.com/webmasters/answer/80471)
- [Mobile (https://developers.google.com/search/mobile-sites/mobile-seo/other-devices)](https://developers.google.com/search/mobile-sites/mobile-seo/other-devices)

License
-------

[](#license)

[MIT](https://github.com/melbahja/seo/blob/master/LICENSE) Copyright (c) 2019-present Mohamed Elbahja

###  Health Score

18

—

LowBetter than 8% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity8

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity29

Early-stage or recently created project

 Bus Factor1

Top contributor holds 59.7% 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 ~44 days

Total

2

Last Release

894d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/8b0183fae593d83cd5fb3426199ba05ec2d2513b0eb40187e4793a9145256e9d?d=identicon)[broqit](/maintainers/broqit)

---

Top Contributors

[![melbahja](https://avatars.githubusercontent.com/u/8259014?v=4)](https://github.com/melbahja "melbahja (40 commits)")[![broqit](https://avatars.githubusercontent.com/u/27624002?v=4)](https://github.com/broqit "broqit (8 commits)")[![marioquartz](https://avatars.githubusercontent.com/u/3995147?v=4)](https://github.com/marioquartz "marioquartz (8 commits)")[![MekDrop](https://avatars.githubusercontent.com/u/342641?v=4)](https://github.com/MekDrop "MekDrop (5 commits)")[![peter279k](https://avatars.githubusercontent.com/u/9021747?v=4)](https://github.com/peter279k "peter279k (2 commits)")[![marclaporte](https://avatars.githubusercontent.com/u/1004261?v=4)](https://github.com/marclaporte "marclaporte (2 commits)")[![samnela](https://avatars.githubusercontent.com/u/1852108?v=4)](https://github.com/samnela "samnela (1 commits)")[![andriichuk](https://avatars.githubusercontent.com/u/38154251?v=4)](https://github.com/andriichuk "andriichuk (1 commits)")

---

Tags

seoPHP7open-graphmeta-tagsschema.orgsitemapssitemap indexsearch engine optimizationsitemap.xmltwitter tags

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[melbahja/seo

SEO library for PHP is a simple PHP library to help developers 🍻 do better on-page SEO optimizations.

355143.7k4](/packages/melbahja-seo)[coffeecode/optimizer

Optimizer makes it easy to bookmark your site tags, open graph and twitter card

28260.9k2](/packages/coffeecode-optimizer)[devrabiul/laravel-seo-manager

Laravel SEO Manager is an SEO tool that improves SEO by adding recommended meta tags.

404.8k](/packages/devrabiul-laravel-seo-manager)[larament/seokit

A complete SEO package for Laravel, covering everything from meta tags to social sharing and structured data.

411.9k](/packages/larament-seokit)[pedroborges/meta-tags

HTML meta tags generator for PHP.

4628.6k1](/packages/pedroborges-meta-tags)[davmixcool/laravel-meta-manager

Laravel Meta Manager is an SEO tool that is used to improve SEO of a website or specific page by adding recommended meta tags to your application.

15040.8k1](/packages/davmixcool-laravel-meta-manager)

PHPackages © 2026

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