Skip to content

Commit eea55b6

Browse files
committed
add matomo support with app router
1 parent 07e4e1a commit eea55b6

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

app/[locale]/layout.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
import { Suspense } from "react"
12
import pick from "lodash.pick"
23
import { IBM_Plex_Mono, Inter } from "next/font/google"
34
import { notFound } from "next/navigation"
45
import { getMessages, setRequestLocale } from "next-intl/server"
56

67
import { Lang } from "@/lib/types"
78

9+
import Matomo from "@/components/Matomo"
10+
811
import { getLastDeployDate } from "@/lib/utils/getLastDeployDate"
912
import { getLocaleTimestamp } from "@/lib/utils/time"
1013

@@ -60,6 +63,10 @@ export default async function LocaleLayout({
6063
>
6164
<body>
6265
<Providers locale={locale} messages={messages}>
66+
<Suspense>
67+
<Matomo />
68+
</Suspense>
69+
6370
<BaseLayout lastDeployLocaleTimestamp={lastDeployLocaleTimestamp}>
6471
{children}
6572
</BaseLayout>

src/components/Matomo.tsx

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"use client"
2+
3+
import { useEffect, useState } from "react"
4+
import { usePathname } from "next/navigation"
5+
import { init, push } from "@socialgouv/matomo-next"
6+
7+
export default function Matomo() {
8+
const pathname = usePathname()
9+
10+
const [inited, setInited] = useState(false)
11+
const [previousPath, setPreviousPath] = useState("")
12+
13+
useEffect(() => {
14+
if (!process.env.IS_PREVIEW_DEPLOY && !inited) {
15+
init({
16+
url: process.env.NEXT_PUBLIC_MATOMO_URL!,
17+
siteId: process.env.NEXT_PUBLIC_MATOMO_SITE_ID!,
18+
})
19+
20+
setInited(true)
21+
}
22+
}, [inited])
23+
24+
/**
25+
* The @socialgouv/matomo-next does not work with next 13
26+
* Code from https://github.com/SocialGouv/matomo-next/issues/99
27+
*/
28+
useEffect(() => {
29+
if (!pathname) {
30+
return
31+
}
32+
33+
if (!previousPath) {
34+
return setPreviousPath(pathname)
35+
}
36+
37+
push(["setReferrerUrl", `${previousPath}`])
38+
push(["setCustomUrl", pathname])
39+
push(["deleteCustomVariables", "page"])
40+
setPreviousPath(pathname)
41+
// In order to ensure that the page title had been updated,
42+
// we delayed pushing the tracking to the next tick.
43+
setTimeout(() => {
44+
push(["setDocumentTitle", document.title])
45+
push(["trackPageView"])
46+
})
47+
/**
48+
* This is because we don't want to track previousPath
49+
* could be a if (previousPath === pathname) return; instead
50+
* But be sure to not send the tracking twice
51+
*/
52+
// eslint-disable-next-line react-hooks/exhaustive-deps
53+
}, [pathname])
54+
55+
return <></>
56+
}

0 commit comments

Comments
 (0)