# SeoKit - Laravel SEO Package ## Introduction SeoKit is a comprehensive SEO solution for Laravel applications that streamlines the management of search engine optimization across your entire site. Built for Laravel 11.x and 12.x with PHP 8.3+, this package provides a unified interface for managing meta tags, Open Graph protocol, Twitter Cards, and JSON-LD structured data through a clean, fluent API with chainable methods. The package offers both programmatic and database-backed approaches to SEO management, making it suitable for static content as well as dynamic, model-driven applications. With built-in caching, polymorphic relationships for Eloquent models, and sensible defaults, SeoKit eliminates the complexity of implementing proper SEO markup while maintaining flexibility for advanced customization. Whether you're building a blog, e-commerce site, or complex web application, SeoKit provides all the tools needed to optimize your content for search engines and social media platforms. ## APIs and Key Functions ### Setting SEO Tags with Facade Simple method to set title, description, and image across all SEO components simultaneously. ```php use Larament\SeoKit\Facades\SeoKit; // In a controller public function show(Post $post) { SeoKit::title($post->title) ->description($post->excerpt) ->image($post->featured_image) ->canonical(route('posts.show', $post)); return view('posts.show', compact('post')); } // In the blade layout (resources/views/layouts/app.blade.php)
@seoKit @yield('content') ``` ### Meta Tags Management Configure standard HTML meta tags including title, description, keywords, robots directives, and canonical URLs. ```php use Larament\SeoKit\Facades\SeoKit; SeoKit::meta() ->title('Complete SEO Guide for Laravel') ->description('Learn how to implement comprehensive SEO in Laravel applications') ->keywords(['laravel', 'seo', 'optimization', 'meta tags']) ->robots(['index', 'follow', 'max-snippet:-1']) ->canonical('https://example.com/seo-guide') ->addMeta('author', 'John Doe') ->addMeta('theme-color', '#4CAF50'); // Conditional pagination links SeoKit::meta() ->prev('https://example.com/posts?page=1', condition: $currentPage > 1) ->next('https://example.com/posts?page=3', condition: $currentPage < $totalPages); // Language alternates SeoKit::meta() ->addLanguage('en', 'https://example.com/en/page') ->addLanguage('es', 'https://example.com/es/page') ->addLanguage('fr', 'https://example.com/fr/page'); ``` ### Open Graph Protocol Implement Facebook and social media sharing with Open Graph meta tags. ```php use Larament\SeoKit\Facades\SeoKit; // Basic Open Graph SeoKit::opengraph() ->type('article') ->title('Understanding Laravel SEO') ->description('A comprehensive guide to SEO in Laravel') ->image('https://example.com/images/og-image.jpg', width: 1200, height: 630, alt: 'SEO Guide Cover') ->url('https://example.com/articles/laravel-seo') ->siteName('Tech Blog') ->locale('en_US') ->localeAlternate(['es_ES', 'fr_FR']); // Article-specific metadata SeoKit::opengraph()->article( publishedTime: '2024-01-15T08:00:00+00:00', modifiedTime: '2024-01-16T10:30:00+00:00', authors: ['https://example.com/author/john-doe'], section: 'Technology', tags: ['Laravel', 'PHP', 'SEO', 'Web Development'] ); // Profile pages SeoKit::opengraph()->profile( firstName: 'John', lastName: 'Doe', username: 'johndoe', gender: 'male' ); ``` ### Twitter Cards Create rich Twitter card previews for enhanced social sharing. ```php use Larament\SeoKit\Facades\SeoKit; // Summary card with large image SeoKit::twitter() ->card('summary_large_image') ->site('@myblog') ->creator('@johndoe') ->title('Laravel SEO Best Practices') ->description('Optimize your Laravel application for search engines') ->image('https://example.com/images/twitter-card.jpg', alt: 'SEO Best Practices'); // Player card for video content SeoKit::twitter() ->card('player') ->title('Laravel Tutorial Video') ->description('Learn Laravel SEO in 10 minutes') ->player('https://example.com/player.html', width: 640, height: 480) ->image('https://example.com/video-thumbnail.jpg'); ``` ### JSON-LD Structured Data - Article Schema Add Schema.org structured data for blog posts and articles to enable rich search results. ```php use Larament\SeoKit\Facades\SeoKit; SeoKit::jsonld()->article([ 'headline' => 'Complete Guide to Laravel SEO', 'description' => 'Learn everything about implementing SEO in Laravel applications', 'image' => 'https://example.com/article-image.jpg', 'author' => [ '@type' => 'Person', 'name' => 'John Doe', 'url' => 'https://example.com/author/john-doe', 'sameAs' => [ 'https://twitter.com/johndoe', 'https://linkedin.com/in/johndoe' ] ], 'publisher' => [ '@type' => 'Organization', 'name' => 'Tech Blog', 'logo' => [ '@type' => 'ImageObject', 'url' => 'https://example.com/logo.png', 'width' => 600, 'height' => 60 ] ], 'datePublished' => '2024-01-15T08:00:00+00:00', 'dateModified' => '2024-01-16T10:30:00+00:00', 'mainEntityOfPage' => [ '@type' => 'WebPage', '@id' => 'https://example.com/articles/laravel-seo' ] ]); ``` ### JSON-LD Structured Data - Product Schema Implement product schema for e-commerce sites with pricing, availability, and reviews. ```php use Larament\SeoKit\Facades\SeoKit; SeoKit::jsonld()->product([ 'name' => 'Laravel SEO Toolkit', 'image' => [ 'https://example.com/product-image-1.jpg', 'https://example.com/product-image-2.jpg', 'https://example.com/product-image-3.jpg' ], 'description' => 'Professional SEO toolkit for Laravel developers', 'sku' => 'LSEO-2024-001', 'mpn' => '925872', 'brand' => [ '@type' => 'Brand', 'name' => 'Laravel Tools' ], 'offers' => [ '@type' => 'Offer', 'url' => 'https://example.com/products/laravel-seo-toolkit', 'priceCurrency' => 'USD', 'price' => '49.99', 'priceValidUntil' => '2024-12-31', 'availability' => 'https://schema.org/InStock', 'itemCondition' => 'https://schema.org/NewCondition' ], 'aggregateRating' => [ '@type' => 'AggregateRating', 'ratingValue' => '4.8', 'reviewCount' => '247', 'bestRating' => '5', 'worstRating' => '1' ], 'review' => [ [ '@type' => 'Review', 'reviewRating' => [ '@type' => 'Rating', 'ratingValue' => '5', 'bestRating' => '5' ], 'author' => [ '@type' => 'Person', 'name' => 'Jane Smith' ], 'reviewBody' => 'Excellent SEO toolkit, highly recommended!' ] ] ]); ``` ### JSON-LD Structured Data - Organization Schema Define organization information for company websites with contact details and social profiles. ```php use Larament\SeoKit\Facades\SeoKit; SeoKit::jsonld()->organization([ 'name' => 'Acme Corporation', 'url' => 'https://example.com', 'logo' => 'https://example.com/logo.png', 'description' => 'Leading provider of web development solutions', 'address' => [ '@type' => 'PostalAddress', 'streetAddress' => '123 Main Street', 'addressLocality' => 'San Francisco', 'addressRegion' => 'CA', 'postalCode' => '94102', 'addressCountry' => 'US' ], 'contactPoint' => [ '@type' => 'ContactPoint', 'telephone' => '+1-415-555-0100', 'contactType' => 'customer service', 'email' => 'support@example.com', 'areaServed' => 'US', 'availableLanguage' => ['English', 'Spanish'] ], 'sameAs' => [ 'https://facebook.com/acmecorp', 'https://twitter.com/acmecorp', 'https://linkedin.com/company/acmecorp', 'https://instagram.com/acmecorp', 'https://youtube.com/acmecorp' ], 'foundingDate' => '2010-01-15', 'numberOfEmployees' => [ '@type' => 'QuantitativeValue', 'value' => 250 ] ]); ``` ### JSON-LD Structured Data - Local Business Schema Optimize local business presence with location, hours, and geographic coordinates. ```php use Larament\SeoKit\Facades\SeoKit; SeoKit::jsonld()->localBusiness([ '@type' => 'Restaurant', 'name' => 'The Gourmet Kitchen', 'image' => 'https://example.com/restaurant-photo.jpg', 'description' => 'Fine dining restaurant specializing in Italian cuisine', 'address' => [ '@type' => 'PostalAddress', 'streetAddress' => '456 Restaurant Row', 'addressLocality' => 'New York', 'addressRegion' => 'NY', 'postalCode' => '10001', 'addressCountry' => 'US' ], 'geo' => [ '@type' => 'GeoCoordinates', 'latitude' => '40.7589', 'longitude' => '-73.9851' ], 'url' => 'https://example.com', 'telephone' => '+1-212-555-0200', 'priceRange' => '$$$', 'openingHoursSpecification' => [ [ '@type' => 'OpeningHoursSpecification', 'dayOfWeek' => ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'], 'opens' => '11:00', 'closes' => '22:00' ], [ '@type' => 'OpeningHoursSpecification', 'dayOfWeek' => ['Saturday', 'Sunday'], 'opens' => '10:00', 'closes' => '23:00' ] ], 'servesCuisine' => 'Italian', 'acceptsReservations' => 'True', 'menu' => 'https://example.com/menu' ]); ``` ### Database-backed SEO with HasSeo Trait Store SEO metadata in database with polymorphic relationships for any Eloquent model. ```php // In your model (app/Models/Post.php) use Illuminate\Database\Eloquent\Model; use Larament\SeoKit\Concerns\HasSeo; class Post extends Model { use HasSeo; } // Creating SEO data $post = Post::find(1); $post->seo()->create([ 'title' => 'Custom SEO Title for Search Engines', 'description' => 'Optimized description that appears in search results', 'canonical' => 'https://example.com/posts/custom-url', 'robots' => 'index, follow', 'og_title' => 'Engaging Social Media Title', 'og_description' => 'Compelling description for social sharing', 'og_image' => 'https://example.com/images/social-share.jpg', 'twitter_image' => 'https://example.com/images/twitter-card.jpg', 'structured_data' => [ '@context' => 'https://schema.org', '@type' => 'BlogPosting', 'headline' => 'My Blog Post', 'author' => [ '@type' => 'Person', 'name' => 'John Doe' ], 'datePublished' => '2024-01-15T08:00:00+00:00' ], 'is_cornerstone' => true ]); // In controller public function show(Post $post) { $post->prepareSeoTags(); // Automatically applies cached SEO data return view('posts.show', compact('post')); } // Updating SEO data $post->seo()->update([ 'title' => 'Updated SEO Title', 'description' => 'Updated description' ]); // Checking cornerstone content if ($post->isCornerstone()) { // Special handling for cornerstone content } ``` ### Model-based SEO with HasSeoData Trait Derive SEO metadata directly from model attributes without separate database storage. ```php // In your model (app/Models/Post.php) use Illuminate\Database\Eloquent\Model; use Larament\SeoKit\Concerns\HasSeoData; use Larament\SeoKit\Data\SeoData; class Post extends Model { use HasSeoData; private function toSeoData(): SeoData { return new SeoData( title: $this->seo_title ?: $this->title, description: $this->seo_description ?: $this->excerpt, canonical: route('posts.show', $this), robots: $this->is_published ? 'index, follow' : 'noindex, nofollow', og_title: $this->social_title ?: $this->title, og_description: $this->social_description ?: $this->excerpt, og_image: $this->featured_image, twitter_image: $this->twitter_image ?: $this->featured_image, structured_data: [ '@context' => 'https://schema.org', '@type' => 'BlogPosting', 'headline' => $this->title, 'description' => $this->excerpt, 'image' => $this->featured_image, 'datePublished' => $this->published_at?->toIso8601String(), 'dateModified' => $this->updated_at?->toIso8601String(), 'author' => [ '@type' => 'Person', 'name' => $this->author->name, 'url' => route('authors.show', $this->author) ], 'wordCount' => str_word_count(strip_tags($this->content)) ] ); } } // In controller public function show(Post $post) { $post->prepareSeoTags(); // Applies SEO data from toSeoData() method return view('posts.show', compact('post')); } ``` ### Open Graph Video Content Optimize video content for social media sharing with specialized video metadata. ```php use Larament\SeoKit\Facades\SeoKit; // Video movie SeoKit::opengraph()->videoMovie( actor: [ 'https://example.com/actor/john-smith', 'https://example.com/actor/jane-doe' ], actorRole: ['Detective', 'Scientist'], director: ['https://example.com/director/james-cameron'], writer: ['https://example.com/writer/aaron-sorkin'], duration: 7200, // Duration in seconds (2 hours) releaseDate: '2024-01-01', tag: ['thriller', 'sci-fi', 'action'] ); SeoKit::opengraph() ->title('Epic Science Fiction Movie') ->description('A thrilling journey through space and time') ->video('https://example.com/video.mp4', secureUrl: 'https://secure.example.com/video.mp4', type: 'video/mp4', width: 1920, height: 1080); // Video episode SeoKit::opengraph()->videoEpisode( series: 'https://example.com/series/tech-talks', actor: ['https://example.com/host/john-doe'], duration: 2400, // 40 minutes releaseDate: '2024-01-15' ); ``` ### Open Graph Music Content Enhance music pages with artist, album, and track information for music streaming services. ```php use Larament\SeoKit\Facades\SeoKit; // Music song SeoKit::opengraph()->musicSong( duration: 245, // 4 minutes 5 seconds album: ['https://example.com/album/greatest-hits'], albumDisc: 1, albumTrack: 5, musician: ['https://example.com/artist/john-doe'] ); SeoKit::opengraph() ->title('Amazing Song Title') ->description('Listen to this incredible track') ->image('https://example.com/album-cover.jpg') ->audio('https://example.com/preview.mp3', secureUrl: 'https://secure.example.com/preview.mp3', type: 'audio/mpeg'); // Music album SeoKit::opengraph()->musicAlbum( song: [ 'https://example.com/song/track-1', 'https://example.com/song/track-2', 'https://example.com/song/track-3' ], musician: ['https://example.com/artist/john-doe'], releaseDate: '2024-01-01' ); // Music playlist SeoKit::opengraph()->musicPlaylist( song: [ 'https://example.com/song/favorite-1', 'https://example.com/song/favorite-2' ], creator: ['https://example.com/user/playlist-creator'] ); ``` ### Configuration and Installation Configure package defaults and install database migrations. ```bash # Quick installation with prompts php artisan seokit:install # Manual installation php artisan vendor:publish --tag="seokit-config" php artisan vendor:publish --tag="seokit-migrations" php artisan migrate # Composer installation composer require larament/seokit ``` ```php // config/seokit.php return [ 'table_name' => 'seokit', 'auto_title_from_url' => true, 'defaults' => [ 'title' => 'My Laravel Application', 'title_separator' => ' | ', 'description' => 'Welcome to our amazing website', 'canonical' => null, // null = current URL, 'full' = full URL, false = disabled 'robots' => 'index, follow, max-snippet:-1, max-image-preview:large', ], 'opengraph' => [ 'enabled' => true, 'defaults' => [ 'site_name' => env('APP_NAME', 'Laravel'), 'type' => 'website', 'url' => null, 'locale' => 'en_US', ], ], 'twitter' => [ 'enabled' => true, 'defaults' => [ 'card' => 'summary_large_image', 'site' => '@yourusername', 'creator' => '@yourusername', ], ], 'json_ld' => [ 'enabled' => true, 'defaults' => [], // Add default JSON-LD schema here ], ]; ``` ### Complete E-commerce Product Page Example Full implementation of SEO tags for an e-commerce product with all metadata types. ```php use App\Models\Product; use Larament\SeoKit\Facades\SeoKit; class ProductController extends Controller { public function show(Product $product) { // Basic SEO SeoKit::title($product->name) ->description($product->short_description) ->image($product->primary_image) ->canonical(route('products.show', $product)); // Meta tags SeoKit::meta() ->keywords($product->tags->pluck('name')->toArray()) ->robots('index, follow'); // Open Graph for social sharing SeoKit::opengraph() ->type('product') ->add('product:price:amount', $product->price) ->add('product:price:currency', 'USD') ->add('product:availability', $product->in_stock ? 'in stock' : 'out of stock') ->add('product:condition', 'new') ->add('product:retailer_item_id', $product->sku); // Twitter Card SeoKit::twitter() ->card('summary_large_image') ->add('label1', 'Price') ->add('data1', '$' . number_format($product->price, 2)) ->add('label2', 'Availability') ->add('data2', $product->in_stock ? 'In Stock' : 'Out of Stock'); // Structured data for rich search results SeoKit::jsonld()->product([ 'name' => $product->name, 'image' => $product->images->pluck('url')->toArray(), 'description' => $product->description, 'sku' => $product->sku, 'mpn' => $product->manufacturer_part_number, 'brand' => [ '@type' => 'Brand', 'name' => $product->brand->name, ], 'offers' => [ '@type' => 'Offer', 'url' => route('products.show', $product), 'priceCurrency' => 'USD', 'price' => $product->price, 'priceValidUntil' => now()->addMonths(3)->format('Y-m-d'), 'availability' => $product->in_stock ? 'https://schema.org/InStock' : 'https://schema.org/OutOfStock', 'itemCondition' => 'https://schema.org/NewCondition', 'seller' => [ '@type' => 'Organization', 'name' => config('app.name') ] ], 'aggregateRating' => [ '@type' => 'AggregateRating', 'ratingValue' => $product->average_rating, 'reviewCount' => $product->reviews_count, 'bestRating' => 5, 'worstRating' => 1 ] ]); return view('products.show', compact('product')); } } ``` ## Summary SeoKit provides Laravel developers with a complete, production-ready solution for managing all aspects of search engine optimization and social media integration. The package excels in three primary use cases: content websites and blogs that need article schema and social sharing optimization, e-commerce applications requiring product schema with pricing and availability data, and business websites needing organization and local business structured data. The fluent API design allows developers to quickly implement SEO features without deep expertise in meta tags, Open Graph protocol, or Schema.org vocabulary. Integration patterns are flexible and scalable, supporting both manual SEO configuration through the facade in controllers and automated approaches using Eloquent model traits. The HasSeo trait enables storing SEO data in a separate polymorphic table with automatic caching, ideal for content managed through admin panels or APIs. The HasSeoData trait derives SEO information from existing model attributes, perfect for applications where SEO metadata closely mirrors content data. Both patterns work seamlessly with Laravel's ecosystem, leveraging Eloquent relationships, caching mechanisms, and Blade directives to minimize boilerplate while maximizing performance. The package's comprehensive structured data support ensures rich search results and enhanced social media previews across all major platforms.