Weave Code
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

Seotools Laravel Package

artesaos/seotools

SEOTools adds SEO helpers to Laravel and Lumen: set page titles and meta tags, manage Open Graph and Twitter Card data, and generate JSON-LD structured data. Simple API, easy configuration, works with Laravel package discovery.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require artesaos/seotools
    

    Laravel 5.5+ auto-discovers the package; for older versions, register the SEOToolsServiceProvider in config/app.php.

  2. Publish Config:

    php artisan vendor:publish --provider="Artesaos\SEOTools\Providers\SEOToolsServiceProvider"
    

    This generates config/seotools.php for customization.

  3. First Use Case: In a controller, set basic meta tags for a page:

    use Artesaos\SEOTools\Facades\SEOMeta;
    
    public function show()
    {
        SEOMeta::setTitle('My Page Title');
        SEOMeta::setDescription('A brief description of the page.');
        return view('page');
    }
    
  4. Verify Output: Inspect the rendered HTML (<head> section) to confirm tags like <title> and <meta name="description"> are present.


Implementation Patterns

Core Workflows

1. Basic Meta Tags

Use SEOMeta for standard SEO tags:

SEOMeta::setTitle('Blog Post');
SEOMeta::setDescription('Detailed summary of the post.');
SEOMeta::setCanonical(url('/posts/123'));
SEOMeta::addKeyword(['laravel', 'seo', 'tips']);

2. Social Media Optimization

OpenGraph (Facebook, LinkedIn):

OpenGraph::setTitle('Post Title')
    ->setUrl(url('/posts/123'))
    ->addImage(url('images/post-123.jpg'))
    ->addProperty('article:published_time', now()->toW3CString());

Twitter Cards:

TwitterCard::setTitle('Post Title')
    ->setSite('@myhandle')
    ->setDescription('Tweet-friendly summary')
    ->addImage(url('images/twitter-card.jpg'));

3. Structured Data (JSON-LD)

For rich snippets (e.g., articles, products):

JsonLd::setTitle('Product Name')
    ->setDescription('Product details.')
    ->setType('Product')
    ->addProperty('price', 19.99)
    ->addProperty('availability', 'https://schema.org/InStock');

Multi-Type JSON-LD (e.g., combining Article and Breadcrumb):

JsonLdMulti::setTitle('Article Title')
    ->setType('Article')
    ->addProperty('headline', 'Article Headline');

if (!JsonLdMulti::isEmpty()) {
    JsonLdMulti::newJsonLd();
    JsonLdMulti::setType('Breadcrumb');
    JsonLdMulti::addProperty('itemListElement', [
        ['position' => 1, 'name' => 'Home'],
        ['position' => 2, 'name' => 'Blog']
    ]);
}

4. Dynamic Content Handling

Use view composers or middleware to set SEO tags dynamically:

// In a composer
public function compose(View $view)
{
    $post = Post::find(1);
    SEOMeta::setTitle($post->title);
    OpenGraph::setImage($post->featured_image_url);
}

Middleware Example:

public function handle($request, Closure $next)
{
    SEOMeta::setTitle(config('app.name') . ' | ' . $request->route()->getName());
    return $next($request);
}

5. Reusable Components

Create a base controller or trait for common SEO logic:

trait SEOable
{
    protected function setSEO($model)
    {
        SEOMeta::setTitle($model->title);
        SEOMeta::setDescription($model->excerpt);
        OpenGraph::setImage($model->image_url);
        JsonLd::setType('Article')->setAuthor($model->author);
    }
}

Integration Tips

Blade Directives

Render SEO tags directly in Blade:

@seotools

API Responses

For SPAs or APIs, return SEO data in JSON:

return response()->json([
    'seo' => [
        'title' => 'API Response',
        'description' => 'Data fetched via API',
        'og_image' => url('images/api-logo.png')
    ]
]);

Testing

Use SEOTools::generate() to test rendered tags in PHPUnit:

$html = SEOTools::generate();
$this->assertStringContainsString('<title>Test Page</title>', $html);

Gotchas and Tips

Pitfalls

  1. Facades vs. Direct Service Binding

    • Lumen: Facades are unsupported; use app('seotools') directly.
    • Laravel: Prefer facades for readability, but bind services directly in tests to avoid global state issues.
  2. Overriding Defaults

    • Custom seotools.php config values do not override dynamically set values. Use SEOMeta::setTitle() to force updates.
  3. JSON-LD Validation

    • Invalid JSON-LD (e.g., missing required fields) may cause schema markup to fail validation tools like Google's Rich Results Test.
    • Fix: Validate with JsonLd::generate() before rendering.
  4. Duplicate Meta Tags

    • Setting the same meta tag multiple times (e.g., SEOMeta::setDescription() twice) will overwrite previous values.
    • Fix: Use SEOMeta::addMeta() for non-overwriting additions (e.g., custom properties).
  5. URL Generation

    • Always use url() or route() helpers for canonical/og:url to avoid hardcoding paths.
    • Example:
      SEOMeta::setCanonical(url()->current()); // Dynamic canonical
      
  6. Image Optimization

    • OpenGraph/Twitter images must be publicly accessible and high-resolution (minimum 1200x630px for OG).
    • Tip: Use Storage::url() for local files:
      OpenGraph::addImage(Storage::url('images/post.jpg'));
      

Debugging Tips

  1. Inspect Rendered HTML Use browser dev tools to verify tags:

    <!-- Check for -->
    <meta property="og:title" content="Expected Title">
    <script type="application/ld+json">...</script>
    
  2. Log Generated Tags Temporarily log output in a controller:

    dd(SEOTools::generate());
    
  3. Validate Structured Data

  4. Clear Cached Views If changes aren’t reflected, clear Laravel’s view cache:

    php artisan view:clear
    

Extension Points

  1. Custom Meta Tags Extend SEOMeta for project-specific tags:

    SEOMeta::addMeta('custom:property', 'value', 'property');
    
  2. Dynamic OpenGraph Types Create a helper for common OG types (e.g., articles, products):

    OpenGraph::setArticleType($post)
        ->setTitle($post->title)
        ->setPublishedTime($post->published_at)
        ->addAuthor($post->author);
    
  3. Middleware for SEO Auto-set SEO tags based on request:

    public function handle($request, Closure $next)
    {
        if ($request->route()->getName() === 'blog.post') {
            SEOMeta::setTitle($request->post->title);
        }
        return $next($request);
    }
    
  4. Service Provider Extensions Bind custom SEO services:

    $this->app->bind('seotools.custom', function () {
        return new CustomSEOService();
    });
    
  5. Localization Use Laravel’s localization features to switch SEO content:

    SEOMeta::setTitle(__('seo.title.home'));
    OpenGraph::setDescription(__('seo.description.home'));
    

Configuration Quirks

  1. Defaults in seotools.php
    • Set meta.defaults to false to disable default tags entirely.
    • Example:
      'meta' => [
          'defaults' => false, // Disables all default meta tags
          '
      
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport