Current section
Files
Jump to
Current section
Files
lib/skua/components/meta.ex
defmodule Skua.Components.Meta do
@moduledoc """
SEO `<meta>` tags for the document `<head>` — description, Open Graph, and
Twitter cards, plus an optional `robots` directive and a canonical link.
Render it once in your root layout's `<head>` (e.g. right after
`<.live_title>`) and drive it from per-page assigns:
<Skua.Components.Meta.seo_meta
description={assigns[:page_description]}
title={assigns[:page_title]}
image={assigns[:page_image]}
url={assigns[:page_canonical]}
robots={assigns[:page_robots]}
/>
Every tag is omitted when its value is `nil`, so a page **opts in** by
assigning `page_description` (and friends) in `mount/3`. Public pages set rich
meta; scoped/authenticated pages assign nothing — or set
`page_robots: "noindex, nofollow"` to keep themselves out of search results.
`mix skua.gen.pages` wires this into the root layout and sets sensible
defaults on the public homepage (and `noindex` on the authenticated
dashboard).
"""
use Phoenix.Component
attr :description, :string, default: nil
attr :title, :string, default: nil, doc: "used for og:title / twitter:title"
attr :site_name, :string, default: nil, doc: "og:site_name — your app/brand name"
attr :image, :string, default: nil, doc: "absolute URL to a share image"
attr :image_alt, :string, default: nil, doc: "alt text for the share image"
attr :url, :string, default: nil, doc: "canonical URL"
attr :type, :string, default: "website", doc: "og:type"
attr :locale, :string, default: nil, doc: ~s(og:locale, e.g. "en_US")
attr :robots, :string, default: nil, doc: ~s(e.g. "noindex, nofollow")
@doc "Render SEO / Open Graph / Twitter meta from optional per-page assigns."
def seo_meta(assigns) do
~H"""
<meta :if={@description} name="description" content={@description} />
<meta :if={@robots} name="robots" content={@robots} />
<link :if={@url} rel="canonical" href={@url} />
<meta property="og:type" content={@type} />
<meta :if={@site_name} property="og:site_name" content={@site_name} />
<meta :if={@title} property="og:title" content={@title} />
<meta :if={@description} property="og:description" content={@description} />
<meta :if={@url} property="og:url" content={@url} />
<meta :if={@image} property="og:image" content={@image} />
<meta :if={@image_alt} property="og:image:alt" content={@image_alt} />
<meta :if={@locale} property="og:locale" content={@locale} />
<meta name="twitter:card" content={if(@image, do: "summary_large_image", else: "summary")} />
<meta :if={@title} name="twitter:title" content={@title} />
<meta :if={@description} name="twitter:description" content={@description} />
<meta :if={@image} name="twitter:image" content={@image} />
<meta :if={@image_alt} name="twitter:image:alt" content={@image_alt} />
"""
end
end