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

Open Graph Laravel Package

chriskonnertz/open-graph

A PHP library for generating Open Graph meta tags. Build and render structured og: properties for titles, descriptions, images, URLs, and more with a simple API suitable for Laravel or any PHP project, helping control how pages appear when shared on social media.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

What the package actually is. A single-responsibility PHP library that accumulates Open Graph properties (og:title, og:image, article:published_time, array-valued properties such as multiple images with og:image:width/og:image:height sub-properties) and renders them as <meta property="…" content="…"> tags. It is framework-agnostic: no service provider, no facade, no config file, no Blade directives, no Laravel dependency. That is simultaneously its cleanest architectural property and its weakest developer-experience property.

Architecture fit. Good conceptual fit for a Laravel app if used as a narrow rendering primitive behind your own abstraction. It occupies the same layer as a schema builder or a breadcrumb generator: a stateless, per-request value object that a presenter/policy composes and a Blade component emits. It has no I/O, no global state, no container coupling, so it slots in without touching application architecture. The risk is not architectural, it is economic: the entire capability is roughly 100–200 lines of string building you could own outright.

Integration feasibility. composer require is trivial; the friction is the composer.json platform constraint. The last tagged release is June 2019, which places it in the PHP 7.x era. Expect one of three outcomes on PHP 8.2–8.4: (a) it installs and runs fine because the runtime code is pure string manipulation; (b) Composer refuses on php constraint and you must fork or use --ignore-platform-reqs (unacceptable in CI); (c) it installs but emits deprecation notices (implicit-nullable parameters, dynamic properties) that pollute logs and fail strict test suites. There are no runtime third-party dependencies, so the transitive supply-chain surface is effectively zero. That is the package's strongest technical argument.

Technical risk. Concentrated in four places, none of them performance:

Risk Severity Notes
Abandonment (last release 2019) High No PHP 8.x CI matrix, no spec updates, no security response path
Output escaping High Verify by test whether content values are HTML-escaped. If not, unescaped user-supplied titles/descriptions are an attribute-injection vector
Spec coverage Medium No evidence of twitter: card tags, og:image:alt, JSON-LD, or locale alternates — you will likely need to extend or wrap it, and extending an unmaintained library means forking it
Composer platform conflict Medium A hard php constraint can block unrelated dependency upgrades across the monolith; this is the failure mode that actually burns engineers

Key questions for the spike (timeboxed to half a day).

  1. Does it install cleanly on our production PHP version, and does composer update still resolve end-to-end?
  2. Is content escaped on render? Write an XSS test with "><script> before anything ships.
  3. Does it handle array/structured properties (multiple images, article:* sub-properties) and dedupe repeated keys, or does the caller?
  4. Does it cover what marketing actually needs — Twitter/X cards, og:image:alt, per-locale variants — or is it og: only?
  5. Does it resolve relative image URLs against APP_URL, or emit them verbatim (a common cause of failed Facebook Sharing Debugger previews)?
  6. Is the code small enough (likely: a few hundred LOC) that forking under our namespace is cheaper than adapting around it?

Verdict. The 3.02 score and 2.27 opportunity score are consistent with what the repository shows: correct, small, well-intentioned, and stale. This is a reference implementation, not a dependency. Its value to us is as a known-good model of the OG property grammar and structured-property syntax.

Integration Approach

Stack fit. Framework-agnostic PHP is a genuine plus here — it means the library can sit behind an interface we control and be swapped without touching call sites. Do not let it leak into Blade templates or controllers directly; that is what makes 2019-era packages expensive later.

Target design (thin adapter, ~1 day):

App\Seo\MetaBuilder            (interface: addProperty, addStructured, render)
App\Seo\OpenGraphMetaBuilder  (wraps chriskonnertz/open-graph)
App\Seo\MetaPresenter         (per-route/resource: maps a Post/Product model → properties)
resources/views/components/meta.blade.php  (single emission point)

Bind the interface in a SeoServiceProvider, resolve it in a Meta facade or @meta directive, and have one Blade component render the head block. Everything downstream — controllers, models, layouts — depends only on MetaBuilder.

Migration path.

  1. Inventory first. Grep for existing <meta property="og: and twitter: emissions, hand-rolled Blade partials, and any SEO plugin config. Tag builders multiply silently; you need the real surface before adding a fourth one.
  2. Introduce the interface with a no-op implementation that delegates to today's Blade partials. Ship it. Zero behaviour change, and it proves the seam.
  3. Swap in the adapter behind the interface, route by route, starting with the highest-traffic shareable pages (product, article, landing). Diff rendered HTML against production before and after — the output should be byte-identical or the difference should be intentional.
  4. Consolidate and delete the old partials in the same PR that migrates the last caller. Never leave two generators live.
  5. Add a contract test that validates rendered tags against a fixed fixture (title, description, canonical URL, absolute image URL, one array property). This is the test that survives the library being replaced.

