Skip to content

Commit 6417f70

Browse files
committed
feat: added bugmail for error tracking
1 parent 015511e commit 6417f70

File tree

7 files changed

+140
-29
lines changed

7 files changed

+140
-29
lines changed

.env.example

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,11 @@ RESEND_AUDIENCE_ID=
3939
UPSTASH_REDIS_REST_URL=
4040
UPSTASH_REDIS_REST_TOKEN=
4141
UPSTASH_REDIS_NEWSLETTER_RATE_LIMIT_KEY=newsletter-rate-limit
42-
DAY_MAX_SUBMISSIONS=
42+
DAY_MAX_SUBMISSIONS=
43+
44+
#------------------------------------------------------------------------
45+
# BugMail: Simple error tracking via email (Optional)
46+
# Get keys from https://bugmail.site
47+
#------------------------------------------------------------------------
48+
NEXT_PUBLIC_BUGMAIL_API_KEY=
49+
NEXT_PUBLIC_BUGMAIL_PROJECT_ID=

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,19 @@ NEXT_PUBLIC_BAIDU_TONGJI=
136136
NEXT_PUBLIC_GOOGLE_ADSENSE=
137137
```
138138

139-
## 📁 Project Structure
139+
## � Error Tracking
140+
141+
This starter kit includes optional error tracking via [BugMail](https://bugmail.site).
142+
143+
To enable it, add these variables to your `.env`:
144+
```bash
145+
NEXT_PUBLIC_BUGMAIL_API_KEY=your_api_key
146+
NEXT_PUBLIC_BUGMAIL_PROJECT_ID=your_project_id
147+
```
148+
149+
If these variables are not present, error tracking is disabled and the app functions normally.
150+
151+
## �📁 Project Structure
140152

141153
```
142154
nextjs-starter/

app/[locale]/error.tsx

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
'use client';
2+
3+
import { createAppRouterErrorHandler } from '@bugmail-js/next';
4+
import { useEffect } from 'react';
5+
6+
// Initialize error reporter conditionally (outside component to avoid re-creation)
7+
const apiKey = process.env.NEXT_PUBLIC_BUGMAIL_API_KEY;
8+
const projectId = process.env.NEXT_PUBLIC_BUGMAIL_PROJECT_ID;
9+
10+
const reportError = (apiKey && projectId)
11+
? createAppRouterErrorHandler({
12+
apiKey,
13+
projectId,
14+
baseUrl: 'https://api.bugmail.site',
15+
environment: process.env.NODE_ENV,
16+
})
17+
: null;
18+
19+
export default function Error({
20+
error,
21+
reset,
22+
}: {
23+
error: Error & { digest?: string };
24+
reset: () => void;
25+
}) {
26+
useEffect(() => {
27+
// Report to BugMail if configured
28+
if (reportError) {
29+
reportError(error);
30+
}
31+
// Always log to console for debugging
32+
console.error('Application error:', error);
33+
}, [error]);
34+
35+
return (
36+
<div className="min-h-screen flex items-center justify-center bg-background">
37+
<div className="text-center space-y-6 p-8 max-w-md">
38+
<div className="space-y-2">
39+
<h2 className="text-2xl font-bold text-foreground">
40+
Something went wrong!
41+
</h2>
42+
<p className="text-muted-foreground">
43+
An unexpected error occurred. Please try again.
44+
</p>
45+
</div>
46+
<button
47+
onClick={() => reset()}
48+
className="px-6 py-3 bg-primary text-primary-foreground rounded-lg font-medium hover:opacity-90 transition-opacity"
49+
>
50+
Try again
51+
</button>
52+
</div>
53+
</div>
54+
);
55+
}

