diff --git a/aksel.nav.no/website/components/layout/footer/Footer.tsx b/aksel.nav.no/website/components/layout/footer/Footer.tsx index d0c8b9a922..ca06e58252 100644 --- a/aksel.nav.no/website/components/layout/footer/Footer.tsx +++ b/aksel.nav.no/website/components/layout/footer/Footer.tsx @@ -54,7 +54,7 @@ const Footer = () => { text: "Hva er Aksel?", }, { - url: "/side/personvernerklaering", + url: "/personvernerklaering", text: "Personvernerklæring", }, { diff --git a/aksel.nav.no/website/components/utils/get-current-environment.ts b/aksel.nav.no/website/components/utils/get-current-environment.ts new file mode 100644 index 0000000000..96b9945823 --- /dev/null +++ b/aksel.nav.no/website/components/utils/get-current-environment.ts @@ -0,0 +1,29 @@ +"use client"; + +/** + * Classifies the current traffic as either "organic" or "polluted" + * + * Organic traffic: Production traffic from real users on the main site + * Polluted traffic: Traffic from preview environments, example pages, templates, admin pages, or non-production environments + * + * @returns {"organic" | "polluted"} Traffic classification + */ + +export const classifyTraffic = () => { + const isProdUrl = () => window.location.host === "aksel.nav.no"; + const isPreview = () => !!document.getElementById("exit-preview-id"); + const isExample = () => window.location.pathname.startsWith("/eksempler/"); + const isTemplate = () => window.location.pathname.startsWith("/templates/"); + const isAdmin = () => window.location.pathname.startsWith("/admin/"); + + if ( + isProdUrl() && + !isPreview() && + !isExample() && + !isTemplate() && + !isAdmin() + ) { + return "organic"; + } + return "polluted"; +}; diff --git a/aksel.nav.no/website/components/website-modules/ConsentBanner.tsx b/aksel.nav.no/website/components/website-modules/ConsentBanner.tsx new file mode 100644 index 0000000000..4ae36d2922 --- /dev/null +++ b/aksel.nav.no/website/components/website-modules/ConsentBanner.tsx @@ -0,0 +1,117 @@ +"use client"; + +import NextLink from "next/link"; +import Script from "next/script"; +import { useEffect, useState } from "react"; +import { + BodyLong, + Button, + HStack, + Heading, + Link, + Page, + Stack, +} from "@navikt/ds-react"; +import { classifyTraffic } from "../utils/get-current-environment"; +import useConsent from "./useConsent"; + +export const ConsentBanner = ({ + defaultShow = false, + hide = false, +}: { + defaultShow?: boolean; + hide?: boolean; +}) => { + const [umamiTag, setUmamiTag] = useState(); + const [clientAcceptsTracking, setClientAcceptsTracking] = useState(false); + const [showConsentBanner, setShowConsentBanner] = useState(defaultShow); + const { consent, updateConsent } = useConsent(); + + useEffect(() => { + const disabledModalParam = new URLSearchParams(window.location.search).get( + "no_consent_modal", + ); + if (consent === "undecided" && !disabledModalParam) { + setShowConsentBanner(true); + } else if (["accepted", "rejected"].includes(consent)) { + setShowConsentBanner(false); + } + + setUmamiTag(classifyTraffic()); + setClientAcceptsTracking(consent === "accepted"); + }, [consent]); + + return ( +
+ {umamiTag && ( + + )} + + {!hide && showConsentBanner && ( + + +
+ + Vi bruker cookies + + + Nødvendige informasjonskapsler sørger for at nettstedet fungerer + og er sikkert, og kan ikke velges bort. Andre brukes til + statistikk og analyse. Godkjenner du alle, hjelper du oss å lage + bedre nettsider og tjenester.{" "} + + Mer om våre informasjonskapsler. + + +
+ + + +