Voeg Sentry-tunnel ook toe voor lokale development

Co-authored-by: Junie <junie@jetbrains.com>
This commit is contained in:
2026-07-25 15:46:58 +02:00
co-authored by Junie
parent f650c01c3e
commit 588e198028
4 changed files with 31 additions and 6 deletions
@@ -528,3 +528,15 @@
**Context**: Post-workflow follow-up (feature already marked Complete); continues the `feature/sentry_error_logging` branch. `pnpm run build`, `pnpm run lint` and `pnpm run test` re-verified successfully after the change. Changes not yet committed/pushed. **Context**: Post-workflow follow-up (feature already marked Complete); continues the `feature/sentry_error_logging` branch. `pnpm run build`, `pnpm run lint` and `pnpm run test` re-verified successfully after the change. Changes not yet committed/pushed.
--- ---
## Post-Completion Follow-up: Sentry "Tunnel" Extended to Local Development
**Timestamp**: 2026-07-25T15:45:00Z
**User Input**: "Is het ook gefixt voor lokaal?" — followed by: "Ja voeg voor lokaal ook een tunnel toe".
**AI Response**: "Added a `server.proxy` entry for `/sentry-tunnel` in `vite.config.ts`, forwarding to the same Sentry envelope endpoint as the reverse-proxy Pi's nginx tunnel (matching the org/project baked into the local `.env.local` DSN). Simplified `src/main.tsx`'s `tunnel` option from the previous `import.meta.env.DEV ? undefined : '/sentry-tunnel'` to an unconditional `'/sentry-tunnel'`, since `pnpm dev` now also has a matching proxy route — local testing no longer requires disabling the ad-blocker. Updated `monitoring-setup.md` to describe the tunnel as active in all environments (including local), and to flag that the org/project id must stay in sync across the nginx config, the Vite proxy target, and the configured DSN."
**Context**: Post-workflow follow-up (feature already marked Complete); continues the `feature/sentry_error_logging` branch. `pnpm run build`, `pnpm run lint` and `pnpm run test` re-verified successfully after the change. Changes not yet committed/pushed.
---
@@ -25,7 +25,7 @@ Both the console and Sentry are now active (original Question 3 resolved as a co
- **Manual follow-up required**: create a free Sentry project (https://sentry.io) for this app, copy its DSN, and set it as the `VITE_SENTRY_DSN` repository variable in Gitea (Repository Settings → Actions → Variables). Until that variable is set, the build still succeeds and the site still works — Sentry reporting simply stays inactive. - **Manual follow-up required**: create a free Sentry project (https://sentry.io) for this app, copy its DSN, and set it as the `VITE_SENTRY_DSN` repository variable in Gitea (Repository Settings → Actions → Variables). Until that variable is set, the build still succeeds and the site still works — Sentry reporting simply stays inactive.
- Free tier limits (error volume, retention) are typically sufficient for a low-traffic marketing site. - Free tier limits (error volume, retention) are typically sufficient for a low-traffic marketing site.
- **Not (yet) implemented, by explicit choice**: automatic source map upload (via `@sentry/vite-plugin`), which the official Sentry setup guide also recommends so stack traces show real source code instead of minified code. This requires a Sentry auth token/org/project as a new Gitea secret; deliberately left out of scope for now — revisit if readable production stack traces become a priority. - **Not (yet) implemented, by explicit choice**: automatic source map upload (via `@sentry/vite-plugin`), which the official Sentry setup guide also recommends so stack traces show real source code instead of minified code. This requires a Sentry auth token/org/project as a new Gitea secret; deliberately left out of scope for now — revisit if readable production stack traces become a priority.
- **Ad-blocker mitigation via a Sentry "tunnel" (test/production only)**: requests straight to `*.ingest.<region>.sentry.io` are commonly blocked client-side by ad-blockers/privacy extensions (`ERR_BLOCKED_BY_CLIENT`), because they resemble third-party tracking. To avoid this in deployed environments, `Sentry.init()` sets `tunnel: '/sentry-tunnel'` (disabled — `undefined` — during local `pnpm dev`, where the ad-blocker itself is disabled instead, per earlier decision). The reverse-proxy Pi (`nginx/reverse-proxy-nginx.conf.example`) forwards that path server-side to Sentry's envelope endpoint, so the browser only ever talks to the first-party domain (e.g. `test.slpsoftware.nl`). This relies on full control over the reverse-proxy's nginx config, which is the case here (self-hosted on the user's own Raspberry Pi's) — it would not work on a third-party/shared host without reverse-proxy access. **Important**: the org-/project-id hardcoded in that nginx `location /sentry-tunnel` block must match whatever `VITE_SENTRY_DSN` is actually configured for that environment; update both together if the Sentry project/DSN ever changes. - **Ad-blocker mitigation via a Sentry "tunnel" (all environments, including local)**: requests straight to `*.ingest.<region>.sentry.io` are commonly blocked client-side by ad-blockers/privacy extensions (`ERR_BLOCKED_BY_CLIENT`), because they resemble third-party tracking. To avoid this, `Sentry.init()` always sets `tunnel: '/sentry-tunnel'`. In deployed (test/production) environments, the reverse-proxy Pi (`nginx/reverse-proxy-nginx.conf.example`) forwards that path server-side to Sentry's envelope endpoint, so the browser only ever talks to the first-party domain (e.g. `test.slpsoftware.nl`). Locally (`pnpm dev`), the equivalent route is provided by Vite's own dev-server proxy (`server.proxy` in `vite.config.ts`), so no ad-blocker whitelisting/disabling is needed anymore for local testing either. This relies on full control over the reverse-proxy's nginx config, which is the case here (self-hosted on the user's own Raspberry Pi's) — it would not work on a third-party/shared host without reverse-proxy access. **Important**: the org-/project-id hardcoded in both the nginx `location /sentry-tunnel` block and the Vite `server.proxy` target must match whatever `VITE_SENTRY_DSN`/`.env.local` DSN is actually configured; update all together if the Sentry project/DSN ever changes.
**Log level strategy**: only errors are logged (no verbose/info-level client logging) — this is a static site with no meaningful "business events" beyond page views, which are covered by analytics (see Dashboards below), not logging. **Log level strategy**: only errors are logged (no verbose/info-level client logging) — this is a static site with no meaningful "business events" beyond page views, which are covered by analytics (see Dashboards below), not logging.
+4 -5
View File
@@ -22,11 +22,10 @@ if (sentryDsn) {
enableLogs: true, enableLogs: true,
// Ad-blockers/privacy extensions commonly block requests straight to *.ingest.sentry.io // Ad-blockers/privacy extensions commonly block requests straight to *.ingest.sentry.io
// (ERR_BLOCKED_BY_CLIENT), because it looks like third-party tracking. Routing through our // (ERR_BLOCKED_BY_CLIENT), because it looks like third-party tracking. Routing through our
// own domain via a reverse-proxy "tunnel" avoids that (see nginx/reverse-proxy-nginx.conf.example). // own domain via a "tunnel" avoids that: in built (test/production) environments this is
// Only enabled for built (test/production) environments — local dev (`pnpm dev`) has no such // handled by the reverse-proxy Pi (see nginx/reverse-proxy-nginx.conf.example); locally
// proxy route available, so it keeps posting straight to Sentry (resolved by disabling the // (`pnpm dev`) the equivalent proxy route is set up in vite.config.ts's `server.proxy`.
// ad-blocker locally instead). tunnel: '/sentry-tunnel',
tunnel: import.meta.env.DEV ? undefined : '/sentry-tunnel',
}); });
} }
+14
View File
@@ -10,6 +10,20 @@ export default defineConfig({
// Injected at build time, used as the Sentry `release` tag (see src/main.tsx). // Injected at build time, used as the Sentry `release` tag (see src/main.tsx).
__APP_VERSION__: JSON.stringify(version), __APP_VERSION__: JSON.stringify(version),
}, },
server: {
proxy: {
// Mirrors the reverse-proxy Pi's "/sentry-tunnel" location (see
// nginx/reverse-proxy-nginx.conf.example) so the same tunnel path also
// works locally during `pnpm dev`, avoiding ad-blocker ERR_BLOCKED_BY_CLIENT
// errors when testing locally too (see src/main.tsx's Sentry.init tunnel option).
// LET OP: moet in sync blijven met de VITE_SENTRY_DSN uit .env.local.
'/sentry-tunnel': {
target: 'https://o4511795618185216.ingest.de.sentry.io',
changeOrigin: true,
rewrite: () => '/api/4511795622838352/envelope/',
},
},
},
test: { test: {
environment: 'jsdom', environment: 'jsdom',
globals: true, globals: true,