app/[locale]/layout.tsx

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import BaiDuAnalytics from "@/app/BaiDuAnalytics";
22
import GoogleAdsense from "@/app/GoogleAdsense";
33
import GoogleAnalytics from "@/app/GoogleAnalytics";
44
import PlausibleAnalytics from "@/app/PlausibleAnalytics";
5+
import { SafeBugMailProvider } from "@/components/bugmail-provider";
56
import Footer from "@/components/footer/Footer";
67
import Header from "@/components/header/Header";
78
import { LanguageDetectionAlert } from "@/components/LanguageDetectionAlert";
@@ -75,34 +76,36 @@ export default async function LocaleLayout({
7576
"min-h-screen bg-background flex flex-col font-sans antialiased"
7677
)}
7778
>
78-
<NextIntlClientProvider messages={messages}>
79-
<ThemeProvider
80-
attribute="class"
81-
defaultTheme={siteConfig.defaultNextTheme}
82-
enableSystem
83-
>
84-
{messages.LanguageDetection && <LanguageDetectionAlert />}
85-
{messages.Header && <Header />}
79+
<SafeBugMailProvider>
80+
<NextIntlClientProvider messages={messages}>
81+
<ThemeProvider
82+
attribute="class"
83+
defaultTheme={siteConfig.defaultNextTheme}
84+
enableSystem
85+
>
86+
{messages.LanguageDetection && <LanguageDetectionAlert />}
87+
{messages.Header && <Header />}
8688

87-
<main className="flex-1 flex flex-col items-center">
88-
{children}
89-
</main>
89+
<main className="flex-1 flex flex-col items-center">
90+
{children}
91+
</main>
9092

91-
{messages.Footer && <Footer />}
92-
</ThemeProvider>
93-
</NextIntlClientProvider>
94-
<TailwindIndicator />
95-
{process.env.NODE_ENV === "development" ? (
96-
<></>
97-
) : (
98-
<>
99-
<Analytics />
100-
<BaiDuAnalytics />
101-
<GoogleAnalytics />
102-
<GoogleAdsense />
103-
<PlausibleAnalytics />
104-
</>
105-
)}
93+
{messages.Footer && <Footer />}
94+
</ThemeProvider>
95+
</NextIntlClientProvider>
96+
<TailwindIndicator />
97+
{process.env.NODE_ENV === "development" ? (
98+
<></>
99+
) : (
100+
<>
101+
<Analytics />
102+
<BaiDuAnalytics />
103+
<GoogleAnalytics />
104+
<GoogleAdsense />
105+
<PlausibleAnalytics />
106+
</>
107+
)}
108+
</SafeBugMailProvider>
106109
</body>
107110
</html>
108111
);

components/bugmail-provider.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use client';
2+
3+
import { BugMailProvider } from '@bugmail-js/next';
4+
5+
/**
6+
* SafeBugMailProvider - Optional error tracking wrapper
7+
*
8+
* If BUGMAIL credentials are configured, wraps children with BugMailProvider
9+
* for automatic error tracking. If not configured, renders children directly.
10+
*
11+
* To enable: Add NEXT_PUBLIC_BUGMAIL_API_KEY and NEXT_PUBLIC_BUGMAIL_PROJECT_ID
12+
* to your .env.local file. Get keys from https://bugmail.site
13+
*/
14+
export function SafeBugMailProvider({ children }: { children: React.ReactNode }) {
15+
const apiKey = process.env.NEXT_PUBLIC_BUGMAIL_API_KEY;
16+
const projectId = process.env.NEXT_PUBLIC_BUGMAIL_PROJECT_ID;
17+
18+
// If credentials are not configured, just render children (no-op)
19+
if (!apiKey || !projectId) {
20+
return <>{children}</>;
21+
}
22+
23+
// If configured, wrap with BugMail for automatic error tracking
24+
return (
25+
<BugMailProvider
26+
apiKey={apiKey}
27+
projectId={projectId}
28+
endpoint="https://api.bugmail.site"
29+
>
30+
{children}
31+
</BugMailProvider>
32+
);
33+
}

next-env.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// <reference types="next" />
22
/// <reference types="next/image-types/global" />
3-
import "./.next/types/routes.d.ts";
3+
import "./.next/dev/types/routes.d.ts";
44

55
// NOTE: This file should not be edited
66
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"fix": "pnpm i fix-react2shell-next@latest && npx fix-react2shell-next"
1414
},
1515
"dependencies": {
16+
"@bugmail-js/next": "^0.1.2",
1617
"@radix-ui/react-dropdown-menu": "^2.1.4",
1718
"@radix-ui/react-select": "^2.1.6",
1819
"@radix-ui/react-slot": "^1.1.0",

0 commit comments

Comments
 (0)