{"id":567,"date":"2025-09-01T10:51:59","date_gmt":"2025-09-01T10:51:59","guid":{"rendered":"https:\/\/1v0.net\/blog\/?p=567"},"modified":"2025-09-01T10:52:01","modified_gmt":"2025-09-01T10:52:01","slug":"adding-meta-tags-and-open-graph-data-dynamically-in-laravel","status":"publish","type":"post","link":"https:\/\/1v0.net\/blog\/adding-meta-tags-and-open-graph-data-dynamically-in-laravel\/","title":{"rendered":"Adding Meta Tags and Open Graph Data Dynamically in Laravel"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\"><strong>Adding Meta Tags and Open Graph Data Dynamically in Laravel<\/strong><\/h1>\n\n\n\n<p>Meta tags, Open Graph, and Twitter Cards help search engines and social networks understand your content. In Laravel, you can dynamically generate these tags per page, pulling from your database or model attributes. This guide shows how to add SEO meta, Open Graph, and Twitter tags in controllers, Blade templates, and admin forms.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Controller-Driven Dynamic Meta Tags<\/strong><\/h2>\n\n\n\n<p>For each resource (like posts), you can pass meta data from the controller into the view. If a post has a <code>meta_title<\/code> and <code>meta_description<\/code> column, use them to build SEO-friendly tags.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ app\/Http\/Controllers\/PostController.php<\/span>\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Http<\/span>\\<span class=\"hljs-title\">Controllers<\/span>;\n\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Models<\/span>\\<span class=\"hljs-title\">Post<\/span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">PostController<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">Controller<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">show<\/span><span class=\"hljs-params\">(Post $post)<\/span>\n    <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> view(<span class=\"hljs-string\">'posts.show'<\/span>, &#91;\n            <span class=\"hljs-string\">'post'<\/span> =&gt; $post,\n            <span class=\"hljs-string\">'meta'<\/span> =&gt; &#91;\n                <span class=\"hljs-string\">'title'<\/span> =&gt; $post-&gt;meta_title ?? $post-&gt;title,\n                <span class=\"hljs-string\">'description'<\/span> =&gt; $post-&gt;meta_description ?? str($post-&gt;content)-&gt;limit(<span class=\"hljs-number\">160<\/span>),\n                <span class=\"hljs-string\">'image'<\/span> =&gt; $post-&gt;cover_image,\n            ]\n        ]);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This way, the Blade view can render correct tags for each post, falling back to defaults when needed.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Blade Example: Meta + Open Graph + Twitter<\/strong><\/h2>\n\n\n\n<p>Inside your layout Blade, add a <code>@yield('meta')<\/code> section so each page can define its own tags. Here\u2019s an example:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">&lt;!-- resources\/views\/layouts\/app.blade.php --&gt;\n&lt;head&gt;\n  &lt;title&gt;@<span class=\"hljs-keyword\">yield<\/span>(<span class=\"hljs-string\">'title'<\/span>, <span class=\"hljs-string\">'My Blog'<\/span>)&lt;\/title&gt;\n  @<span class=\"hljs-keyword\">yield<\/span>(<span class=\"hljs-string\">'meta'<\/span>)\n&lt;\/head&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">&lt;!-- resources\/views\/posts\/show.blade.php --&gt;\n@extends(<span class=\"hljs-string\">'layouts.app'<\/span>)\n\n@section(<span class=\"hljs-string\">'title'<\/span>, $meta&#91;<span class=\"hljs-string\">'title'<\/span>])\n\n@section(<span class=\"hljs-string\">'meta'<\/span>)\n  &lt;meta name=<span class=\"hljs-string\">\"description\"<\/span> content=<span class=\"hljs-string\">\"{{ $meta&#91;'description'] }}\"<\/span>&gt;\n\n  &lt;!-- Open Graph --&gt;\n  &lt;meta property=<span class=\"hljs-string\">\"og:title\"<\/span> content=<span class=\"hljs-string\">\"{{ $meta&#91;'title'] }}\"<\/span>&gt;\n  &lt;meta property=<span class=\"hljs-string\">\"og:description\"<\/span> content=<span class=\"hljs-string\">\"{{ $meta&#91;'description'] }}\"<\/span>&gt;\n  &lt;meta property=<span class=\"hljs-string\">\"og:type\"<\/span> content=<span class=\"hljs-string\">\"article\"<\/span>&gt;\n  &lt;meta property=<span class=\"hljs-string\">\"og:url\"<\/span> content=<span class=\"hljs-string\">\"{{ url()-&gt;current() }}\"<\/span>&gt;\n  &lt;meta property=<span class=\"hljs-string\">\"og:image\"<\/span> content=<span class=\"hljs-string\">\"{{ asset('storage\/'.$meta&#91;'image']) }}\"<\/span>&gt;\n\n  &lt;!-- Twitter Cards --&gt;\n  &lt;meta name=<span class=\"hljs-string\">\"twitter:card\"<\/span> content=<span class=\"hljs-string\">\"summary_large_image\"<\/span>&gt;\n  &lt;meta name=<span class=\"hljs-string\">\"twitter:title\"<\/span> content=<span class=\"hljs-string\">\"{{ $meta&#91;'title'] }}\"<\/span>&gt;\n  &lt;meta name=<span class=\"hljs-string\">\"twitter:description\"<\/span> content=<span class=\"hljs-string\">\"{{ $meta&#91;'description'] }}\"<\/span>&gt;\n  &lt;meta name=<span class=\"hljs-string\">\"twitter:image\"<\/span> content=<span class=\"hljs-string\">\"{{ asset('storage\/'.$meta&#91;'image']) }}\"<\/span>&gt;\n@endsection\n\n@section(<span class=\"hljs-string\">'content'<\/span>)\n  &lt;h1&gt;{{ $post-&gt;title }}&lt;\/h1&gt;\n  &lt;p&gt;{{ $post-&gt;content }}&lt;\/p&gt;\n@endsection<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>This setup ensures each post page has correct SEO meta, Open Graph for Facebook\/LinkedIn, and Twitter card tags for rich previews.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>UI Example: Admin Form for Meta Fields<\/strong><\/h2>\n\n\n\n<p>Allow editors to define meta title, description, and OG image directly in the admin panel. Add these fields in your post form:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">&lt;form action=<span class=\"hljs-string\">\"{{ route('posts.store') }}\"<\/span> method=<span class=\"hljs-string\">\"POST\"<\/span> enctype=<span class=\"hljs-string\">\"multipart\/form-data\"<\/span>&gt;\n  @csrf\n\n  &lt;label&gt;Title&lt;\/label&gt;\n  &lt;input type=<span class=\"hljs-string\">\"text\"<\/span> name=<span class=\"hljs-string\">\"title\"<\/span>&gt;\n\n  &lt;label&gt;Meta Title&lt;\/label&gt;\n  &lt;input type=<span class=\"hljs-string\">\"text\"<\/span> name=<span class=\"hljs-string\">\"meta_title\"<\/span>&gt;\n\n  &lt;label&gt;Meta Description&lt;\/label&gt;\n  &lt;textarea name=<span class=\"hljs-string\">\"meta_description\"<\/span>&gt;&lt;\/textarea&gt;\n\n  &lt;label&gt;OG\/Twitter Image&lt;\/label&gt;\n  &lt;input type=<span class=\"hljs-string\">\"file\"<\/span> name=<span class=\"hljs-string\">\"cover_image\"<\/span>&gt;\n\n  &lt;button type=<span class=\"hljs-string\">\"submit\"<\/span>&gt;Save&lt;\/button&gt;\n&lt;\/form&gt;<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>These values are then stored in your <code>posts<\/code> table and rendered dynamically in the head tags.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Global Defaults with Middleware or Service<\/strong><\/h2>\n\n\n\n<p>To avoid missing tags on pages without meta fields, create a middleware or service that sets global defaults.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-comment\">\/\/ app\/Http\/Middleware\/DefaultMeta.php<\/span>\n<span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">App<\/span>\\<span class=\"hljs-title\">Http<\/span>\\<span class=\"hljs-title\">Middleware<\/span>;\n\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Closure<\/span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">DefaultMeta<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">handle<\/span><span class=\"hljs-params\">($request, Closure $next)<\/span>\n    <\/span>{\n        view()-&gt;share(<span class=\"hljs-string\">'defaultMeta'<\/span>, &#91;\n            <span class=\"hljs-string\">'title'<\/span> =&gt; <span class=\"hljs-string\">'My Laravel Blog'<\/span>,\n            <span class=\"hljs-string\">'description'<\/span> =&gt; <span class=\"hljs-string\">'Latest Laravel tutorials and guides'<\/span>,\n            <span class=\"hljs-string\">'image'<\/span> =&gt; <span class=\"hljs-string\">'\/images\/default-og.png'<\/span>,\n        ]);\n\n        <span class=\"hljs-keyword\">return<\/span> $next($request);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Register this middleware globally, then in your views use <code>$meta ?? $defaultMeta<\/code> to ensure every page has valid meta tags.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Wrapping Up<\/strong><\/h2>\n\n\n\n<p>Dynamic meta tags let you optimize every page for SEO and social sharing. With controller-driven meta, Blade templates for OG and Twitter cards, admin UI fields, and global defaults, your Laravel app is fully SEO-ready and shares beautifully on social media.<\/p>\n\n\n\n<div class=\"wp-block-spacer\" style=\"height:100px\" aria-hidden=\"true\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>What\u2019s Next<\/strong><\/h2>\n\n\n\n<p>Keep building your SEO toolkit with these related guides:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"\/blog\/laravel-seo-guide-optimizing-meta-slugs-and-sitemaps\">Laravel SEO Guide: Optimizing Meta, Slugs, and Sitemaps<\/a><\/li>\n<li><a href=\"\/blog\/how-to-generate-seo-friendly-urls-and-slugs-in-laravel\">How to Generate SEO-Friendly URLs and Slugs in Laravel<\/a><\/li>\n<li><a href=\"\/blog\/how-to-build-an-xml-sitemap-generator-in-laravel\">How to Build an XML Sitemap Generator in Laravel<\/a><\/li>\n<\/ul>\n\n","protected":false},"excerpt":{"rendered":"<p>Adding Meta Tags and Open Graph Data Dynamically in Laravel Meta tags, Open Graph, and Twitter Cards help search engines and social networks understand your content. In Laravel, you can dynamically generate these tags per page, pulling from your database or model attributes. This guide shows how to add SEO meta, Open Graph, and Twitter [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":571,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[96,108,112,109,116],"class_list":["post-567","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-laravel","tag-blade","tag-meta","tag-open-graph","tag-seo","tag-twitter-cards"],"_links":{"self":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/567","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/comments?post=567"}],"version-history":[{"count":1,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/567\/revisions"}],"predecessor-version":[{"id":570,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/posts\/567\/revisions\/570"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/media\/571"}],"wp:attachment":[{"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/media?parent=567"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/categories?post=567"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/1v0.net\/blog\/wp-json\/wp\/v2\/tags?post=567"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}