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

Meta Tags Laravel Package

torann/meta-tags

Meta tags manager for Laravel that adds SEO and social metadata to models and views with a fluent, configurable API. It handles titles, descriptions, Open Graph, and Twitter cards, keeping tag setup readable and centralized.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Pin the exact version. composer require torann/meta-tags:0.0.4. The package is pre-1.0 with a single tagged release from 2017; a ^0.0.4 constraint on a 0.0.x line gives you almost no protection, and floating to a later patch is how you get a silent behaviour change in your <head>.
  • Register the provider manually if auto-discovery doesn't fire. A 2017-era package may or may not declare extra.laravel in its composer.json. Check vendor/torann/meta-tags/composer.json first; if it's absent, add Torann\MetaTags\MetaTagsServiceProvider::class to config/app.php and the facade alias (commonly Meta) to aliases.
  • Read the source before the README. The whole package is typically a service provider, one manager class, one facade, and a config file — maybe a few hundred lines. Ten minutes there answers every question about method names, defaults, and how rendering works, and it tells you whether the public API actually matches what the docs imply.
  • Publish the config and read it. php artisan vendor:publish --provider="Torann\MetaTags\MetaTagsServiceProvider". This is where defaults, tag attribute conventions (name vs property), and any section/fallback structure live. Treat this file as the package's real documentation.
  • First use case — one description tag in your main layout. In a controller action, set the page description via the facade; in resources/views/layouts/app.blade.php, render the package output once inside <head>. Curl the page and confirm you get exactly <meta name="description" content="...">. That specific attribute pair is what 0.0.4 fixed, so it's the right smoke test.
  • Then add Open Graph. Same flow with an og:title / og:description / og:image, and verify the output uses property="og:..." and not name="og:...". If OG tags come out with name, you're either on the wrong version or overriding the attribute convention in config incorrectly.

Implementation Patterns

  • One render point, always. Put the package's render call (or @meta directive) in a single layout partial, e.g. resources/views/partials/meta.blade.php, included from every layout. Every duplicate-tag bug I've seen with this class of package comes from a second render call or a leftover hand-written <meta> block.
  • Config for defaults, code for overrides. Define the site-wide title suffix, fallback description, default OG image, and Twitter handle in the published config. Then set only the differences per page in controllers. This keeps git log on the config meaningful and avoids repeating your site name in forty controllers.
  • Controller workflow, not view workflow, for anything data-driven. Set meta values in the controller action (or a form request / action class) where the Eloquent model is already loaded, then return the view. Views that reach into $page->meta_description tend to multiply; controllers that call Meta::set(...) once are easy to grep.
  • Middleware for cross-cutting values. Canonical URL, locale-specific defaults, hreflang, and tenant-specific OG images belong in middleware that runs after locale/tenant resolution and before the response is rendered. This is the cleanest place for "the default title is {page} — {tenant name}" logic.
  • Model-driven SEO for CMS pages. Store seo_title, seo_description, og_image on the model, map them in the controller with ?? fallbacks to config. Use an accessor on the model for the fallback chain so controllers stay short.
  • Wrap it behind your own thin service. Something like App\Seo\PageMeta with forModel(), forPage(), defaults() methods that delegate to the package. Given the maturity level, this is non-optional: it makes the eventual replacement a one-file change and gives you a place to put the escaping and duplication guards you'll want anyway.
  • Test the rendered <head> in feature tests. Assert on assertSee('<meta name="description"', false), assert the description content matches, and — importantly — assert the count of description occurrences is exactly 1. Ordering and duplication problems are near-invisible in a browser and obvious in an assertion.
  • Compose with structured data yourself. If you need JSON-LD, generate it with your own Blade partial or a small builder; don't assume the package covers schema.org. Keep that in the same head partial so there's still one place to audit.

Gotchas and Tips

  • This package is effectively frozen. Last release January 2017, six stars, zero dependents. That's not a reason to avoid it, but it is a reason to budget for owning it. Fork it into your VCS or vendor it if you're using it in production — you will be the one patching it.
  • Laravel version compatibility is the first real risk. A 2017 package may call helpers that were removed (array_get, str_*, studly_case) or use a service provider pattern that predates current conventions. If you're on Laravel 9+, try the install on a branch and load a page immediately; if it explodes, a two-line shim in a forked copy is usually cheaper than finding an alternative.
  • The 0.0.4 fix is your debugging anchor. If descriptions are missing, ignored by crawlers, or malformed, first confirm the installed version with composer show torann/meta-tags, then php artisan config:clear and php artisan view:clear. Cached config and cached compiled Blade are the two most common reasons a change "doesn't apply."
  • Duplicate tags from legacy layouts. Every Laravel app accumulates a hand-written <meta name="description"> in a layout that nobody remembers adding. Grep the whole resources/views tree for <meta before you ship, and delete rather than comment out — commented-out tags come back.
  • name vs property is the most common correctness bug. Standard meta and Twitter cards use name; Open Graph uses property. Verify each tag type in the actual output, ideally in a test, because a wrong attribute is invisible in the rendered page but silently breaks the preview.
  • Escaping and quoting. Descriptions authored by marketing will contain apostrophes, &, em dashes, and occasionally pasted HTML. Test with "quoted", it's, and a non-ASCII character. If the package doesn't escape, escape at your PageMeta wrapper boundary — never trust the input, and never {!! !!} it into the attribute.
  • Truncation is your job. Meta descriptions over ~160 characters get truncated by search engines and OG descriptions get cut in social previews. Enforce a limit in your wrapper service so authors see a consistent result rather than discovering it in a LinkedIn preview.
  • Blade directive caching. If @meta is the interface you use, remember that Blade compiles directives — a stale compiled view will hold an old tag list. view:clear after changing anything structural, and prefer the plain render call in the layout if you want fewer moving parts.
  • Canonical URLs need absolute, request-aware values. Set canonicals in middleware using url()->current() or an explicit route, not relative paths — a relative canonical is worse than none.
  • Don't spread the facade across the codebase. Every Meta::set() call in a controller is a coupling point to an abandoned package. Funnel everything through App\Seo\PageMeta so the package name appears in exactly one directory. When you outgrow it — and given 0.0.x, plan for that — you swap the internals and nothing else moves.
  • Debugging technique: dump the head, not the page. curl -s https://app.test/page | sed -n '/<head>/,/<\/head>/p' gives you the exact bytes crawlers see, with no DevTools normalisation and no JavaScript-injected tags confusing you.
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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core