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

ActiveSymfony-bundle[Utility &amp; Helpers](/categories/utility)

gurtok/seo-bundle
=================

Flexible and modern SEO management bundle for Symfony applications

v2.2.0(11mo ago)013MITPHPPHP &gt;=8.1CI passing

Since Apr 30Pushed 11mo ago1 watchersCompare

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

READMEChangelog (5)Dependencies (14)Versions (6)Used By (0)

Gurtok SeoBundle
================

[](#gurtok-seobundle)

Modern and flexible SEO Bundle for Symfony 6/7 projects. Easily manage meta tags, OpenGraph, Twitter cards, canonical URLs, hreflangs, and verification tags.

🧭 Roadmap (Post-2.0)
====================

[](#-roadmap-post-20)

🟥 Priority 1: Full SEO "out-of-the-box"
---------------------------------------

[](#-priority-1-full-seo-out-of-the-box)

- 🧩 Support `JsonLd` + `JsonLdMulti` rendering helpers
- 🧠 Add schema.org presets (Article, Product, Event, etc.)
- 🌐 Integrate with sitemap generator (e.g., via Symfony event or SitemapProviderInterface)
- 🧷 Provide Google Tag Manager (GTM) support
- 🧲 Provide Meta Pixel support (Facebook)

🟧 Priority 2: Enhanced social sharing support
---------------------------------------------

[](#-priority-2-enhanced-social-sharing-support)

- 🖼️ `og:image` object support: `url`, `width`, `height`, `alt`, `type`
- 🎥 `og:video` support with full metadata
- 🧵 Multiple `og:image` / `og:video` entries
- 🎯 `og:type` configuration (article, product, etc.)
- 📌 Pinterest meta tags (`pinterest:description`, `pinterest:image`)
- 💼 LinkedIn-specific sharing optimization

🟨 Priority 3: Developer Experience &amp; Flexibility
----------------------------------------------------

[](#-priority-3-developer-experience--flexibility)

- 🧰 Symfony UX Component for real-time preview of tags in dev mode
- 🧪 PHPUnit constraint: `assertSeoRenderedContains($tag)`
- 🧬 Full extensibility via custom `SeoRenderStrategyInterface`
- 📦 Export configuration to JSON/LD, XML for third-party SEO analysis
- 📖 Recipe / packagist recipe for easy install with Flex

✅ Done
------

[](#-done)

- Rewrite listeners for flexibility and testability
- Add support for localized defaults (en/uk/…) and translatable attributes
- Add `SeoMetaRenderOptions` (include\_title, skip\_empty, etc.)
- Add `SeoTagHtmlBuilder` for rendering
- Add new SeoMeta flags (noIndex, disableDefaults, etc.)
- Add canonical generator with query filtering
- Add granular disabling via config/environment

---

📦 Installation
--------------

[](#-installation)

Require the bundle via Composer:

```
composer require gurtok/seo-bundle
```

If you're using Symfony Flex, the bundle will be registered automatically. Otherwise, manually add to `config/bundles.php`:

```
return [
    Gurtok\SeoBundle\GurtokSeoBundle::class => ['all' => true],
];
```

---

⚙️ Configuration
----------------

[](#️-configuration)

Create a config file `config/packages/gurtok_seo.yaml`:

```
gurtok_seo:
    allow_custom_meta: false         # Allow setting custom meta tags (true/false)
    auto_inject_response: true       # Auto-insert SEO meta into  if not manually called
    excluded_paths:
        - '/admin'
        - '/api'
    canonical_excluded_query_keys:
        - 'utm_source'
        - 'utm_medium'
        - 'utm_campaign'
        - 'utm_term'
        - 'utm_content'
        - 'ref'
        - 'fbclid'
        - 'page'
    defaults:
        title: { en: 'Default Title', uk: 'Типовий заголовок' } # Default title for the site
        title_separator: ' | '
        description: { en: 'Default description', uk: 'Типовий опис' }
        auto_canonical: true         # Automatically generate canonical URL
        meta:
            robots: 'index, follow'
        og:
            type: 'website'
        twitter:
            card: 'summary_large_image'
        verifications:
            google-site-verification: 'abc123'
        no_index: false              # Set to true if the site should not be indexed by search engines
        is_adult_content: false      # Set to true if the content is adult-oriented and will be marked as such
```

**Note:**The default locale is automatically taken from `%kernel.default_locale%` (usually configured in `framework.yaml`).

Example `framework.yaml`:

```
framework:
    default_locale: 'en'
```

---

🚀 Usage
-------

[](#-usage)

### Using the Attribute on Controllers

[](#using-the-attribute-on-controllers)

You can define SEO metadata directly via PHP 8+ attributes:

```
use Gurtok\SeoBundle\Attribute\SeoMeta;

#[SeoMeta(
    title: 'Homepage',
    titlePrefix: 'MySite',
    titleSeparator: ' ~ ',
    description: 'Welcome to our amazing website!',
    canonical: 'https://example.com',
    meta: ['robots' => 'index, follow'],
    og: [
        'title' => 'Homepage OG',
        'image' => 'https://example.com/image.jpg',
    ],
    twitter: ['card' => 'summary_large_image'],
    verifications: ['google-site-verification' => 'your-verification-code'],
    hreflangs: [
        'en' => 'https://example.com',
        'uk' => 'https://example.com/uk'
    ],
    noIndex: false,
    isAdultContent: false,
    disableDefaults: false
)]
public function __invoke()
{
    // ...
}
```

You can place the attribute either **on the controller method** or **on the class** — method attribute has priority.

---

### Localized Titles and Descriptions

[](#localized-titles-and-descriptions)

You can specify translations via arrays:

```
#[SeoMeta(
    title: [
        'en' => 'Homepage',
        'uk' => 'Головна сторінка'
    ],
    description: [
        'en' => 'Welcome!',
        'uk' => 'Ласкаво просимо!'
    ]
)]
```

The bundle automatically detects the current request locale (`RequestStack`) and uses the localized value. Fallback is the default locale from `%kernel.default_locale%`, or the first available value.

---

🎨 Twig integration
------------------

[](#-twig-integration)

In your Twig layout (`base.html.twig`):

```

    {{ seo() }}

```

This will render:

- `` tag
- `` description
- `` robots
- OpenGraph tags
- Twitter card tags
- Canonical link
- Hreflang alternate links
- Verification meta tags

---

### 🔍 Twig Functions

[](#-twig-functions)

Twig FunctionDescription`seo()`Renders everything (title + meta + OG + Twitter + etc)`seo_title()`Renders only `` tag`seo_meta()`Renders only `` tags`seo_og()`Renders OpenGraph tags`seo_open_graph()`Alias for `seo_og()``seo_twitter()`Renders Twitter card tags`seo_hreflangs()`Renders hreflang links`seo_verification()`Renders verification tags---

### ⚙️ Twig Function Options

[](#️-twig-function-options)

Functions `seo()` and `seo_meta()` accept an optional options array:

```
{{ seo({ include_title: true, skip_empty: true }) }}
```

- `include_title` (bool, default `true`) — whether to include the `` tag.
- `skip_empty` (bool, default `true`) — skip rendering empty meta fields.

---

🔥 Auto Injection (Optional)
---------------------------

[](#-auto-injection-optional)

If you forget to call `{{ seo() }}` manually in Twig, and `auto_inject_response` is enabled (default `true`), SeoBundle will automatically inject SEO meta before `` during the HTTP Response phase.

---

📘 Full Example
--------------

[](#-full-example)

```
# config/packages/gurtok_seo.yaml
gurtok_seo:
    allow_custom_meta: true
    auto_inject_response: true
    excluded_paths:
        - '/admin'
        - '/api'
```

Controller:

```
use Gurtok\SeoBundle\Attribute\SeoMeta;

#[SeoMeta(
    title: 'Blog',
    titleSeparator: ' * ',
    description: 'Latest articles and news.',
    og: ['title' => 'Blog OG', 'type' => 'website'],
    twitter: ['card' => 'summary'],
)]
class BlogController
{
    public function __invoke(SeoManager $seoManager)
    {
        // get post data, from database or API
        $seoManager->setTitlePrfix('Post Name');

        // ...
    }
}
```

Twig:

```

    {{ seo() }}

```

Result in HTML:

```
Post * Blog

```

---

📄 License
---------

[](#-license)

SeoBundle is open-sourced software licensed under the [MIT license](LICENSE).

---

###  Health Score

30

—

LowBetter than 64% of packages

Maintenance50

Moderate activity, may be stable

Popularity5

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity49

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 95.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 ~7 days

Total

5

Last Release

352d ago

Major Versions

v1.0.0 → v2.0.02025-05-28

### Community

Maintainers

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

---

Top Contributors

[![yuriiborovchuk](https://avatars.githubusercontent.com/u/181962335?v=4)](https://github.com/yuriiborovchuk "yuriiborovchuk (20 commits)")[![yurez](https://avatars.githubusercontent.com/u/1506500?v=4)](https://github.com/yurez "yurez (1 commits)")

---

Tags

symfonyseo

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

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

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

###  Alternatives

[pentatrion/vite-bundle

Vite integration for your Symfony app

2725.3M13](/packages/pentatrion-vite-bundle)[winzou/state-machine-bundle

Bundle for the very lightweight yet powerful PHP state machine

34010.4M15](/packages/winzou-state-machine-bundle)[maba/webpack-bundle

Bundle to Integrate Webpack to Symfony

123268.2k4](/packages/maba-webpack-bundle)[elao/accesseo

Provide accessibility and SEO insights of your page in Symfony profiler

299.2k](/packages/elao-accesseo)[rumenx/php-seo

AI-powered, framework-agnostic PHP package for automated SEO optimization. Intelligently generates meta tags, titles, descriptions, and alt texts using configurable AI providers or manual patterns.

102.0k](/packages/rumenx-php-seo)

PHPackages © 2026

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