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

Laravel Meta Laravel Package

eusonlito/laravel-meta

Laravel Meta provides a simple, fluent API for managing SEO and social meta tags in Laravel applications. Set titles, descriptions, keywords, canonical URLs, robots, Open Graph, and Twitter Card tags from controllers or views, with configuration defaults and Blade helpers.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require eusonlito/laravel-Meta. The service provider is auto-discovered on Laravel 5.5+, so no manual registration is normally needed.
  • Publish the config (php artisan vendor:publish --provider="Eusonlito\LaravelMeta\MetaServiceProvider", or --tag=config) and open config/meta.php first. That file is where the package's real defaults live — site name, default title, description, author, robots, image — and it is the fastest way to understand what render() will emit before you set anything yourself.
  • Drop {!! Meta::render() !!} inside <head> in your base layout, once. That is the whole integration surface for most apps.
  • First use case: set a per-page title and description from a controller action before returning the view:
Meta::set('title', $post->title);
Meta::set('description', Str::limit(strip_tags($post->body), 155));
Meta::set('image', $post->hero->url());

Anything not explicitly set falls back to the published config, so a fresh install renders sensible defaults immediately and you only override what differs per page.

Note on v3.3.0: the release note is a stub that only links to issue #34 and PR #23. Read those two threads before upgrading — the changelog itself tells you nothing about behaviour changes.

Implementation Patterns

Config defaults + per-request overrides. Treat config/meta.php as the site-wide baseline (title suffix, default OG image, Twitter handle) and treat Meta::set() calls as the per-request delta. This keeps controllers short and means a new page is never accidentally blank.

Middleware or view composer for route-driven metadata. For content sites where the meta is derivable from the route model, a small middleware or a View::composer('*') that inspects request()->route()->parameters() is cleaner than repeating Meta::set() in twenty controllers. Guard it with $request->isMethod('GET') so POST/redirect responses don't pay for it.

Model accessors for SEO fields. If editors control titles, add getMetaTitleAttribute() that falls back to the title column, and call it from one place. Avoid letting raw column names leak into Blade.

Blade component for the head. Wrap {!! Meta::render() !!} in <x-head-meta /> alongside your other head tags (canonical, hreflang, JSON-LD). This gives you one file to audit when SEO requirements change, and keeps the layout readable.

Absolute URLs for Open Graph. og:image must be absolute. Use asset() or Storage::url()-plus-url() rather than a relative path; the package will not fix that for you and most crawlers will silently drop the image.

Localisation. In a multilingual app, set meta inside the localised request lifecycle (after App::setLocale()), and register hreflang alternates through the same mechanism so ordering and escaping stay consistent.

Caching. The rendered head is request-specific. If you cache full HTML responses, make sure the cached fragment excludes user- or page-specific meta, or key the cache on the meta inputs. Fragment caching of the <head> is almost always a bug.

Testing. Assert on the rendered string with $response->assertSee('<meta name="description"', false) in feature tests. This is the cheapest way to catch a refactor that moved Meta::set() after the view was composed.

Inertia / Livewire. The package is server-rendered only. With Inertia you need to pass meta through shared props and render it in the root Blade template; with Livewire, set meta in the initial component mount, not on subsequent AJAX updates, which never touch the document head.

Gotchas and Tips

  • {!! !!} is required — render() returns an HTML string and Blade escapes it by default. If you use {{ }} you will see literal &lt;meta&gt; in the page source.
  • Double-escaping in content. The package escapes attribute values, but if you pre-escape with e() or pass HTML through strip_tags inconsistently, you get &amp;quot; artifacts. Pass plain strings and let the package do the escaping.
  • Duplicates from config fallback. If a tag appears twice, it is usually the config default plus your explicit set(). Decide early whether a set() is meant to override or append, and verify against the rendered output rather than assuming.
  • Order of operations. Set meta in the controller or a view composer, not in a Blade @section that runs after the head is rendered. If a value is missing, check where in the render pipeline it was assigned before blaming the package.
  • Config cache. After editing config/meta.php, run php artisan config:clear in development. A stale cached config is the most common "my change did nothing" report.
  • Long-running workers. Under Octane or a queue worker, verify whether the meta store is reset per request. If it is bound as a singleton, values can bleed between requests; a per-request scoped() binding or an explicit reset in a middleware is the fix.
  • Debugging output. Dump the rendered head ({!! Meta::render() !!} in isolation) or the whole tag collection before chasing config. Reading the actual emitted tags resolves most disputes faster than re-reading the docs.
  • Extension point. For tags the package doesn't model first-class (custom property pairs, JSON-LD), use the generic add-meta method rather than forking the view; keep JSON-LD in your own component so you control json_encode flags and </script> escaping.
  • Upgrade hygiene. Because v3.3.0's changelog is only a pair of links, diff the published config after upgrading (vendor:publish --force into a scratch dir and compare) — config shape changes are the most likely silent breakage in a meta package.
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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib