SEO
The SeoFactory is a wrapper for melbahja/seo. Check out the documentation for more info.
Generate Schema.org
<?php
use App\Shared\Services\SeoFactory;
$schema = SeoFactory::schema(
    SeoFactory::thing('Website', [
        'url'          => site_url(),
        'logo'         => site_url('static/assets/img/auth/auth-logo.png'),
        'contactPoint' => SeoFactory::thing('ContactPoint', [
            'telephone' => '+1-000-555-1212',
            'contactType' => 'customer service'
        ])
    ])
);
echo '<script type="application/ld+json">' . "\n" . json_encode($schema, JSON_PRETTY_PRINT) . "\n" . '</script>';
Results
<script type="application/ld+json">
{
    "@context": "https://schema.org",
    "@graph": [
        {
            "url": "http://localhost:8080/",
            "logo": "http://localhost:8080/static/assets/img/auth/auth-logo.png",
            "contactPoint": {
                "telephone": "+1-000-555-1212",
                "contactType": "customer service",
                "@type": "ContactPoint",
                "@context": "https://schema.org/"
            },
            "@type": "Website",
            "@context": "https://schema.org/"
        }
    ]
}
</script>
Meta Tags
<?php
use App\Shared\Services\SeoFactory;
use function App\Shared\Helpers\site_url;
$metaTags = SeoFactory::metaTags()
    ->title('Developer Blog')
    ->description('Blog featuring PHP tips and tricks.')
    ->meta('author', 'Joshua Parker')
    ->image('https://www.gravatar.com/avatar/cc144b35b739d6b30cea73a24469377c?s=160')
    ->canonical(site_url());
echo $metaTags;
Results
<meta name="title" content="Developer Blog" />
<meta name="description" content="Blog featuring PHP tips and tricks." />
<meta name="author" content="Joshua Parker" />
<link rel="canonical" href="http://localhost:8080/" />
<meta property="twitter:title" content="Developer Blog" />
<meta property="twitter:description" content="Blog featuring PHP tips and tricks." />
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:image" content="https://www.gravatar.com/avatar/cc144b35b739d6b30cea73a24469377c?s=160" />
<meta property="og:title" content="Developer Blog" />
<meta property="og:description" content="Blog featuring PHP tips and tricks." />
<meta property="og:image" content="https://www.gravatar.com/avatar/cc144b35b739d6b30cea73a24469377c?s=160" />
Sitemaps
$sitemap = SeoFactory::sitemap(string $url, array $options = []): SitemapIndexInterface;
| Option Name | Description | Required? | Default | 
|---|---|---|---|
| save_path | Generated sitemaps storage path. | Yes | |
| sitemaps_url | Sitemap index custom url for generated sitemaps. | No | $url | 
| index_name | Custom sitemap index name. | No | sitemap.xml | 
<?php
use App\Shared\Services\SeoFactory;
use function Codefy\Framework\Helpers\public_path;
$sitemap = SeoFactory::sitemap('https://myblog.com', ['save_path' => public_path()]);
$sitemap->links('blog.xml', function ($map) {
    $map->loc('/')->freq('weekly')->priority('1.0')
            ->loc('/devflow-a-headless-framework-for-php-programmers')->freq('weekly')->lastMod('2024-12-01')
            ->loc('/devflow-cmf-vs-wordpress-wordpress-alternative')->freq('weekly');
    $map->loc('/problems-devflow-solve-for-developers')->freq('weekly');
});
return $sitemap->save();
Results
sitemap.xml (formatted)
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by https://git.io/phpseo -->
<sitemapindex
        xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <sitemap>
        <loc>https://myblog.com/blog.xml</loc>
        <lastmod>2025-02-14T00:39:49-08:00</lastmod>
    </sitemap>
</sitemapindex>
blog.xml (formatted)
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated by https://git.io/phpseo -->
<urlset
        xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <loc>https://myblog.com/</loc>
        <changefreq>weekly</changefreq>
        <priority>1.0</priority>
    </url>
    <url>
        <loc>https://myblog.com/devflow-a-headless-framework-for-php-programmers</loc>
        <changefreq>weekly</changefreq>
        <lastmod>2024-12-01T00:00:00-08:00</lastmod>
    </url>
    <url>
        <loc>https://myblog.com/devflow-cmf-vs-wordpress-wordpress-alternative</loc>
        <changefreq>weekly</changefreq>
    </url>
    <url>
        <loc>https://myblog.com/problems-devflow-solve-for-developers</loc>
        <changefreq>weekly</changefreq>
    </url>
</urlset>
Sending Sitemaps to Search Engines
Based on the sitemaps protocol, search engines normally would have a url structure for submitting your sitemaps to: 
<searchengine_URL>/ping?sitemap=sitemap_url
<?php
use App\Shared\Services\SeoFactory;
use function App\Shared\Helpers\site_url;
$ping = SeoFactory::ping();
$ping->send(site_url('sitemap.xml'));
Indexing
Supports Indexing API (indexnow.org).
<?php
use App\Shared\Services\SeoFactory;
use function App\Shared\Helpers\site_url;
$indexer = SeoFactory::indexing(site_url(), [
    'bing.com' => 'your_api_key_here',
    'yandex.com' => 'your_api_key_here',
]);
// index single url
$indexer->indexUrl(site_url('devflow-a-headless-framework-for-php-programmers'));
// index multiple urls
$indexer->indexUrls([
    site_url('devflow-a-headless-framework-for-php-programmers'),
    site_url('problems-devflow-solve-for-developers'),
]);