chore: remove Sentry integration
All checks were successful
Gitea CI / test-build (push) Successful in 11m8s
All checks were successful
Gitea CI / test-build (push) Successful in 11m8s
Remove @sentry/nextjs and all related files since it was never actively used. - Delete sentry.server.config.ts, sentry.edge.config.ts - Delete sentry-example-page and sentry-example-api routes - Clean up instrumentation.ts, global-error.tsx, middleware.ts - Remove Sentry env vars from env.example and docs - Update CLAUDE.md, copilot-instructions.md, PRODUCTION_READINESS.md Middleware bundle reduced from 86KB to 34.8KB (-51KB). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
3
.github/copilot-instructions.md
vendored
3
.github/copilot-instructions.md
vendored
@@ -58,7 +58,7 @@ npm run db:seed # Seed database
|
|||||||
- **CMS**: Directus (self-hosted, GraphQL, optional)
|
- **CMS**: Directus (self-hosted, GraphQL, optional)
|
||||||
- **Automation**: n8n webhooks (status, chat, hardcover, image generation)
|
- **Automation**: n8n webhooks (status, chat, hardcover, image generation)
|
||||||
- **i18n**: next-intl (EN + DE)
|
- **i18n**: next-intl (EN + DE)
|
||||||
- **Monitoring**: Sentry
|
- **Monitoring**: Console error logging (development mode only)
|
||||||
- **Deployment**: Docker (standalone mode) + Nginx
|
- **Deployment**: Docker (standalone mode) + Nginx
|
||||||
|
|
||||||
### Key Directories
|
### Key Directories
|
||||||
@@ -200,7 +200,6 @@ REDIS_URL=redis://...
|
|||||||
|
|
||||||
### Optional
|
### Optional
|
||||||
```bash
|
```bash
|
||||||
SENTRY_DSN=...
|
|
||||||
NEXT_PUBLIC_BASE_URL=https://dk0.dev
|
NEXT_PUBLIC_BASE_URL=https://dk0.dev
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -37,10 +37,6 @@ yarn-error.log*
|
|||||||
# env files (can opt-in for committing if needed)
|
# env files (can opt-in for committing if needed)
|
||||||
.env*
|
.env*
|
||||||
|
|
||||||
# Sentry
|
|
||||||
.sentryclirc
|
|
||||||
sentry.properties
|
|
||||||
|
|
||||||
# vercel
|
# vercel
|
||||||
.vercel
|
.vercel
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Personal portfolio website for Dennis Konkol (dk0.dev). Built with Next.js 15 (A
|
|||||||
- **CMS**: Directus (self-hosted, REST/GraphQL, optional)
|
- **CMS**: Directus (self-hosted, REST/GraphQL, optional)
|
||||||
- **Automation**: n8n webhooks (status, chat, hardcover, image generation)
|
- **Automation**: n8n webhooks (status, chat, hardcover, image generation)
|
||||||
- **i18n**: next-intl (EN + DE), message files in `messages/`
|
- **i18n**: next-intl (EN + DE), message files in `messages/`
|
||||||
- **Monitoring**: Sentry
|
- **Monitoring**: Console error logging (development mode only)
|
||||||
- **Deployment**: Docker + Nginx, CI via Gitea Actions
|
- **Deployment**: Docker + Nginx, CI via Gitea Actions
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
@@ -122,7 +122,6 @@ DATABASE_URL=postgresql://...
|
|||||||
|
|
||||||
# Optional
|
# Optional
|
||||||
REDIS_URL=redis://...
|
REDIS_URL=redis://...
|
||||||
SENTRY_DSN=...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Conventions
|
## Conventions
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
import * as Sentry from "@sentry/nextjs";
|
|
||||||
import { NextResponse } from "next/server";
|
|
||||||
|
|
||||||
export const dynamic = "force-dynamic";
|
|
||||||
|
|
||||||
// A faulty API route to test Sentry's error monitoring
|
|
||||||
export function GET() {
|
|
||||||
const testError = new Error("Sentry Example API Route Error");
|
|
||||||
Sentry.captureException(testError);
|
|
||||||
return NextResponse.json({ error: "This is a test error from the API route" }, { status: 500 });
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import * as Sentry from "@sentry/nextjs";
|
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
|
||||||
export default function GlobalError({
|
export default function GlobalError({
|
||||||
@@ -11,15 +10,9 @@ export default function GlobalError({
|
|||||||
reset: () => void;
|
reset: () => void;
|
||||||
}) {
|
}) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Capture exception in Sentry
|
if (process.env.NODE_ENV === "development") {
|
||||||
Sentry.captureException(error);
|
|
||||||
|
|
||||||
// Log error details to console
|
|
||||||
console.error("Global Error:", error);
|
console.error("Global Error:", error);
|
||||||
console.error("Error Name:", error.name);
|
}
|
||||||
console.error("Error Message:", error.message);
|
|
||||||
console.error("Error Stack:", error.stack);
|
|
||||||
console.error("Error Digest:", error.digest);
|
|
||||||
}, [error]);
|
}, [error]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,81 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import Head from "next/head";
|
|
||||||
import * as Sentry from "@sentry/nextjs";
|
|
||||||
|
|
||||||
export default function SentryExamplePage() {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Head>
|
|
||||||
<title>Sentry Onboarding</title>
|
|
||||||
<meta name="description" content="Test Sentry for your Next.js app!" />
|
|
||||||
</Head>
|
|
||||||
|
|
||||||
<main
|
|
||||||
style={{
|
|
||||||
minHeight: "100vh",
|
|
||||||
display: "flex",
|
|
||||||
flexDirection: "column",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
padding: "2rem",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<h1 style={{ fontSize: "2rem", fontWeight: "bold", marginBottom: "1rem" }}>
|
|
||||||
Sentry Onboarding
|
|
||||||
</h1>
|
|
||||||
<p style={{ marginBottom: "1rem" }}>
|
|
||||||
Get started by sending us a sample error:
|
|
||||||
</p>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
style={{
|
|
||||||
padding: "0.5rem 1rem",
|
|
||||||
backgroundColor: "#0070f3",
|
|
||||||
color: "white",
|
|
||||||
border: "none",
|
|
||||||
borderRadius: "0.25rem",
|
|
||||||
cursor: "pointer",
|
|
||||||
}}
|
|
||||||
onClick={async () => {
|
|
||||||
Sentry.captureException(new Error("This is your first error!"));
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await fetch("/api/sentry-example-api");
|
|
||||||
if (!res.ok) {
|
|
||||||
throw new Error("Sentry Example API Error");
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
Sentry.captureException(err);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Throw error!
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<p style={{ marginTop: "2rem", fontSize: "0.875rem", color: "#666" }}>
|
|
||||||
Next, look for the error on the{" "}
|
|
||||||
<a
|
|
||||||
style={{ color: "#0070f3", textDecoration: "underline" }}
|
|
||||||
href="https://dk0.sentry.io/issues/?project=4510751388926032"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
Issues Page
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<p style={{ fontSize: "0.875rem", color: "#666" }}>
|
|
||||||
For more information, see{" "}
|
|
||||||
<a
|
|
||||||
style={{ color: "#0070f3", textDecoration: "underline" }}
|
|
||||||
href="https://docs.sentry.io/platforms/javascript/guides/nextjs/"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
https://docs.sentry.io/platforms/javascript/guides/nextjs/
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -13,7 +13,7 @@ This document provides an assessment of the portfolio website's production readi
|
|||||||
- [x] Input sanitization on forms
|
- [x] Input sanitization on forms
|
||||||
- [x] SQL injection protection (Prisma ORM)
|
- [x] SQL injection protection (Prisma ORM)
|
||||||
- [x] XSS protection via React and sanitize-html
|
- [x] XSS protection via React and sanitize-html
|
||||||
- [x] Error monitoring with Sentry.io
|
- [x] Error logging in development mode
|
||||||
|
|
||||||
### Performance
|
### Performance
|
||||||
- [x] Next.js App Router with Server Components
|
- [x] Next.js App Router with Server Components
|
||||||
@@ -42,10 +42,8 @@ This document provides an assessment of the portfolio website's production readi
|
|||||||
- [x] Analytics opt-in (Umami - privacy-friendly)
|
- [x] Analytics opt-in (Umami - privacy-friendly)
|
||||||
- [x] Data processing documentation
|
- [x] Data processing documentation
|
||||||
- [x] Contact form with consent
|
- [x] Contact form with consent
|
||||||
- [x] Sentry.io mentioned in privacy policy
|
|
||||||
|
|
||||||
### Monitoring & Observability
|
### Monitoring & Observability
|
||||||
- [x] Sentry.io error tracking (configured)
|
|
||||||
- [x] Umami analytics (self-hosted, privacy-friendly)
|
- [x] Umami analytics (self-hosted, privacy-friendly)
|
||||||
- [x] Health check endpoint (`/api/health`)
|
- [x] Health check endpoint (`/api/health`)
|
||||||
- [x] Logging infrastructure
|
- [x] Logging infrastructure
|
||||||
@@ -79,15 +77,6 @@ This document provides an assessment of the portfolio website's production readi
|
|||||||
- Locations: Hero.tsx, CurrentlyReading.tsx, Projects pages
|
- Locations: Hero.tsx, CurrentlyReading.tsx, Projects pages
|
||||||
- Benefit: Better performance, automatic optimization
|
- Benefit: Better performance, automatic optimization
|
||||||
|
|
||||||
2. **Configure Sentry.io DSN**
|
|
||||||
- Set `NEXT_PUBLIC_SENTRY_DSN` in production environment
|
|
||||||
- Set `SENTRY_AUTH_TOKEN` for source map uploads
|
|
||||||
- Get DSN from: https://sentry.io/settings/dk0/projects/portfolio/keys/
|
|
||||||
|
|
||||||
3. **Review CSP for Sentry**
|
|
||||||
- May need to adjust Content-Security-Policy headers to allow Sentry
|
|
||||||
- Add `connect-src` directive for `*.sentry.io`
|
|
||||||
|
|
||||||
### Medium Priority
|
### Medium Priority
|
||||||
1. **Accessibility audit**
|
1. **Accessibility audit**
|
||||||
- Run Lighthouse audit
|
- Run Lighthouse audit
|
||||||
@@ -105,7 +94,6 @@ This document provides an assessment of the portfolio website's production readi
|
|||||||
|
|
||||||
### Low Priority
|
### Low Priority
|
||||||
1. **Enhanced monitoring**
|
1. **Enhanced monitoring**
|
||||||
- Custom Sentry contexts for better debugging
|
|
||||||
- Performance metrics dashboard
|
- Performance metrics dashboard
|
||||||
|
|
||||||
2. **Advanced features**
|
2. **Advanced features**
|
||||||
@@ -123,10 +111,6 @@ Before deploying to production:
|
|||||||
DATABASE_URL=postgresql://...
|
DATABASE_URL=postgresql://...
|
||||||
REDIS_URL=redis://...
|
REDIS_URL=redis://...
|
||||||
|
|
||||||
# Sentry (Recommended)
|
|
||||||
NEXT_PUBLIC_SENTRY_DSN=https://...@sentry.io/...
|
|
||||||
SENTRY_AUTH_TOKEN=...
|
|
||||||
|
|
||||||
# Email (Optional)
|
# Email (Optional)
|
||||||
MY_EMAIL=...
|
MY_EMAIL=...
|
||||||
MY_PASSWORD=...
|
MY_PASSWORD=...
|
||||||
@@ -156,7 +140,6 @@ Before deploying to production:
|
|||||||
- Test HTTPS redirect
|
- Test HTTPS redirect
|
||||||
|
|
||||||
6. **Monitoring**
|
6. **Monitoring**
|
||||||
- Verify Sentry is receiving events
|
|
||||||
- Check Umami analytics tracking
|
- Check Umami analytics tracking
|
||||||
- Test health endpoint
|
- Test health endpoint
|
||||||
|
|
||||||
@@ -200,13 +183,12 @@ The application is production-ready with the following notes:
|
|||||||
3. **Performance**: Optimized for production
|
3. **Performance**: Optimized for production
|
||||||
4. **SEO**: Properly configured for search engines
|
4. **SEO**: Properly configured for search engines
|
||||||
5. **Privacy**: GDPR-compliant with privacy policy
|
5. **Privacy**: GDPR-compliant with privacy policy
|
||||||
6. **Monitoring**: Sentry.io configured (needs DSN in production)
|
6. **Monitoring**: Umami analytics (self-hosted)
|
||||||
|
|
||||||
**Next Steps**:
|
**Next Steps**:
|
||||||
1. Configure Sentry.io DSN in production environment
|
1. Replace `<img>` tags with Next.js `<Image />` for optimal performance
|
||||||
2. Replace `<img>` tags with Next.js `<Image />` for optimal performance
|
2. Run final accessibility audit
|
||||||
3. Run final accessibility audit
|
3. Monitor performance metrics after deployment
|
||||||
4. Monitor performance metrics after deployment
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,4 @@ PRISMA_AUTO_BASELINE=false
|
|||||||
# SKIP_PRISMA_MIGRATE=true
|
# SKIP_PRISMA_MIGRATE=true
|
||||||
|
|
||||||
# Monitoring (optional)
|
# Monitoring (optional)
|
||||||
NEXT_PUBLIC_SENTRY_DSN=your-sentry-dsn
|
|
||||||
SENTRY_AUTH_TOKEN=your-sentry-auth-token
|
|
||||||
LOG_LEVEL=info
|
LOG_LEVEL=info
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
// Sentry client SDK disabled to reduce bundle size (~400KB).
|
// Client-side instrumentation hook for Next.js
|
||||||
// To re-enable, restore the @sentry/nextjs import and withSentryConfig in next.config.ts.
|
// Add any client-side instrumentation here if needed
|
||||||
|
|||||||
@@ -1,13 +1,4 @@
|
|||||||
import * as Sentry from '@sentry/nextjs';
|
|
||||||
|
|
||||||
export async function register() {
|
export async function register() {
|
||||||
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
// Instrumentation hook for Next.js
|
||||||
await import('./sentry.server.config');
|
// Add any server-side instrumentation here if needed
|
||||||
}
|
|
||||||
|
|
||||||
if (process.env.NEXT_RUNTIME === 'edge') {
|
|
||||||
await import('./sentry.edge.config');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const onRequestError = Sentry.captureRequestError;
|
|
||||||
|
|||||||
@@ -70,9 +70,7 @@ export function middleware(request: NextRequest) {
|
|||||||
pathname.startsWith("/api/") ||
|
pathname.startsWith("/api/") ||
|
||||||
pathname === "/api" ||
|
pathname === "/api" ||
|
||||||
pathname.startsWith("/manage") ||
|
pathname.startsWith("/manage") ||
|
||||||
pathname.startsWith("/editor") ||
|
pathname.startsWith("/editor");
|
||||||
pathname === "/sentry-example-page" ||
|
|
||||||
pathname.startsWith("/sentry-example-page/");
|
|
||||||
|
|
||||||
// Locale routing for public site pages
|
// Locale routing for public site pages
|
||||||
const responseUrl = request.nextUrl.clone();
|
const responseUrl = request.nextUrl.clone();
|
||||||
|
|||||||
2803
package-lock.json
generated
2803
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -55,7 +55,6 @@
|
|||||||
"@next/bundle-analyzer": "^15.1.7",
|
"@next/bundle-analyzer": "^15.1.7",
|
||||||
"@prisma/client": "^5.22.0",
|
"@prisma/client": "^5.22.0",
|
||||||
"@react-three/fiber": "^9.5.0",
|
"@react-three/fiber": "^9.5.0",
|
||||||
"@sentry/nextjs": "^10.36.0",
|
|
||||||
"@shadergradient/react": "^2.4.20",
|
"@shadergradient/react": "^2.4.20",
|
||||||
"@swc/helpers": "^0.5.19",
|
"@swc/helpers": "^0.5.19",
|
||||||
"@tiptap/extension-color": "^3.15.3",
|
"@tiptap/extension-color": "^3.15.3",
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
// This file configures the initialization of Sentry for edge features (middleware, etc).
|
|
||||||
// The config you add here will be used whenever the server handles a request.
|
|
||||||
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
|
|
||||||
|
|
||||||
import * as Sentry from "@sentry/nextjs";
|
|
||||||
|
|
||||||
Sentry.init({
|
|
||||||
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN || "https://148e31ea874c60f3d2e0f70fd6701f6b@o4510751135105024.ingest.de.sentry.io/4510751388926032",
|
|
||||||
enabled: false,
|
|
||||||
});
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
// This file configures the initialization of Sentry on the server.
|
|
||||||
// The config you add here will be used whenever the server handles a request.
|
|
||||||
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
|
|
||||||
|
|
||||||
import * as Sentry from "@sentry/nextjs";
|
|
||||||
|
|
||||||
Sentry.init({
|
|
||||||
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN || "https://148e31ea874c60f3d2e0f70fd6701f6b@o4510751135105024.ingest.de.sentry.io/4510751388926032",
|
|
||||||
enabled: false,
|
|
||||||
});
|
|
||||||
Reference in New Issue
Block a user