function MyApp()

in frontend/src/pages/_app.page.tsx [22:121]


function MyApp({ Component, pageProps }: AppProps) {
  const router = useRouter();
  const isLoggedIn = useIsLoggedIn();
  const googleAnalytics = useGoogleAnalytics();
  const metricsEnabled = useMetrics();
  const addonDataElementRef = useRef<HTMLElement>(null);

  const addonData = useAddonElementWatcher(addonDataElementRef);
  const [l10n, setL10n] = useState<ReactLocalization>(
    getL10n({ deterministicLocales: true }),
  );

  useEffect(() => {
    // When pre-rendering and on the first render, we deterministically load the
    // `en` bundle.  After that, however, we want to load the bundles relevant
    // to the user's preferred locales. (See the `useL10n` hook for more detail
    // on why.) Unfortunately we can't load additional needed locales
    // asynchronously on the client-side yet using @fluent/react, see
    // https://github.com/projectfluent/fluent.js/wiki/ReactLocalization/43a959b35fbf9eea694367f948cfb1387914657c#flexibility
    setL10n(getL10n({ deterministicLocales: false }));
  }, []);

  useEffect(() => {
    if (metricsEnabled === "enabled" && !googleAnalytics) {
      initGoogleAnalytics();
    }
  }, [metricsEnabled, googleAnalytics]);

  useEffect(() => {
    if (!googleAnalytics) return;
    ReactGa.pageview(router.asPath);
  }, [router.asPath, googleAnalytics]);

  const [waitingForMsw, setIsWaitingForMsw] = useState(
    process.env.NEXT_PUBLIC_MOCK_API === "true",
  );
  useEffect(() => {
    if (process.env.NEXT_PUBLIC_MOCK_API !== "true") {
      return;
    }
    (async () => {
      await initialiseApiMocks();

      if (
        typeof URLSearchParams !== "undefined" &&
        typeof document !== "undefined"
      ) {
        // When deploying the frontend with a mocked back-end,
        // this query parameter will allow us to automatically "sign in" with one
        // of the mock users. This is useful to be able to give testers a link
        // in which to see a particular feature:
        const searchParams = new URLSearchParams(document.location.search);
        const mockId = searchParams.get("mockId");
        const selectedMockId = mockIds.find((id) => id === mockId);
        if (typeof selectedMockId === "string") {
          // See `src/hooks/api/api.ts`; this localStorage entry is how we tell the
          // API mock what mock data we want to load:
          localStorage.setItem("authToken", selectedMockId);
        }
      }

      setIsWaitingForMsw(false);
    })();
  }, []);

  if (waitingForMsw) {
    // As soon as we start rendering the app, it will start sending requests.
    // If we're running the demo site, we want to hold off on doing that until
    // MSW is fully initialised. Usually, you'd run the initialisation before
    // rendering in the first place, but since Next.js handles the start of the
    // rendering (which it does to support server-side rendering), we're doing
    // it here instead. For more info, see
    // https://mswjs.io/docs/integrations/browser#conditionally-enable-mocking
    return <></>;
  }

  return (
    <LocalizationProvider l10n={l10n}>
      <ReactAriaI18nProvider>
        <AddonDataContext.Provider value={addonData}>
          {createElement("firefox-private-relay-addon", {
            // The following attributes are set by the add-on,
            // and read by the website (via the useAddonElementWatcher hook).
            "data-addon-installed": addonData.present,
            "data-local-labels": JSON.stringify(addonData.localLabels),
            // The following attributes are set by the website,
            // and read by the add-on.
            // Capitalised boolean for backwards compatibility;
            // this element was previously generated by Django:
            "data-user-logged-in":
              isLoggedIn === "logged-in" ? "True" : "False",
          })}
          <OverlayProvider id="overlayProvider">
            <Component {...pageProps} />
          </OverlayProvider>
        </AddonDataContext.Provider>
      </ReactAriaI18nProvider>
    </LocalizationProvider>
  );
}