Multi-domain sitemap post-processing (one domain = one canonical language).
Activated by a host-app provider:
config :phoenix_kit, :sitemap_domains_provider, {MyAppWeb.SEO, :sitemap_domains}The provider returns [%{host: "example.fr", language: "fr", primary: false}, ...].
The result is VALIDATED here — exactly one primary: true, every host a
distinct language (base-code level), well-formed hosts. Any violation
deactivates domain mode (with a warning) rather than silently producing
malformed URLs or dropping x-default.
rebuild_for_domains/2 regroups the entries the generator already
collected across languages: for the domain of language L, every canonical
group that HAS an L entry contributes one URL — L's own entry re-hosted on
that domain with its locale prefix stripped (L is the default there) —
carrying an alternates set computed ONCE per group (identical across all
domain files by construction): each group language on its home URL, plus
x-default for the primary domain's language when the group has it
(omitted otherwise — never mislabel another language as x-default).
Runs inside Oban jobs and unpiped controller requests: language resolution
here never consults the request-scoped default-language override — the
unprefixed-entry fallback reads the raw is_default flag, mirroring the
generator's hardened get_languages/0.
NB: the generator's base_url (Settings site_url) and the provider's
primary host are independently-edited settings that must refer to the same
site; rel-path extraction below is host-string-agnostic, so a mismatch
yields consistent (if unexpected-host) URLs rather than corruption.
Summary
Functions
Validated provider domains; [] (inactive) on any contract violation.
Regroups collected entries into per-domain URL sets: %{host => [UrlEntry.t()]}.
Types
Functions
@spec domains() :: [domain()]
Validated provider domains; [] (inactive) on any contract violation.
@spec rebuild_for_domains([PhoenixKit.Modules.Sitemap.UrlEntry.t()], String.t()) :: %{ required(String.t()) => [PhoenixKit.Modules.Sitemap.UrlEntry.t()] }
Regroups collected entries into per-domain URL sets: %{host => [UrlEntry.t()]}.