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

ActiveLibrary

melbahja/seo
============

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

v3.0.3(2mo ago)355143.7k—5%534MITPHPPHP &gt;=8.1CI passing

Since Mar 2Pushed 1mo ago6 watchersCompare

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

READMEChangelogDependencies (2)Versions (13)Used By (4)

PHP SEO
=======

[](#php-seo)

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

[![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)

### PHP SEO features:

[](#php-seo-features)

- [\[👷\]](#-generate-schemaorg) **Generate Rich Results schema.org ld+json**
- [\[🛀\]](#-meta-tags) **Generate Meta Tags with X (Twitter) and Open Graph Support**
- [\[🌐\]](#-sitemaps) **Generate XML Sitemaps (supports: 📰 News Sitemaps, 🖼 Images Sitemaps, 📹 Video Sitemaps, Index Sitemaps)**
- [\[📤\]](#-indexing-api) **IndexNow and Google Indexing API**
- \[✅\] **Schema Rich Results Validator**
- [\[🧩\]](https://github.com/melbahja/seo/blob/master/composer.json) **Zero Dependencies**

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

[](#installation)

```
composer require melbahja/seo
```

Documentation
-------------

[](#documentation)

You can read the docs [Here](https://elbahja.me/docs/seo/).

Usage:
------

[](#usage)

Check this simple examples.

#### 👷 Generate schema.org

[](#-generate-schemaorg)

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

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

echo $schema;
```

**Results:** (formatted)

```

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

```

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

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

$webpage = new 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": [
        {
            "@type": "Product",
            "@context": "https:\/\/schema.org",
            "name": "Foo Bar",
            "sku": "sk12",
            "image": "\/image.jpeg",
            "description": "testing",
            "offers": {
                "@type": "Offer",
                "@context": "https:\/\/schema.org",
                "availability": "https:\/\/schema.org\/InStock",
                "priceCurrency": "USD",
                "price": "119.99",
                "url": "https:\/\/gool.com"
            }
        },
        {
            "@type": "WebPage",
            "@context": "https:\/\/schema.org",
            "@id": "https:\/\/example.com\/product\/#webpage",
            "url": "https:\/\/example.com\/product",
            "name": "Foo Bar"
        }
    ]
}
```

#### 🛀 Meta Tags

[](#-meta-tags)

```
use Melbahja\Seo\MetaTags;

$metatags = new MetaTags();

$metatags
        ->title('PHP SEO')
        ->description('This is my description')
        ->meta('author', 'Mohamed Elbahja')
        ->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')
        ->robots(['index', 'follow', 'max-snippet' => -1])
        ->robots(botName: 'bingbot', options: ['index', 'nofollow'])
        ->feed("https://example.com/feed.rss")
        ->verification("google", "token_value")
        ->verification("yandex", "token_value")
        ->hreflang("de", "https://de.example.com")
        ->og("type", "website")
        ->twitter("creator", "Mohamed Elbahja");
        // ->schema($schema)

echo $metatags;
```

**Results:**

```
PHP SEO

```

🗺 Sitemaps
==========

[](#-sitemaps)

Generate XML sitemaps with support for images, videos, news, and localized URLs.

Basic Usage
-----------

[](#basic-usage)

```
use Melbahja\Seo\Sitemap;

$sitemap = new Sitemap(
    baseUrl: 'https://example.com',
    saveDir: '/path/to_save/files',
);

$sitemap->links('blog.xml', function($map)
{
    $map->loc('/blog')
            ->changeFreq('daily')
            ->priority(0.8)
            ->loc('/blog/my-new-article')
            ->changeFreq('weekly')
            ->lastMod('2024-01-15')
            ->loc('/اهلا-بالعالم')
            ->changeFreq('weekly');

    $map->loc('/blog/hello')->changeFreq('monthly');
});

$sitemap->render();
```

Options
-------

[](#options)

OptionDescriptionRequiredDefault`saveDir`Generated sitemaps storage pathYes-`sitemapBaseUrl`Custom URL for generated sitemapsNoBase URL`indexName`Custom sitemap index nameNositemap.xml`mode`Output mode (FILE, MEMORY, STREAM, TEMP)NoTEMPURL Methods
-----------

[](#url-methods)

```
$builder->loc('/page')               // URL path relative or absolute
        ->priority(0.8)              // Priority 0.0-1.0
        ->changeFreq('weekly')       // always, hourly, daily, weekly, monthly, yearly, never
        ->lastMod('2024-01-15')      // Last modified date in string or unix ts
        ->image('/image.jpg')        // Add image (requires 'images' => true)
        ->video('Title', [...])      // Add video (requires 'videos' => true)
        ->alternate('/es/page', 'es'); // Add hreflang alternate
```

Advanced Features
-----------------

[](#advanced-features)

### Image Sitemaps

[](#image-sitemaps)

```
$sitemap->links(['name' => 'gallery.xml', 'images' => true], function($builder)
{
    $builder->loc('/gallery/1')
            ->image('/images/photo1.jpg', [
                'title' => 'Photo Title',
                'caption' => 'Photo caption'
            ]);
});
```

### Video Sitemaps

[](#video-sitemaps)

```
$sitemap->links(['name' => 'videos.xml', 'videos' => true], function($builder)
{
    $builder->loc('/video/page')
            ->video('Video Title', [
                'thumbnail' => '/thumb.jpg',
                'description' => 'Video description',
                'content_loc' => '/video.mp4'
            ]);
});
```

### News Sitemaps

[](#news-sitemaps)

```
use Melbahja\Seo\Sitemap\NewsBuilder;

$sitemap->news('news.xml', function(NewsBuilder $builder)
{
    $builder->setPublication('Your News', 'en');

    $builder->loc('/article/1')
            ->news([
                'title' => 'Article Title',
                'publication_date' => '2024-01-15T10:00:00Z',
                'keywords' => 'news, breaking'
            ]);
});
```

### Multilingual Sitemaps

[](#multilingual-sitemaps)

```
$sitemap->links(['name' => 'multilang.xml', 'localized' => true], function($builder)
{
    $builder->loc('/page')
            ->alternate('/es/page', 'es')
            ->alternate('/fr/page', 'fr');
});
```

Output Modes
------------

[](#output-modes)

### TEMP Mode (Default)

[](#temp-mode-default)

```
$sitemap = new Sitemap('https://example.com',
[
    'saveDir' => './storage',
    'mode' => OutputMode::TEMP
]);
$sitemap->render(); // Saves to temp dir and save to disk only on generation success.
```

### File Mode

[](#file-mode)

```
$sitemap = new Sitemap('https://example.com',
[
    'saveDir' => './storage',
    'mode' => OutputMode::FILE
]);
$sitemap->render(); // Saves to disk
```

### Memory Mode

[](#memory-mode)

```
$sitemap = new Sitemap('https://example.com', [
    'mode' => OutputMode::MEMORY
]);
$xml = $sitemap->render(); // Returns XML string
```

### Stream Mode

[](#stream-mode)

```
$stream = fopen('sitemap.xml', 'w');
$builder = new LinksBuilder(
    baseUrl: 'https://example.com',
    stream: $stream, // defaults to stdout
    mode: OutputMode::STREAM,
);
$builder->loc('/page')->render();
fclose($stream);
```

Complete Example
----------------

[](#complete-example)

```
$sitemap = new Sitemap(baseUrl: 'https://example.com', options: [
    'saveDir' => './sitemaps',
    'indexName' => 'sitemap-index.xml'
]);

// Regular pages y can just pass array of links
$sitemap->links('pages.xml', ['/', '/about', '/contact']);

// Products with images
$sitemap->links(['name' => 'products.xml', 'images' => true], function($builder)
{
    $builder->loc('/product/123')
            ->priority(0.9)
            ->image('/product-main.jpg', ['title' => 'Product Image']);
});

// News section
$sitemap->news('news.xml', function($builder)
{
    $builder->setPublication('Tech News', 'en');
    $builder->loc('/article/1')
            ->news(['title' => 'New Article', 'publication_date' => date('c')]);
});

// Generate everything
$sitemap->render();
// Creates: sitemap-index.xml, pages.xml, products.xml, news.xml
```

### Indexing API

[](#indexing-api)

Submit URLs to search engines for instant indexing using Google Indexing API and IndexNow protocol.

#### Google Indexing API

[](#google-indexing-api)

```
use Melbahja\Seo\Indexing\GoogleIndexer;
use Melbahja\Seo\Indexing\URLIndexingType;

$indexer = new GoogleIndexer('your-google-access-token');

// Index single URL
$indexer->submitUrl('https://www.example.com/page');

// Index multiple URLs
$indexer->submitUrls([
    'https://www.example.com/page1',
    'https://www.example.com/page2'
]);

// Delete URL from index
$indexer->submitUrl('https://www.example.com/deleted-page', URLIndexingType::DELETE);
```

#### IndexNow Protocol

[](#indexnow-protocol)

```
use Melbahja\Seo\Indexing\IndexNowIndexer;

$indexer = new IndexNowIndexer('your-indexnow-api-key');

// Submit to all supported engines
$indexer->submitUrl('https://www.example.com/page');

// Submit multiple URLs
$indexer->submitUrls([
    'https://www.example.com/page1',
    'https://www.example.com/page2'
]);
```

AI LLMs.txt Support
-------------------

[](#ai-llmstxt-support)

If you find LLMs.txt valuable for your use case, contributions are welcome! Feel free to submit a PR.

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) Mohamed Elbahja

###  Health Score

64

—

FairBetter than 99% of packages

Maintenance86

Actively maintained with recent releases

Popularity53

Moderate usage in the ecosystem

Community28

Small or concentrated contributor base

Maturity76

Established project with proven stability

 Bus Factor1

Top contributor holds 83.2% 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 ~255 days

Recently: every ~316 days

Total

11

Last Release

82d ago

Major Versions

v1.0.2 → v2.0.02021-10-26

v2.1.1 → v3.0.02026-01-19

PHP version history (3 changes)v1.0.0PHP &gt;=7.1

v2.0.1PHP &gt;=7.2

v3.0.0PHP &gt;=8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/67b45037a03b3a6ed6cc118eb636a3cc544366594e8dc460f9f87fe30dc6bd6b?d=identicon)[melbahja](/maintainers/melbahja)

---

Top Contributors

[![melbahja](https://avatars.githubusercontent.com/u/8259014?v=4)](https://github.com/melbahja "melbahja (99 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)")[![marclaporte](https://avatars.githubusercontent.com/u/1004261?v=4)](https://github.com/marclaporte "marclaporte (3 commits)")[![peter279k](https://avatars.githubusercontent.com/u/9021747?v=4)](https://github.com/peter279k "peter279k (2 commits)")[![andriichuk](https://avatars.githubusercontent.com/u/38154251?v=4)](https://github.com/andriichuk "andriichuk (1 commits)")[![samnela](https://avatars.githubusercontent.com/u/1852108?v=4)](https://github.com/samnela "samnela (1 commits)")

---

Tags

google-indexing-apiindexing-apiindexnowjson-ldmetatagsphpphp8robots-txtschema-orgsearch-engine-optimizationseoseo-metaseo-metadataseo-optimizationseo-toolsseotoolssitemapsitemap-buildersitemap-generatorsitemap-xmlseophp8open-graphmeta-tagsschema.orgsitemapssitemap indexsearch engine optimizationsitemap.xmltwitter tagsrich resultsimages sitemapsvideo sitemapsindex sitemapsnews sitemaps

###  Code Quality

TestsPHPUnit

### Embed Badge

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

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

###  Alternatives

[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)[brotkrueml/schema

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

33584.6k13](/packages/brotkrueml-schema)

PHPackages © 2026

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