@escape-game-over/atlas 0.1.42 → 0.1.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
package/src/astro/Document.astro
CHANGED
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
* `restoreScroll={false}`: the router keeps its own position in the same
|
|
11
11
|
* history state.
|
|
12
12
|
*
|
|
13
|
+
* A site with a lead form passes `rememberCampaign`, so the `utm_*` tags a
|
|
14
|
+
* visit landed with survive to the page the form is on; see `attribution.ts`.
|
|
15
|
+
*
|
|
13
16
|
* ```astro
|
|
14
17
|
* <Document meta={meta} html={{ class: "scroll-smooth" }} body={{ class: "…" }}>
|
|
15
18
|
* <Fragment slot="head"><link rel="preload" … /></Fragment>
|
|
@@ -20,6 +23,7 @@
|
|
|
20
23
|
import type { HTMLAttributes } from "astro/types";
|
|
21
24
|
import type { PageMeta } from "../site/index.ts";
|
|
22
25
|
import MetaTags from "./MetaTags.astro";
|
|
26
|
+
import RememberCampaign from "./RememberCampaign.astro";
|
|
23
27
|
import ScrollRestore from "./ScrollRestore.astro";
|
|
24
28
|
|
|
25
29
|
interface Props {
|
|
@@ -29,9 +33,17 @@ interface Props {
|
|
|
29
33
|
readonly body?: HTMLAttributes<"body">;
|
|
30
34
|
/** Defaults to `true`; `false` for a site on `ClientRouter`. */
|
|
31
35
|
readonly restoreScroll?: boolean;
|
|
36
|
+
/** Off unless stated: a site with no lead form has nothing to keep them for. */
|
|
37
|
+
readonly rememberCampaign?: boolean;
|
|
32
38
|
}
|
|
33
39
|
|
|
34
|
-
const {
|
|
40
|
+
const {
|
|
41
|
+
meta,
|
|
42
|
+
html,
|
|
43
|
+
body,
|
|
44
|
+
restoreScroll = true,
|
|
45
|
+
rememberCampaign = false,
|
|
46
|
+
} = Astro.props;
|
|
35
47
|
---
|
|
36
48
|
|
|
37
49
|
<!doctype html>
|
|
@@ -49,5 +61,6 @@ const { meta, html, body, restoreScroll = true } = Astro.props;
|
|
|
49
61
|
<MetaTags tags={meta.bodyTags} />
|
|
50
62
|
<slot />
|
|
51
63
|
{restoreScroll && <ScrollRestore />}
|
|
64
|
+
{rememberCampaign && <RememberCampaign />}
|
|
52
65
|
</body>
|
|
53
66
|
</html>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* Keeps the campaign tags a visit landed with for the tab, so a lead form on
|
|
4
|
+
* another page can still report them — see `attribution.ts`.
|
|
5
|
+
*
|
|
6
|
+
* Rendered by `Document` when asked for. A bundled module rather than inline:
|
|
7
|
+
* the tags are wanted by a form, which cannot be sent before it runs.
|
|
8
|
+
*/
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<script src="./remember-campaign.ts" />
|
package/src/astro/attribution.ts
CHANGED
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
* - **Campaign tags** (`utm_*`) are labels a campaign shares with everyone who
|
|
12
12
|
* clicked it, not an identifier. They are kept for the tab in
|
|
13
13
|
* `sessionStorage`, so a visitor who lands on one page and fills a form on
|
|
14
|
-
* another still reports them. `rememberCampaign()`
|
|
14
|
+
* another still reports them. `rememberCampaign()` does that; `Document`'s
|
|
15
|
+
* `rememberCampaign` runs it on every page, with analytics consent only.
|
|
15
16
|
* - **The ad click id** (`gclid`, `gbraid`, `wbraid`) identifies one click, and
|
|
16
17
|
* is never stored here. Google keeps it under the visitor's consent: on the
|
|
17
18
|
* URL while marketing is denied — `urlPassthrough` in `GoogleSettings` — and
|
package/src/astro/consent.ts
CHANGED
|
@@ -80,8 +80,15 @@ export function readConsent(): ConsentRecord | undefined {
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
83
|
+
* The event `recordConsent` fires on `window` with the new answer as `detail`,
|
|
84
|
+
* for anything on the page that waits on a category — without the banner
|
|
85
|
+
* having to know it exists.
|
|
86
|
+
*/
|
|
87
|
+
export const CONSENT_EVENT = "atlas:consent";
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Remembers an answer, dated now, tells Google about it, and announces it — one
|
|
91
|
+
* call, so the three cannot come apart.
|
|
85
92
|
*/
|
|
86
93
|
export function recordConsent(choices: ConsentChoices): void {
|
|
87
94
|
const record: ConsentRecord = { ...choices, at: new Date().toISOString() };
|
|
@@ -92,6 +99,9 @@ export function recordConsent(choices: ConsentChoices): void {
|
|
|
92
99
|
// one — the choice still applies to this page.
|
|
93
100
|
}
|
|
94
101
|
applyConsent(choices);
|
|
102
|
+
window.dispatchEvent?.(
|
|
103
|
+
new CustomEvent<ConsentChoices>(CONSENT_EVENT, { detail: choices })
|
|
104
|
+
);
|
|
95
105
|
}
|
|
96
106
|
|
|
97
107
|
/**
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Every page: a visit can land anywhere before it reaches a form.
|
|
2
|
+
//
|
|
3
|
+
// Only with analytics consent. Keeping campaign tags is measurement, and EU
|
|
4
|
+
// rules ask consent for anything stored on a visitor's device that the site
|
|
5
|
+
// does not need to work — not only cookies. So the tags are kept now if the
|
|
6
|
+
// visitor already agreed, or the moment they agree on this page.
|
|
7
|
+
import { rememberCampaign } from "./attribution.ts";
|
|
8
|
+
import { CONSENT_EVENT, type ConsentChoices, readConsent } from "./consent.ts";
|
|
9
|
+
|
|
10
|
+
if (readConsent()?.analytics === "granted") rememberCampaign();
|
|
11
|
+
|
|
12
|
+
addEventListener(CONSENT_EVENT, (event) => {
|
|
13
|
+
const choices = (event as CustomEvent<ConsentChoices>).detail;
|
|
14
|
+
if (choices.analytics === "granted") rememberCampaign();
|
|
15
|
+
});
|