Skip to content

Commit 6617725

Browse files
committed
Version 1 of NextJS 15 + TrackJS integration example
1 parent 01e505f commit 6617725

26 files changed

+554
-2
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ This repository contains example projects for using and integrating the TrackJS
1616

1717
## Examples
1818

19-
* [NextJS 14+](./nextjs14/)
19+
* [NextJS 15+](./nextjs15/)
20+
* [NextJS 14](./nextjs14/)
2021
* [NextJS (old)](./nextjs9/)
2122
* [Express](./express/)
2223
* [RequireJS](./requirejs/)

nextjs14/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Integrating NextJS 14+ with the TrackJS Agents.
1111

1212
## Reference
1313

14-
- [NextJS Integration Docs](https://docs.trackjs.com/browser-agent/integrations/nextjs14/)
14+
- [NextJS Integration Docs](https://docs.trackjs.com/browser-agent/integrations/legacy/nextjs14/)
1515
- [TrackJS Browser Agent Documentation](https://docs.trackjs.com/browser-agent/)
1616
- [TrackJS Node Agent Documentation](https://docs.trackjs.com/node-agent/)
1717

nextjs15/.eslintrc.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"extends": [
3+
"next/core-web-vitals"
4+
]
5+
}

nextjs15/.gitignore

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
.yarn/install-state.gz
8+
9+
# testing
10+
/coverage
11+
12+
# next.js
13+
/.next/
14+
/out/
15+
16+
# production
17+
/build
18+
19+
# misc
20+
.DS_Store
21+
*.pem
22+
23+
# debug
24+
npm-debug.log*
25+
yarn-debug.log*
26+
yarn-error.log*
27+
28+
# local env files
29+
.env*.local
30+
31+
# vercel
32+
.vercel
33+
34+
# typescript
35+
*.tsbuildinfo
36+
next-env.d.ts

nextjs15/README.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<p align="center">
2+
<a href="https://trackjs.com/" target="_blank" align="center">
3+
<img src="https://trackjs.com/assets/external/github_readme.svg" width="280">
4+
</a>
5+
<br />
6+
</p>
7+
8+
# TrackJS NextJS15 Integration Example
9+
10+
Integrating NextJS 15+ with TrackJS using the `trackjs-nextjs` package.
11+
12+
## Reference
13+
14+
- [NextJS Integration Docs](https://docs.trackjs.com/browser-agent/integrations/nextjs15/)
15+
- [TrackJS Browser Agent Documentation](https://docs.trackjs.com/browser-agent/)
16+
- [TrackJS Node Agent Documentation](https://docs.trackjs.com/node-agent/)
17+
18+
## Usage
19+
20+
```bash
21+
npm install
22+
npm run build
23+
npm start
24+
```
25+
26+
Visit `http://localhost:3000/` to load a page and generate requests.
27+

nextjs15/app/client-error/page.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import ErrorButton from "../components/ErrorButton";
2+
3+
export default function ClientError() {
4+
5+
return (
6+
<div className="flex min-h-screen flex-col items-center p-24">
7+
<h1 className="mb-3 text-2xl font-semibold">Client-Side Logic Errors</h1>
8+
<p className="mb-3">
9+
Bugs are inevitable. This page throws an error when clicking a button, which is captured by TrackJS.
10+
</p>
11+
<ErrorButton label={"💣 Simulate Logic Error"} />
12+
</div>
13+
);
14+
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"use client";
2+
3+
import { useState } from "react";
4+
5+
export default function ErrorButton(props: any) {
6+
const [raiseError, setRaiseError] = useState(false);
7+
8+
if (raiseError) {
9+
// "a" is undefined so "props.a.b" will result in an error
10+
return props.a.b;
11+
} else {
12+
return (
13+
<button onClick={() => setRaiseError((error) => !error)} className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded">
14+
{props.label}
15+
</button>
16+
);
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
"use client";
2+
3+
export default function NetworkButton(props: any) {
4+
return (
5+
<button onClick={() => fetch("/notReal")} className="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded">
6+
{props.label}
7+
</button>
8+
);
9+
}

nextjs15/app/favicon.ico

25.3 KB
Binary file not shown.

nextjs15/app/global-error.tsx

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"use client";
2+
3+
import NextError from "next/error";
4+
import { useEffect } from "react";
5+
import { TrackJS } from "trackjs-nextjs";
6+
7+
export default function GlobalError({
8+
error,
9+
reset,
10+
}: {
11+
error: Error & { digest?: string }
12+
reset: () => void
13+
}) {
14+
useEffect(() => {
15+
TrackJS.track(error);
16+
}, [error]);
17+
18+
return (
19+
<html>
20+
<body>
21+
{/* This is the default Next.js error component. */}
22+
<NextError statusCode={undefined as any} />
23+
</body>
24+
</html>
25+
);
26+
}

nextjs15/app/globals.css

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
4+
5+
:root {
6+
--foreground-rgb: 0, 0, 0;
7+
--background-start-rgb: 214, 219, 220;
8+
--background-end-rgb: 255, 255, 255;
9+
}
10+
11+
@media (prefers-color-scheme: dark) {
12+
:root {
13+
--foreground-rgb: 255, 255, 255;
14+
--background-start-rgb: 0, 0, 0;
15+
--background-end-rgb: 0, 0, 0;
16+
}
17+
}
18+
19+
body {
20+
color: rgb(var(--foreground-rgb));
21+
background: linear-gradient(
22+
to bottom,
23+
transparent,
24+
rgb(var(--background-end-rgb))
25+
)
26+
rgb(var(--background-start-rgb));
27+
}
28+
29+
h2 {
30+
font-size: 1.4em;
31+
}
32+
33+
@layer utilities {
34+
.text-balance {
35+
text-wrap: balance;
36+
}
37+
}

nextjs15/app/layout.tsx

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import type { Metadata } from "next";
2+
import { Inter } from "next/font/google";
3+
import { TrackJSAgent } from "trackjs-nextjs"
4+
5+
import "./globals.css";
6+
7+
const inter = Inter({ subsets: ["latin"] });
8+
9+
export const metadata: Metadata = {
10+
title: "TrackJS in NextJS 15+",
11+
description: "Generated by create next app",
12+
};
13+
14+
export default function RootLayout({
15+
children,
16+
}: Readonly<{
17+
children: React.ReactNode;
18+
}>) {
19+
return (
20+
<html lang="en">
21+
<head>
22+
<TrackJSAgent config={{
23+
token: "YOUR_TOKEN"
24+
}} />
25+
</head>
26+
<body>
27+
<main className={"main"}>{children}</main>
28+
</body>
29+
</html>
30+
);
31+
}

nextjs15/app/network-error/page.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import NetworkButton from "../components/NetworkButton";
2+
3+
export default function NetworkError() {
4+
5+
return (
6+
<div className="flex min-h-screen flex-col items-center p-24">
7+
<h1 className="mb-3 text-2xl font-semibold">Network Errors</h1>
8+
<p className="mb-3">
9+
Networks are volatile. This page captures a 404 response from a FETCH request.
10+
</p>
11+
<NetworkButton label={"💣 Trigger Network Error"} />
12+
</div>
13+
);
14+
}

nextjs15/app/page.tsx

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import Image from "next/image";
2+
import Link from 'next/link'
3+
4+
export default function Home() {
5+
return (
6+
<main className="flex min-h-screen flex-col items-center justify-between p-24">
7+
<div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex">
8+
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
9+
Tracking Errors in NextJS 15+ Demo
10+
</p>
11+
</div>
12+
13+
<div className="relative flex place-items-center before:absolute before:h-[300px] before:w-full sm:before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-full sm:after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 before:lg:h-[360px] z-[-1]">
14+
<Image
15+
className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert"
16+
src="/trackjs.svg"
17+
alt="TrackJS Logo"
18+
width={300}
19+
height={60}
20+
priority
21+
/>
22+
</div>
23+
24+
<div>
25+
<h2 className="text-3xl font-semibold">App Router Examples</h2>
26+
<div className="mb-32 grid text-center lg:max-w-5xl lg:w-full lg:mb-0 lg:grid-cols-4 lg:text-left">
27+
<Link
28+
href="/client-error"
29+
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
30+
prefetch={false}
31+
>
32+
<h2 className={`mb-3 text-2xl font-semibold`}>
33+
Client Logic Errors
34+
</h2>
35+
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
36+
See how TrackJS captures client-side logic errors
37+
</p>
38+
</Link>
39+
40+
<Link
41+
href="/network-error"
42+
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
43+
prefetch={false}
44+
>
45+
<h2 className={`mb-3 text-2xl font-semibold`}>
46+
Network Errors
47+
</h2>
48+
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
49+
See how TrackJS captures network errors
50+
</p>
51+
</Link>
52+
53+
<Link
54+
href="/third-party"
55+
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
56+
prefetch={false}
57+
>
58+
<h2 className={`mb-3 text-2xl font-semibold`}>
59+
Third Party Errors
60+
</h2>
61+
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
62+
See how TrackJS captures errors in third-party code
63+
</p>
64+
</Link>
65+
66+
<Link
67+
href="/server-error?shouldThrow=1"
68+
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
69+
prefetch={false}
70+
>
71+
<h2 className={`mb-3 text-2xl font-semibold`}>
72+
Server Errors
73+
</h2>
74+
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
75+
See how TrackJS captures errors from the server-side.
76+
</p>
77+
</Link>
78+
</div>
79+
</div>
80+
81+
<div>
82+
<h2 className="text-3xl font-semibold">Pages Router Examples</h2>
83+
<div className="mb-32 grid text-center lg:max-w-5xl lg:w-full lg:mb-0 lg:grid-cols-4 lg:text-left">
84+
<Link
85+
href="/pages/client-error"
86+
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
87+
prefetch={false}
88+
>
89+
<h2 className={`mb-3 text-2xl font-semibold`}>
90+
Client Logic Errors
91+
</h2>
92+
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
93+
See how TrackJS captures client-side logic errors
94+
</p>
95+
</Link>
96+
97+
<Link
98+
href="/pages/server-error?shouldThrow=1"
99+
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
100+
prefetch={false}
101+
>
102+
<h2 className={`mb-3 text-2xl font-semibold`}>
103+
Server Errors
104+
</h2>
105+
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
106+
See how TrackJS captures errors from the server-side.
107+
</p>
108+
</Link>
109+
</div>
110+
</div>
111+
112+
</main>
113+
);
114+
}

nextjs15/app/server-error/page.tsx

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
export default async function ServerError({
3+
params,
4+
searchParams
5+
}: {
6+
params: Promise<{ slug: string }>,
7+
searchParams: Promise<{ [key: string]: string }>
8+
}) {
9+
10+
if ((await searchParams).shouldThrow) {
11+
throw new Error("server thrown error");
12+
}
13+
14+
return (
15+
<div className="flex min-h-screen flex-col items-center p-24">
16+
<h1 className="mb-3 text-2xl font-semibold">Server Errors</h1>
17+
<p className="mb-3">
18+
Generates a server error when using ?shouldThrow=1 in the querystring.
19+
</p>
20+
</div>
21+
)
22+
23+
}

0 commit comments

Comments
 (0)