diff --git a/src/JobsMedical.Web/Pages/Jobs/Index.cshtml b/src/JobsMedical.Web/Pages/Jobs/Index.cshtml index b66206a..5d6ec4f 100644 --- a/src/JobsMedical.Web/Pages/Jobs/Index.cshtml +++ b/src/JobsMedical.Web/Pages/Jobs/Index.cshtml @@ -145,4 +145,8 @@ @section Head { @{ var bcUrl = $"{ViewContext.HttpContext.Request.Scheme}://{ViewContext.HttpContext.Request.Host}"; } @Html.Raw("") + @if (Model.Results.Count > 0) + { + @Html.Raw("") + } } diff --git a/src/JobsMedical.Web/Pages/Shifts/Index.cshtml b/src/JobsMedical.Web/Pages/Shifts/Index.cshtml index 5ccb325..503e500 100644 --- a/src/JobsMedical.Web/Pages/Shifts/Index.cshtml +++ b/src/JobsMedical.Web/Pages/Shifts/Index.cshtml @@ -178,4 +178,8 @@ @section Head { @{ var bcUrl = $"{ViewContext.HttpContext.Request.Scheme}://{ViewContext.HttpContext.Request.Host}"; } @Html.Raw("") + @if (Model.Results.Count > 0) + { + @Html.Raw("") + } } diff --git a/src/JobsMedical.Web/Services/SeoJsonLd.cs b/src/JobsMedical.Web/Services/SeoJsonLd.cs index 4f79916..87fcfc2 100644 --- a/src/JobsMedical.Web/Services/SeoJsonLd.cs +++ b/src/JobsMedical.Web/Services/SeoJsonLd.cs @@ -145,6 +145,22 @@ public static class SeoJsonLd }, Opts)); } + /// ItemList JSON-LD for a results/landing page — an ordered list of the listing URLs, + /// so Google understands it as a curated collection. Relative URLs are made absolute. + public static string ItemList(IEnumerable urls, string baseUrl) + { + var els = urls.Select((u, i) => (object)new Dictionary + { + ["type"] = "ListItem", ["position"] = i + 1, ["url"] = u.StartsWith("http") ? u : baseUrl + u, + }).ToList(); + return Fix(JsonSerializer.Serialize(new Dictionary + { + ["@context"] = "https://schema.org", + ["@type"] = "ItemList", + ["itemListElement"] = els, + }, Opts)); + } + // Nested anonymous objects use "type"/"queryyy" placeholders for @type / query-input; // restore the @-prefixed schema.org keys here. private static string Fix(string json) => json