Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php Seo Laravel Package

rumenx/php-seo

A lightweight PHP SEO library for generating meta tags, Open Graph and Twitter Card data, canonical URLs, sitemaps, and robots directives. Simple fluent API, framework-agnostic, and easy to integrate into Laravel or any PHP app.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer and confirm your PHP version matches the package requirement (8.1+ is typical for AI-SDK-backed libraries):

composer require rumenx/php-seo

Where to look first

  1. README.md — the primary usage example for the entry class (often Rumenx\PhpSeo\Seo or an SeoManager/SeoOptimizer equivalent). Copy the constructor signature exactly; the package is framework-agnostic, so there is no facade autoloading magic to fall back on.
  2. src/Providers/ (or src/Ai/) — this is where the OpenAI/Anthropic/other AI drivers live. Check which providers and model names are actually supported before you wire config.
  3. config/ if present — provider selection, API key resolution, model, temperature, and max-token settings usually live here. If there's no published config, config is passed as a constructor array.

First use case: generate meta for a blog post

The lowest-friction entry point is one-shot generation from raw content:

use Rumenx\PhpSeo\Seo;

$seo = new Seo([
    'provider' => 'openai',
    'api_key'  => $_ENV['OPENAI_API_KEY'],
    'model'    => 'gpt-4o-mini',
]);

$result = $seo->generate($post->body); // or ->optimize(), ->analyze()

echo $result->title;        // <= 60 chars ideally
echo $result->description;  // <= 160 chars ideally
print_r($result->metaTags); // assoc array of name => content

Start with generate() on a single known article, dump the result, and inspect it before integrating. Verify the exact method names against the README — this package is young and pre-1.0 APIs move.

First integration target: a Laravel/Symfony controller or console command that takes existing content and returns a rendered <head> block. Do not start with batch processing; start with one page, eyeball the output, then scale.

Implementation Patterns

Wrap it in a service, never call it from views. Because it's framework-agnostic, treat it like any third-party SDK:

final class SeoService
{
    public function __construct(private Seo $seo) {}

    public function forPost(Post $post): SeoResult
    {
        return Cache::rememberForever(
            "seo:post:{$post->id}:".md5($post->body),
            fn () => $this->seo->generate($post->body)
        );
    }
}

Bind Seo as a singleton in a service provider so the HTTP client and config are reused.

Cache by content hash, not by model ID. AI output is expensive and non-deterministic; the hash key naturally invalidates when the article is edited.

Queue everything that isn't a page render. Generation typically takes 1–5 seconds per call. Dispatch a job on model save (PostSaved → GenerateSeoMetadata) that writes results back into seo_title, seo_description, og_image_alt columns. This keeps request latency flat and gives you retries for free.

Hybrid fallback pipeline. Use deterministic heuristics (first 160 chars, H1 as title) as the default, and only overwrite with AI output when it passes validation (length, non-empty, no markdown fences). This is the single biggest reliability win:

$ai = $this->seoService->forPost($post);
$title = $this->validTitle($ai->title) ? $ai->title : Str::limit($post->title, 60);

Render through a Blade partial, not string concatenation. Emit meta tags via @foreach over the returned array and run values through e(). It keeps escaping and deduplication in one place:

@foreach ($meta as $name => $content)
    <meta name="{{ $name }}" content="{{ $content }}">
@endforeach

Alt-text generation belongs in the upload/media pipeline. Trigger it after the image is stored, pass the image path/URL, and write the result to the media record. Pair it with a vision-capable model — text-only models will hallucinate descriptions.

Batch/backfill via a console command. Loop over records, process in chunks of 10–20, throttle between calls, and log failures per-record. Never foreach 5,000 posts in a single synchronous command.

Provider abstraction for local dev. Configure a cheap/fast model in local and testing, and the production model only in production. If the package allows a null/no-op provider, use it in tests so CI never spends money.

Framework integration tips

  • Laravel: singleton binding + a queued job + a seo_metadata JSON column. Publish config if available with php artisan vendor:publish.
  • Symfony: register the client as a service in services.yaml, inject into a SeoGenerator service, and use Messenger for async.
  • Slim/plain PHP: instantiate once in your bootstrap/DI container and pass down; keep the API key in environment, not in the file.

Gotchas and Tips

It's pre-1.0 and low-adoption. Pin an exact version ("rumenx/php-seo": "0.x.y") and read the CHANGELOG before every bump. With near-zero dependents, you are effectively the QA team — expect to read src/ when the README is thin.

Non-deterministic output breaks tests. Never assert exact generated strings. Mock the underlying HTTP/AI client, or assert only on structural constraints (strlen <= 160, is_string, key presence).

Length limits are guidance, not guarantees. The model will sometimes return a 200-character description. Truncate defensively with multibyte-safe functions (mb_substr, Str::limit), and trim on a word boundary to avoid chopped words.

AI responses can be wrapped in markdown fences or JSON prologues. If the package asks the model for structured output, still validate. A json_decode returning null should fall through to your heuristic path, not throw a 500 on a page render.

Escape everything at render time. AI can and will echo HTML from the source content. If you inject content into a meta tag without htmlspecialchars/e(), you have an XSS vector.

Cost and rate limits. Add a per-run token/request budget, honor 429 responses with exponential backoff, and log token usage per generation so you can attribute cost to features. One un-cached page render per request is the classic way to burn a monthly budget in an afternoon.

API key resolution. Prefer environment variables over constructor args committed to config files. Confirm the package's precedence order (env vs. constructor vs. config file) — mismatches here cause "works locally, fails in prod."

Watch for silent provider failures. AI SDKs often return an empty string rather than throwing. Always check for empty/null output before persisting; otherwise you'll overwrite good metadata with blanks during a provider outage.

Debugging checklist when generation returns garbage: (1) dump the raw response before parsing, (2) confirm you're passing the article body and not the HTML wrapper/nav, (3) check the model name is still valid — providers deprecate models regularly, (4) verify temperature isn't set high, (5) confirm your prompt/template isn't being overridden by config.

Extension points to look for: a provider interface you can implement for a custom LLM endpoint, configurable prompt templates (so you can enforce brand voice and output format), and any events/hooks fired around generation. Custom prompts are usually the highest-leverage customization — pinning exact output format ("respond with JSON: title, description, keywords") removes most of the parsing fragility.

Don't let AI own canonical/robots tags. Generate titles, descriptions, keywords, OG tags, and alt text with AI; keep canonical, robots, hreflang, and structured data (application/ld+json) deterministic. Those are SEO correctness issues, not creative ones.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator