Project updates from Template #1

Merged
javier merged 123 commits from project/update-from-template into main 2026-09-04 13:40:36 +00:00
2 changed files with 40 additions and 0 deletions
Showing only changes of commit 4bb3e9098c - Show all commits
@@ -86,6 +86,7 @@ public extension Page {
/// The structured data is an inert data block browsers never execute it, so a site's `Content-Security-Policy` does not apply to it /// The structured data is an inert data block browsers never execute it, so a site's `Content-Security-Policy` does not apply to it
/// that search engines read for the organization's name, logo, and profiles. The analytics tracker, by contrast, is an executable script the /// that search engines read for the organization's name, logo, and profiles. The analytics tracker, by contrast, is an executable script the
/// policy must allow, and it is `defer`red so it never delays the page render; each behavior flag renders its `data-` attribute only when enabled. /// policy must allow, and it is `defer`red so it never delays the page render; each behavior flag renders its `data-` attribute only when enabled.
/// When recorder mode is on, the session recorder script follows the tracker script, deferred as well and carrying only the website id.
@HTMLBuilder @HTMLBuilder
var head: some HTML { var head: some HTML {
meta( meta(
@@ -147,6 +148,17 @@ public extension Page {
value: $0.value value: $0.value
) )
}) })
if let recorderScriptURL = analytics.recorderScriptURL {
script(
.defer,
.src(recorderScriptURL),
.custom(
name: "data-website-id",
value: analytics.websiteID
)
) {}
}
} }
metadata metadata
@@ -151,6 +151,34 @@ struct PageTests {
#expect(preconnect.lowerBound < script.lowerBound) #expect(preconnect.lowerBound < script.lowerBound)
} }
@Test
func `omits the session recorder script by default`() {
let html = StubPage(analytics: .init(
scriptURL: "https://analytics.example.com/script",
websiteID: "0000-website-id",
domains: "example.com"
)).render()
#expect(!html.contains("recorder.js"))
}
@Test
func `renders the session recorder script when recorder mode is on`() throws {
let html = StubPage(analytics: .init(
scriptURL: "https://analytics.example.com/script",
websiteID: "0000-website-id",
domains: "example.com",
recorder: true
)).render()
#expect(html.contains(#"<script defer src="https://analytics.example.com/recorder.js" data-website-id="0000-website-id"></script>"#))
let tracker = try #require(html.range(of: #"<script defer src="https://analytics.example.com/script""#))
let recorder = try #require(html.range(of: #"<script defer src="https://analytics.example.com/recorder.js""#))
#expect(tracker.lowerBound < recorder.lowerBound)
}
@Test @Test
func `omits the analytics behavior flags that are disabled`() { func `omits the analytics behavior flags that are disabled`() {
let html = StubPage(analytics: .init( let html = StubPage(analytics: .init(