Compatibility notes.

  • No auto-discovery, so no surprise wiring; you register the provider explicitly, which is preferable.
  • Pin the dependency exactly ("chriskonnertz/open-graph": "1.0.x" or equivalent) — with no upstream releases, a floating constraint buys nothing and risks a fork tag colliding.
  • If the platform constraint blocks install, the fallback is a 30-minute local port of the render logic into App\Seo, MIT-licensed and attributed. Given the size, this is a legitimate first choice, not a fallback of last resort.
  • Laravel 10/11/12 compatibility is a non-issue if the adapter boundary holds; the only version-sensitive surface is composer.json and PHP syntax.

Sequencing. Spike and XSS/escaper verification (0.5d) → interface + no-op + contract test (1d) → adapter or port (0.5–1d) → migrate routes in traffic order (1–2d) → delete legacy partials (0.5d). Roughly one engineer-week including review, dominated by the migration and diffing, not by the library.

Operational Impact

Maintenance. Upstream maintenance is zero and should be planned as zero. The repository has no commits since 2019, 115 stars, a single maintainer (bus factor 1), and no security advisory process. MIT licensing means we can fork, patch, and re-publish internally without legal friction — that is the escape hatch that makes this tolerable at all. Budget realistically: we are the maintainers from day one. The compensating factor is code size; a library this small is auditable in an afternoon and forkable in a day, which is not true of the 2019-era packages that actually hurt.

Support. No vendor, no community forum, no Stack Overflow corpus, no CVE feed. Internal support means the adapter's owner reads the source. Onboarding a second engineer to the adapter is cheap because the interface is ours; onboarding them to the library internals is also cheap because there is almost nothing there. Treat the adapter as the owned artifact and the library as an implementation detail nobody needs to learn.

Scaling. Effectively free. Rendering is string concatenation over a handful of properties per request — sub-millisecond, no allocation pressure worth measuring, no external calls, no state, no cache invalidation problem. It is compatible with full-page caching and edge caching because the output is a pure function of the input properties. The only scaling-adjacent concern is correctness at scale: one bad template emitting unescaped or relative-URL tags affects every share of that page type simultaneously, and social crawlers cache aggressively (Facebook's debugger holds scraped metadata for days), so a bad deploy has a long tail. That argues for the contract test and a pre-release check against the Sharing Debugger on one representative URL per template.

Failure modes, ranked by likelihood × blast radius.

Failure mode Likelihood Impact Mitigation
Composer platform constraint blocks an unrelated upgrade Medium High — halts the whole app's dependency track Pin exactly; be ready to port or fork on day one
Unescaped content → attribute injection Unknown until tested High — XSS on every page Escape test in the spike; escape at the adapter, not the caller
PHP 8.x deprecation noise in logs / strict CI Medium Low–Medium Suppress at the boundary or patch in the fork
Relative image URLs → broken social previews Medium Medium — marketing-visible, slow to detect Assert absolute URLs in the contract test
Duplicate/conflicting tags from a leftover partial High during migration Low Single emission point; grep-and-delete discipline in the migration PR
Spec drift (new required og: / twitter: properties) Low, slow-moving Low Adapter can emit extra tags without touching the library

Ramp-up. Half a day for a mid-level Laravel engineer to be productive behind the adapter; the library's API is small and the README is adequate. The non-obvious cost is judgement, not knowledge: engineers need to know which properties each surface (Facebook, LinkedIn, Slack, X, iMessage) actually consumes, because the library will happily let you emit syntactically valid tags that render no preview. Document the required-property set per template in the presenter, not in tribal memory.

Recommendation. Do not adopt this as a strategic dependency, and do not sponsor a migration onto it. Adopt it only where it is already present, isolated behind an owned interface, pinned exactly, and covered by a rendering contract test — with a written expectation that the next substantive change is a local fork or a port. For greenfield work, budget the same one engineer-week to own a ~150-line MetaBuilder outright: it removes the platform-constraint trap, the abandonment question, and the escaping uncertainty in a single move, and the resulting code is indistinguishable at the call site because the interface is the same. The package earned its stars as a clear, correct articulation of the OG property grammar; use it that way — read it, then write your own.

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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin