f976af0f7c
Escape </>& in JSON-LD body to kill script-breakout; byArtist now uses the release artist; detail-page not-found branches emit noindex; default robots gated to Production via a PersistentState SeoEnvironment bridge.
34 lines
1.7 KiB
C#
34 lines
1.7 KiB
C#
using Microsoft.AspNetCore.Components;
|
|
|
|
namespace DeepDrftPublic.Client.Common;
|
|
|
|
/// <summary>
|
|
/// Environment-gated robots bridge (Phase 22 remediation §4). The beta/staging site is web-hosted and must
|
|
/// not be crawled, so the <i>default</i> robots directive is environment-gated: <c>index,follow</c> only in
|
|
/// Production, <c>noindex,nofollow</c> everywhere else. A per-page <see cref="SeoModel.Robots"/> override
|
|
/// still wins — this only sets the default.
|
|
///
|
|
/// <para>
|
|
/// Crawlers read the server-prerendered HTML, so correctness lives in the server prerender pass — but the
|
|
/// value must be identical across the InteractiveAuto double render (AC6), so the WASM pass has to resolve
|
|
/// the same flag. The WASM assembly has no <c>IWebHostEnvironment</c> (config comes from the server). This
|
|
/// mirrors the DarkMode bridge exactly: a scoped service the server seeds during prerender (from
|
|
/// <c>IWebHostEnvironment.IsProduction()</c>) and <c>[PersistentState]</c> rounds to the client, so both
|
|
/// passes resolve the identical value. <c>SeoHead</c> injects this rather than an environment dependency,
|
|
/// honouring the no-environment-in-the-component constraint.
|
|
/// </para>
|
|
/// </summary>
|
|
public class SeoEnvironment
|
|
{
|
|
/// <summary>
|
|
/// True only in Production. Seeded server-side and persisted across the WASM boot. Defaults to
|
|
/// <c>false</c> so the fail-safe is "do not index" — a missing bridge never accidentally opens a
|
|
/// non-production site to crawlers.
|
|
/// </summary>
|
|
[PersistentState]
|
|
public bool IsProduction { get; set; }
|
|
|
|
/// <summary>The environment-gated default robots directive. Explicit page values override this.</summary>
|
|
public string DefaultRobots => IsProduction ? "index,follow" : "noindex,nofollow";
|
|
}
|