• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mozilla / fx-private-relay / 86faa70d-e4aa-4ff4-a770-2a04951f034a

24 Jun 2024 03:13PM CUT coverage: 85.34% (-0.02%) from 85.364%
86faa70d-e4aa-4ff4-a770-2a04951f034a

Pull #4796

circleci

groovecoder
for MPP-2822: add googletagmanager to CSP
Pull Request #4796: MPP-2822: add gtag to Layout and update gaEvent hook to ping both GA endpoints

3992 of 5128 branches covered (77.85%)

Branch coverage included in aggregate %.

19 of 26 new or added lines in 4 files covered. (73.08%)

15760 of 18017 relevant lines covered (87.47%)

10.34 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

62.96
/frontend/src/components/GoogleAnalyticsWorkaround.tsx
1
// Based on: https://github.com/mozilla/blurts-server/blob/8fb1587f1af40b25fed455c79faf138c4be2d0d6/src/app/components/client/GoogleAnalyticsWorkaround.tsx
2
// License for this specific file:
3
/*
4
The MIT License (MIT)
5

6
Copyright (c) 2024 Vercel, Inc.
7

8
Permission is hereby granted, free of charge, to any person obtaining a copy of
9
this software and associated documentation files (the "Software"), to deal in
10
the Software without restriction, including without limitation the rights to
11
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
12
the Software, and to permit persons to whom the Software is furnished to do so,
13
subject to the following conditions:
14

15
The above copyright notice and this permission notice shall be included in all
16
copies or substantial portions of the Software.
17

18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
20
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
21
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
22
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
*/
25

26
"use client";
27

28
import { GAParams } from "@next/third-parties/dist/types/google";
29
import Script, { ScriptProps } from "next/script";
23✔
30
import { useEffect } from "react";
23✔
31

32
// We don't send Analytics events in tests:
33
/* c8 ignore start */
34

35
let currDataLayerName: string | undefined = undefined;
23✔
36

37
/**
38
 * This component is based on <GoogleAnalytics> from `@next/third-parties`, but accepting a nonce
39
 *
40
 * @param props
41
 */
42
export const GoogleAnalyticsWorkaround = (
91✔
43
  props: GAParams & { nonce?: ScriptProps["nonce"]; debugMode?: boolean },
44
) => {
45
  const { gaId, dataLayerName = "dataLayer", nonce, debugMode } = props;
91✔
46

47
  if (currDataLayerName === undefined) {
91✔
48
    currDataLayerName = dataLayerName;
6✔
49
  }
50

51
  useEffect(() => {
91✔
52
    if (typeof performance.mark !== "function") {
78✔
53
      return;
78✔
54
    }
55
    // performance.mark is being used as a feature use signal. While it is traditionally used for performance
56
    // benchmarking it is low overhead and thus considered safe to use in production and it is a widely available
57
    // existing API.
58
    // The performance measurement will be handled by Chrome Aurora
59

NEW
60
    performance.mark("mark_feature_usage", {
×
61
      detail: {
62
        feature: "next-third-parties-ga",
63
      },
64
    });
65
  }, []);
66

67
  return (
68
    <>
69
      <Script
70
        id="_next-ga-init"
71
        dangerouslySetInnerHTML={{
72
          __html: `
73
          window['${dataLayerName}'] = window['${dataLayerName}'] || [];
74
          function gtag(){window['${dataLayerName}'].push(arguments);}
75
          gtag('js', new Date());
76

77
          gtag('config', '${gaId}', { 'debug_mode': ${debugMode} });`,
78
        }}
79
        nonce={nonce}
80
      />
81
      <Script
82
        id="_next-ga"
83
        src={`https://www.googletagmanager.com/gtag/js?id=${gaId}`}
84
        nonce={nonce}
85
      />
86
    </>
87
  );
88
};
89

90
export const sendGAEvent = (type: "event", eventName: string, args: object) => {
23✔
91
  if (process.env.NODE_ENV === "test") {
12✔
92
    return;
12✔
93
  }
94

NEW
95
  if (currDataLayerName === undefined) {
×
NEW
96
    console.warn(`@next/third-parties: GA has not been initialized`);
×
NEW
97
    return;
×
98
  }
99

NEW
100
  if (window[currDataLayerName]) {
×
NEW
101
    window.gtag(type, eventName, args);
×
102
  } else {
NEW
103
    console.warn(
×
104
      `@next/third-parties: GA dataLayer ${currDataLayerName} does not exist`,
105
    );
106
  }
107
};
108
/* c8 ignore stop */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc