Generates rel="alternate" hreflang annotations.
An hreflang set is how a site tells search engines and agents which
locale-specific variants of a page exist, and it is consumed rather than
negotiated: nothing sends Accept-Language on the reader's behalf, so the
declaration is the only signal.
Which is why it is validated here rather than emitted verbatim. A malformed annotation is silently ignored by every consumer, so the failure never shows up in production — the site simply looks monolingual. Every locale is therefore validated and rendered in its canonical BCP 47 form, and every URL must be fully qualified.
Summary
Functions
Builds link tags for a map of locale to URL.
Functions
@spec links( map() | nil, keyword() ) :: {:ok, Phoenix.HTML.safe()} | {:error, Exception.t()}
Builds link tags for a map of locale to URL.
Arguments
alternatesis a map of locale to fully-qualified URL. A locale may be any termLocalize.validate_locale/1accepts, or the string"x-default"to designate the fallback variant.optionsis a keyword list of options.
Options
:canonicalizedetermines whether locales are rendered in canonical BCP 47 form —"es_MX"becomes"es-MX","en-us"becomes"en-US". The default istrue. Set it tofalseto emit exactly what was supplied.
Returns
{:ok, safe}wheresafeis rendered HTML, or{:error, exception}if a locale is not recognised or a URL is not fully qualified.
Examples
iex> {:ok, {:safe, html}} = Localize.HTML.Hreflang.links(%{
...> "en" => "https://example.com/",
...> "de" => "https://example.com/de/"
...> })
iex> IO.iodata_to_binary(html) =~ ~s|hreflang="de"|
true
# Underscores are canonicalised; BCP 47 requires a hyphen
iex> {:ok, {:safe, html}} = Localize.HTML.Hreflang.links(%{"es_MX" => "https://example.com/mx/"})
iex> IO.iodata_to_binary(html) =~ ~s|hreflang="es-MX"|
true
# A locale that does not exist is an error, not silent bad markup
iex> Localize.HTML.Hreflang.links(%{"es-SP" => "https://example.com/es/"})
{:error, %Localize.InvalidLocaleError{locale_id: "es-SP"}}
# So is a relative URL, which every consumer ignores
iex> {:error, error} = Localize.HTML.Hreflang.links(%{"de" => "/de/"})
iex> error.__struct__
Localize.RelativeUrlError