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

Php Open Graph Laravel Package

astrotomic/php-open-graph

Generate Open Graph meta tags in PHP with a fluent, framework-agnostic API. Build structured og: tags for titles, images, videos, audio, and more, then render valid HTML for Facebook, Twitter, and other social platforms. Works standalone or in Laravel.

Deep Wiki
Context7

Getting Started

composer require astrotomic/php-open-graph

There is no configuration file and no mandatory service provider — it is a plain PHP object builder, usable anywhere (Laravel auto-discovery is not required for the core static API).

First place to look is src/OpenGraph.php — it is the factory / entry point. From there the tree splits into:

  • Types/ — Website, Article, Book, Profile, Music, Video (each sets og:type for you).
  • Structured property objects (Image, Video, Audio, etc.) returned by the corresponding methods.

Minimal first use case — a layout <head>:

use Astrotomic\OpenGraph\OpenGraph;

$og = OpenGraph::website(config('app.name'))
    ->title('Page title')
    ->description('One-sentence summary for social cards.')
    ->url(request()->url())
    ->image(asset('img/og-default.jpg'));

echo $og; // emits <meta property="og:..."> tags

If your layout renders {{ $og }} and you see escaped HTML (&lt;meta ...), switch to {!! $og !!} (or confirm the object implements Htmlable). The builder's __toString() returns the full meta-tag block.

Start with website for static pages, article for blog/news, profile for user pages. Everything else is optional richness.

Implementation Patterns

Build in the controller, render in the layout. Pass a fully-built OpenGraph instance to the view and echo it once in <head>. This keeps templates free of @php blocks and makes the tags unit-testable.

public function show(Post $post)
{
    $og = OpenGraph::article($post->title)
        ->description(Str::limit($post->excerpt, 200))
        ->url(route('posts.show', $post))
        ->locale('en_US');

    $og->image($post->cover_url)
        ->width(1200)
        ->height(630)
        ->alt($post->title);

    $og->publishedTime($post->published_at)
        ->modifiedTime($post->updated_at)
        ->author($post->author->name);

    return view('posts.show', compact('post', 'og'));
}

Default + override pattern. In layouts/app.blade.php, provide a fallback so every page has at least og:title, og:type, og:url, og:image:

{!! $og ?? OpenGraph::website(config('app.name'))
    ->description(config('app.tagline'))
    ->url(request()->url())
    ->image(asset('img/og-default.jpg')) !!}

Reusable factory / view composer. For larger apps, add a small service (or a View::composer('layouts.app', ...)) that assembles the builder from the current route, model, and locale. This is where you centralize image sizing rules and absolute-URL resolution.

Structured properties are sub-builders. ->image($url) returns an Image object; configure it immediately:

$og = OpenGraph::website('Title')->url($url);
$og->image($url)->width(1200)->height(630)->alt('Cover');
$og->image($url2); // call again for a second image

Calling ->image() multiple times adds multiple og:image sets, which is allowed and useful for galleries.

Localization. Set ->locale('de_DE') and ->alternateLocale('en_US') on multi-language sites; keep the primary locale first.

Testing. The rendered output is a stable string, so assert with assertStringContainsString('og:title', (string) $og) or snapshot the block in a feature test.

Compose with other tools. This package only owns Open Graph. Pair it with Twitter Card / JSON-LD output from a separate concern — do not try to bend it into a general SEO library.

Gotchas and Tips

  • Structured properties break fluent chains. ->image($url)->width(...)->height(...) is fine, but the object returned from ->width() is still the Image, not the root type. If you then need ->description(...), keep a reference to the root $og first. This is the most common source of BadMethodCallException / "method does not exist" errors.
  • Type-specific methods only exist on the right class. Article-only calls (publishedTime, section, tag, author) will fail on Website. Choose the factory method first; the type is not switchable afterwards.
  • No validation of required properties. The OG spec requires og:title, og:type, og:image, og:url, but the builder will happily render an incomplete set and many scrapers will silently drop the card. Enforce your own checklist in the default layout or a view composer.
  • URLs are not resolved for you. ->image('cover.jpg') produces a relative URL that Facebook/LinkedIn/Slack may refuse. Always pass absolute URLs (asset(), Storage::url(), CDN base).
  • Escaping in Blade. {{ $og }} escapes. Use {!! $og !!} (or verify Htmlable), and never pass unescaped user input as raw content yourself — the builder escapes attribute values, but double-check titles/descriptions for HTML entities.
  • Image dimensions matter more than the URL. Platforms prefer 1200×630 (1.91:1). Forgetting width/height often downgrades the preview to a thumbnail strip.
  • Cache invalidation. If you cache rendered __toString() output (fragment caching, full-page cache), tags can go stale after model edits — key the cache on updated_at.
  • No Twitter Card / JSON-LD. og:* is not enough for X/Twitter; add <meta name="twitter:card"> separately or combine with a card package.
  • Extending. New types are subclasses of the base Type; new structured properties follow the existing Image/Video pattern. Check the base class for the property() / render contract before adding custom tags — that is the intended extension point.
  • Maintenance. Last release was October 2023 and the surface is small and stable. Pin the version and wrap construction in one place (a factory or Blade component) so a future fork or replacement is a one-file change.
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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource