Feature: OG Social media cards

Not Original Gangsta, but ObjectGraph

Reason: images were showing on LinkedIn, but small.
This commit is contained in:
2026-05-10 21:34:07 +01:00
parent 764585c642
commit 061787e897
13 changed files with 300 additions and 105 deletions
@@ -12,6 +12,27 @@ defmodule FirehoseWeb.Layouts do
embed_templates "layouts/*"
@doc """
Stores content in the connection for later rendering in layouts.
Used to inject dynamic meta tags into the `<head>` section.
"""
def put_content_for(conn, key, content) do
content_for = Map.get(conn.assigns, :content_for, %{})
new_content_for = Map.update(content_for, key, [content], &(&1 ++ [content]))
Plug.Conn.assign(conn, :content_for, new_content_for)
end
@doc """
Retrieves content stored via `put_content_for/3`.
Can be called from HEEx templates with `get_content_for(assigns, :meta_tags)`.
"""
def get_content_for(assigns, key) do
content_for = assigns[:content_for]
if is_map(content_for), do: Map.get(content_for, key, []), else: []
end
@doc """
Shows the flash group with standard titles and content.
@@ -31,6 +31,16 @@
window.addEventListener("phx:set-theme", (e) => setTheme(e.target.dataset.phxTheme));
})();
</script>
<%= for meta <- get_content_for(assigns, :meta_tags) do %>
<meta property="og:title" content={meta.og_title} />
<meta property="og:description" content={meta.og_description} />
<meta property="og:type" content={meta.og_type} />
<meta property="og:url" content={meta.og_url} />
<%= if meta.og_image do %>
<meta property="og:image" content={meta.og_image} />
<% end %>
<meta name="twitter:card" content={meta.twitter_card} />
<% end %>
</head>
<body>
{@inner_content}
@@ -8,7 +8,11 @@ defmodule FirehoseWeb.BlogController do
page = parse_page(params["page"])
result = blog.paginate(page)
render(conn, :index,
meta = Blogex.SEO.meta_tags_for_blog(blog, FirehoseWeb.Endpoint.url())
conn
|> FirehoseWeb.Layouts.put_content_for(:meta_tags, meta)
|> render(:index,
page_title: blog.title(),
blog_title: blog.title(),
blog_description: blog.description(),
@@ -24,9 +28,14 @@ defmodule FirehoseWeb.BlogController do
post = blog.get_post!(slug)
visibility = Blogex.Post.visibility(post)
render(conn, :show,
meta = Blogex.SEO.meta_tags(post, FirehoseWeb.Endpoint.url(), blog)
conn
|> FirehoseWeb.Layouts.put_content_for(:meta_tags, meta)
|> render(:show,
page_title: post.title,
post: post,
meta: meta,
base_path: blog.base_path(),
visibility: visibility,
authenticated: !!(conn.assigns[:current_scope] && conn.assigns.current_scope.user)