diff --git a/frontend/.gitignore b/frontend/.gitignore index a2da9df46..37839feb2 100644 --- a/frontend/.gitignore +++ b/frontend/.gitignore @@ -42,3 +42,5 @@ test-results/ # histoire .histoire package-lock.json +# Sentry Config File +.env.sentry-build-plugin diff --git a/frontend/package.json b/frontend/package.json index 0e6bd76ab..770846d61 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -111,6 +111,7 @@ "@histoire/plugin-screenshot": "1.0.0-beta.1", "@histoire/plugin-vue": "1.0.0-beta.1", "@playwright/test": "1.58.2", + "@sentry/vite-plugin": "3.5.0", "@tsconfig/node24": "24.0.4", "@types/codemirror": "5.60.17", "@types/is-touch-device": "1.0.3", @@ -148,7 +149,6 @@ "unplugin-inject-preload": "3.0.0", "vite": "7.3.1", "vite-plugin-pwa": "1.2.0", - "vite-plugin-sentry": "1.4.1", "vite-plugin-vue-devtools": "8.0.7", "vite-svg-loader": "5.1.0", "vitest": "4.0.18", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index f158e0ccf..cda7ced29 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -197,6 +197,9 @@ importers: '@playwright/test': specifier: 1.58.2 version: 1.58.2 + '@sentry/vite-plugin': + specifier: 3.5.0 + version: 3.5.0 '@tsconfig/node24': specifier: 24.0.4 version: 24.0.4 @@ -308,9 +311,6 @@ importers: vite-plugin-pwa: specifier: 1.2.0 version: 1.2.0(vite@7.3.1(@types/node@24.11.0)(jiti@2.4.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.31.6)(yaml@2.5.0))(workbox-build@7.4.0)(workbox-window@7.4.0) - vite-plugin-sentry: - specifier: 1.4.1 - version: 1.4.1(vite@7.3.1(@types/node@24.11.0)(jiti@2.4.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.31.6)(yaml@2.5.0)) vite-plugin-vue-devtools: specifier: 8.0.7 version: 8.0.7(vite@7.3.1(@types/node@24.11.0)(jiti@2.4.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.31.6)(yaml@2.5.0))(vue@3.5.27(typescript@5.9.3)) @@ -2211,53 +2211,61 @@ packages: resolution: {integrity: sha512-nLMkJgvHq+uCCrQKV2KgSdVHxTsmDk0r2hsAoTcKCbzUpXyW5UhCziMRS6ULjBlzt5sbxoIIplE25ZpmIEeNgg==} engines: {node: '>=18'} + '@sentry/babel-plugin-component-annotate@3.5.0': + resolution: {integrity: sha512-s2go8w03CDHbF9luFGtBHKJp4cSpsQzNVqgIa9Pfa4wnjipvrK6CxVT4icpLA3YO6kg5u622Yoa5GF3cJdippw==} + engines: {node: '>= 14'} + '@sentry/browser@10.36.0': resolution: {integrity: sha512-yHhXbgdGY1s+m8CdILC9U/II7gb6+s99S2Eh8VneEn/JG9wHc+UOzrQCeFN0phFP51QbLkjkiQbbanjT1HP8UQ==} engines: {node: '>=18'} - '@sentry/cli-darwin@2.33.1': - resolution: {integrity: sha512-+4/VIx/E1L2hChj5nGf5MHyEPHUNHJ/HoG5RY+B+vyEutGily1c1+DM2bum7RbD0xs6wKLIyup5F02guzSzG8A==} + '@sentry/bundler-plugin-core@3.5.0': + resolution: {integrity: sha512-zDzPrhJqAAy2VzV4g540qAZH4qxzisstK2+NIJPZUUKztWRWUV2cMHsyUtdctYgloGkLyGpZJBE3RE6dmP/xqQ==} + engines: {node: '>= 14'} + + '@sentry/cli-darwin@2.42.2': + resolution: {integrity: sha512-GtJSuxER7Vrp1IpxdUyRZzcckzMnb4N5KTW7sbTwUiwqARRo+wxS+gczYrS8tdgtmXs5XYhzhs+t4d52ITHMIg==} engines: {node: '>=10'} os: [darwin] - '@sentry/cli-linux-arm64@2.33.1': - resolution: {integrity: sha512-DbGV56PRKOLsAZJX27Jt2uZ11QfQEMmWB4cIvxkKcFVE+LJP4MVA+MGGRUL6p+Bs1R9ZUuGbpKGtj0JiG6CoXw==} + '@sentry/cli-linux-arm64@2.42.2': + resolution: {integrity: sha512-BOxzI7sgEU5Dhq3o4SblFXdE9zScpz6EXc5Zwr1UDZvzgXZGosUtKVc7d1LmkrHP8Q2o18HcDWtF3WvJRb5Zpw==} engines: {node: '>=10'} cpu: [arm64] os: [linux, freebsd] - '@sentry/cli-linux-arm@2.33.1': - resolution: {integrity: sha512-zbxEvQju+tgNvzTOt635le4kS/Fbm2XC2RtYbCTs034Vb8xjrAxLnK0z1bQnStUV8BkeBHtsNVrG+NSQDym2wg==} + '@sentry/cli-linux-arm@2.42.2': + resolution: {integrity: sha512-7udCw+YL9lwq+9eL3WLspvnuG+k5Icg92YE7zsteTzWLwgPVzaxeZD2f8hwhsu+wmL+jNqbpCRmktPteh3i2mg==} engines: {node: '>=10'} cpu: [arm] os: [linux, freebsd] - '@sentry/cli-linux-i686@2.33.1': - resolution: {integrity: sha512-g2LS4oPXkPWOfKWukKzYp4FnXVRRSwBxhuQ9eSw2peeb58ZIObr4YKGOA/8HJRGkooBJIKGaAR2mH2Pk1TKaiA==} + '@sentry/cli-linux-i686@2.42.2': + resolution: {integrity: sha512-Sw/dQp5ZPvKnq3/y7wIJyxTUJYPGoTX/YeMbDs8BzDlu9to2LWV3K3r7hE7W1Lpbaw4tSquUHiQjP5QHCOS7aQ==} engines: {node: '>=10'} cpu: [x86, ia32] os: [linux, freebsd] - '@sentry/cli-linux-x64@2.33.1': - resolution: {integrity: sha512-IV3dcYV/ZcvO+VGu9U6kuxSdbsV2kzxaBwWUQxtzxJ+cOa7J8Hn1t0koKGtU53JVZNBa06qJWIcqgl4/pCuKIg==} + '@sentry/cli-linux-x64@2.42.2': + resolution: {integrity: sha512-mU4zUspAal6TIwlNLBV5oq6yYqiENnCWSxtSQVzWs0Jyq97wtqGNG9U+QrnwjJZ+ta/hvye9fvL2X25D/RxHQw==} engines: {node: '>=10'} cpu: [x64] os: [linux, freebsd] - '@sentry/cli-win32-i686@2.33.1': - resolution: {integrity: sha512-F7cJySvkpzIu7fnLKNHYwBzZYYwlhoDbAUnaFX0UZCN+5DNp/5LwTp37a5TWOsmCaHMZT4i9IO4SIsnNw16/zQ==} + '@sentry/cli-win32-i686@2.42.2': + resolution: {integrity: sha512-iHvFHPGqgJMNqXJoQpqttfsv2GI3cGodeTq4aoVLU/BT3+hXzbV0x1VpvvEhncJkDgDicJpFLM8sEPHb3b8abw==} engines: {node: '>=10'} cpu: [x86, ia32] os: [win32] - '@sentry/cli-win32-x64@2.33.1': - resolution: {integrity: sha512-8VyRoJqtb2uQ8/bFRKNuACYZt7r+Xx0k2wXRGTyH05lCjAiVIXn7DiS2BxHFty7M1QEWUCMNsb/UC/x/Cu2wuA==} + '@sentry/cli-win32-x64@2.42.2': + resolution: {integrity: sha512-vPPGHjYoaGmfrU7xhfFxG7qlTBacroz5NdT+0FmDn6692D8IvpNXl1K+eV3Kag44ipJBBeR8g1HRJyx/F/9ACw==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@sentry/cli@2.33.1': - resolution: {integrity: sha512-dUlZ4EFh98VFRPJ+f6OW3JEYQ7VvqGNMa0AMcmvk07ePNeK/GicAWmSQE4ZfJTTl80ul6HZw1kY01fGQOQlVRA==} + '@sentry/cli@2.42.2': + resolution: {integrity: sha512-spb7S/RUumCGyiSTg8DlrCX4bivCNmU/A1hcfkwuciTFGu8l5CDc2I6jJWWZw8/0enDGxuj5XujgXvU5tr4bxg==} engines: {node: '>= 10'} hasBin: true @@ -2265,6 +2273,10 @@ packages: resolution: {integrity: sha512-EYJjZvofI+D93eUsPLDIUV0zQocYqiBRyXS6CCV6dHz64P/Hob5NJQOwPa8/v6nD+UvJXvwsFfvXOHhYZhZJOQ==} engines: {node: '>=18'} + '@sentry/vite-plugin@3.5.0': + resolution: {integrity: sha512-jUnpTdpicG8wefamw7eNo2uO+Q3KCbOAiF76xH4gfNHSW6TN2hBfOtmLu7J+ive4c0Al3+NEHz19bIPR0lkwWg==} + engines: {node: '>= 14'} + '@sentry/vue@10.36.0': resolution: {integrity: sha512-pGED21QngK1ulqGsNn1NyBKgay8Cf7qZBnaxQXvnm9RaIlTGYdqg7TeooQru45We/8f0DzM6n59YykAsUu21kw==} engines: {node: '>=18'} @@ -3561,6 +3573,10 @@ packages: resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} engines: {node: '>=18'} + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} @@ -3929,6 +3945,9 @@ packages: resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} engines: {node: '>=10'} + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + fsevents@2.3.2: resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -4007,6 +4026,11 @@ packages: deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true + glob@9.3.5: + resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} + engines: {node: '>=16 || 14 >=14.17'} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + global-directory@4.0.1: resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} engines: {node: '>=18'} @@ -4582,6 +4606,10 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + magic-string@0.30.8: + resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} + engines: {node: '>=12'} + map-obj@1.0.1: resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} engines: {node: '>=0.10.0'} @@ -4697,6 +4725,10 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@4.2.8: + resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} + engines: {node: '>=8'} + minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} @@ -6260,6 +6292,9 @@ packages: resolution: {integrity: sha512-JLoggz+PvLVMJo+jZt97hdIIIZ2yTzGgft9e9q8iMrC4ewufl62ekeW7mixBghonn2gVb/ICjyvlmOCUBnJLQg==} engines: {node: '>=20.19.0'} + unplugin@1.0.1: + resolution: {integrity: sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==} + unplugin@1.12.2: resolution: {integrity: sha512-bEqQxeC7rxtxPZ3M5V4Djcc4lQqKPgGe3mAWZvxcSmX5jhGxll19NliaRzQSQPrk4xJZSGniK3puLWpRuZN7VQ==} engines: {node: '>=14.0.0'} @@ -6341,12 +6376,6 @@ packages: '@vite-pwa/assets-generator': optional: true - vite-plugin-sentry@1.4.1: - resolution: {integrity: sha512-Q9lu7to7SPoT1OgWo1IN9biLsKXjPMlPMr+Si5FPFPUnQnG6a3mnLZA7RxCeAFtVS/eEsj7k0wDk6Tn+4SLm3g==} - engines: {node: '>= 14'} - peerDependencies: - vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 - vite-plugin-vue-devtools@8.0.7: resolution: {integrity: sha512-BWj/ykGpqVAJVdPyHmSTUm44buz3jPv+6jnvuFdQSRH0kAgP1cEIE4doHiFyqHXOmuB5EQVR/nh2g9YRiRNs9g==} engines: {node: '>=v14.21.3'} @@ -6540,6 +6569,9 @@ packages: resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} + webpack-virtual-modules@0.5.0: + resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==} + webpack-virtual-modules@0.6.2: resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} @@ -8655,6 +8687,8 @@ snapshots: '@sentry-internal/browser-utils': 10.36.0 '@sentry/core': 10.36.0 + '@sentry/babel-plugin-component-annotate@3.5.0': {} + '@sentry/browser@10.36.0': dependencies: '@sentry-internal/browser-utils': 10.36.0 @@ -8663,28 +8697,42 @@ snapshots: '@sentry-internal/replay-canvas': 10.36.0 '@sentry/core': 10.36.0 - '@sentry/cli-darwin@2.33.1': + '@sentry/bundler-plugin-core@3.5.0': + dependencies: + '@babel/core': 7.26.0 + '@sentry/babel-plugin-component-annotate': 3.5.0 + '@sentry/cli': 2.42.2 + dotenv: 16.6.1 + find-up: 5.0.0 + glob: 9.3.5 + magic-string: 0.30.8 + unplugin: 1.0.1 + transitivePeerDependencies: + - encoding + - supports-color + + '@sentry/cli-darwin@2.42.2': optional: true - '@sentry/cli-linux-arm64@2.33.1': + '@sentry/cli-linux-arm64@2.42.2': optional: true - '@sentry/cli-linux-arm@2.33.1': + '@sentry/cli-linux-arm@2.42.2': optional: true - '@sentry/cli-linux-i686@2.33.1': + '@sentry/cli-linux-i686@2.42.2': optional: true - '@sentry/cli-linux-x64@2.33.1': + '@sentry/cli-linux-x64@2.42.2': optional: true - '@sentry/cli-win32-i686@2.33.1': + '@sentry/cli-win32-i686@2.42.2': optional: true - '@sentry/cli-win32-x64@2.33.1': + '@sentry/cli-win32-x64@2.42.2': optional: true - '@sentry/cli@2.33.1': + '@sentry/cli@2.42.2': dependencies: https-proxy-agent: 5.0.1 node-fetch: 2.7.0 @@ -8692,19 +8740,27 @@ snapshots: proxy-from-env: 1.1.0 which: 2.0.2 optionalDependencies: - '@sentry/cli-darwin': 2.33.1 - '@sentry/cli-linux-arm': 2.33.1 - '@sentry/cli-linux-arm64': 2.33.1 - '@sentry/cli-linux-i686': 2.33.1 - '@sentry/cli-linux-x64': 2.33.1 - '@sentry/cli-win32-i686': 2.33.1 - '@sentry/cli-win32-x64': 2.33.1 + '@sentry/cli-darwin': 2.42.2 + '@sentry/cli-linux-arm': 2.42.2 + '@sentry/cli-linux-arm64': 2.42.2 + '@sentry/cli-linux-i686': 2.42.2 + '@sentry/cli-linux-x64': 2.42.2 + '@sentry/cli-win32-i686': 2.42.2 + '@sentry/cli-win32-x64': 2.42.2 transitivePeerDependencies: - encoding - supports-color '@sentry/core@10.36.0': {} + '@sentry/vite-plugin@3.5.0': + dependencies: + '@sentry/bundler-plugin-core': 3.5.0 + unplugin: 1.0.1 + transitivePeerDependencies: + - encoding + - supports-color + '@sentry/vue@10.36.0(pinia@3.0.4(typescript@5.9.3)(vue@3.5.27(typescript@5.9.3)))(vue@3.5.27(typescript@5.9.3))': dependencies: '@sentry/browser': 10.36.0 @@ -10148,6 +10204,8 @@ snapshots: dependencies: type-fest: 4.41.0 + dotenv@16.6.1: {} + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 @@ -10620,6 +10678,8 @@ snapshots: jsonfile: 6.1.0 universalify: 2.0.1 + fs.realpath@1.0.0: {} + fsevents@2.3.2: optional: true @@ -10709,6 +10769,13 @@ snapshots: package-json-from-dist: 1.0.0 path-scurry: 2.0.1 + glob@9.3.5: + dependencies: + fs.realpath: 1.0.0 + minimatch: 10.2.4 + minipass: 4.2.8 + path-scurry: 1.11.1 + global-directory@4.0.1: dependencies: ini: 4.1.1 @@ -11314,6 +11381,10 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + magic-string@0.30.8: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + map-obj@1.0.1: {} map-obj@4.3.0: {} @@ -11428,6 +11499,8 @@ snapshots: minimist@1.2.8: {} + minipass@4.2.8: {} + minipass@7.1.2: {} mitt@3.0.1: {} @@ -13183,6 +13256,13 @@ snapshots: pathe: 2.0.3 picomatch: 4.0.3 + unplugin@1.0.1: + dependencies: + acorn: 8.15.0 + chokidar: 3.6.0 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.5.0 + unplugin@1.12.2: dependencies: acorn: 8.14.0 @@ -13300,14 +13380,6 @@ snapshots: transitivePeerDependencies: - supports-color - vite-plugin-sentry@1.4.1(vite@7.3.1(@types/node@24.11.0)(jiti@2.4.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.31.6)(yaml@2.5.0)): - dependencies: - '@sentry/cli': 2.33.1 - vite: 7.3.1(@types/node@24.11.0)(jiti@2.4.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.31.6)(yaml@2.5.0) - transitivePeerDependencies: - - encoding - - supports-color - vite-plugin-vue-devtools@8.0.7(vite@7.3.1(@types/node@24.11.0)(jiti@2.4.2)(sass-embedded@1.97.3)(sass@1.97.3)(terser@5.31.6)(yaml@2.5.0))(vue@3.5.27(typescript@5.9.3)): dependencies: '@vue/devtools-core': 8.0.7(vue@3.5.27(typescript@5.9.3)) @@ -13496,6 +13568,8 @@ snapshots: webpack-sources@3.2.3: {} + webpack-virtual-modules@0.5.0: {} + webpack-virtual-modules@0.6.2: {} whatwg-mimetype@3.0.0: {} diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 0bf67c7e4..1a81de2a2 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -55,6 +55,14 @@ const browserLanguage = getBrowserLanguage() setLanguage(browserLanguage).then(() => { const app = createApp(App) + if (window.SENTRY_ENABLED) { + try { + import('./sentry').then(sentry => sentry.default(app, router)) + } catch (e) { + console.error('Could not enable Sentry tracking', e) + } + } + app.use(Notifications) app.directive('focus', focus) @@ -100,14 +108,6 @@ setLanguage(browserLanguage).then(() => { success, } - if (window.SENTRY_ENABLED) { - try { - import('./sentry').then(sentry => sentry.default(app, router)) - } catch (e) { - console.error('Could not enable Sentry tracking', e) - } - } - app.use(pinia) app.use(router) app.use(i18n) diff --git a/frontend/src/sentry.ts b/frontend/src/sentry.ts index d2bd4b931..c49140ebe 100644 --- a/frontend/src/sentry.ts +++ b/frontend/src/sentry.ts @@ -1,7 +1,7 @@ -import 'virtual:vite-plugin-sentry/sentry-config' import type {App} from 'vue' import type {Router} from 'vue-router' import {AxiosError} from 'axios' +import {VERSION} from './version.json' export default async function setupSentry(app: App, router: Router) { const Sentry = await import('@sentry/vue') @@ -9,14 +9,35 @@ export default async function setupSentry(app: App, router: Router) { Sentry.init({ app, dsn: window.SENTRY_DSN ?? '', - release: import.meta.env.VITE_PLUGIN_SENTRY_CONFIG.release, - dist: import.meta.env.VITE_PLUGIN_SENTRY_CONFIG.dist, + + // cache offline errors + transport: Sentry.makeBrowserOfflineTransport(Sentry.makeFetchTransport), integrations: [ - Sentry.browserTracingIntegration({ - router, - }), + Sentry.browserTracingIntegration({ router }), + Sentry.replayIntegration(), ], + + // vue + trackComponents: true, + + // Set tracesSampleRate to 1.0 to capture 100% + // of transactions for tracing. + // We recommend adjusting this value in production tracesSampleRate: 1.0, + + // Set `tracePropagationTargets` to control for which URLs trace propagation should be enabled + tracePropagationTargets: [ + 'localhost', + /^\//, + // /^https:\/\/yourserver\.io\/api/, + ], + + // Capture Replay for 10% of all sessions, + // plus for 100% of sessions with an error + replaysSessionSampleRate: 0.1, + replaysOnErrorSampleRate: 1.0, + + beforeSend(event, hint) { if ((typeof hint.originalException?.code !== 'undefined' && @@ -28,4 +49,26 @@ export default async function setupSentry(app: App, router: Router) { return event }, }) + + // from https://docs.sentry.io/platforms/javascript/guides/vue/troubleshooting/ + // under "Capturing resource 404s" + document.body.addEventListener( + 'error', + (event) => { + if (!event.target) return + + if (event.target.tagName === 'IMG') { + Sentry.captureMessage( + `Failed to load image: ${event.target.src}`, + 'warning', + ) + } else if (event.target.tagName === 'LINK') { + Sentry.captureMessage( + `Failed to load css: ${event.target.href}`, + 'warning', + ) + } + }, + true, // useCapture - necessary for resource loading errors + ) } diff --git a/frontend/tsconfig.app.json b/frontend/tsconfig.app.json index 51d331e78..fface8507 100644 --- a/frontend/tsconfig.app.json +++ b/frontend/tsconfig.app.json @@ -23,9 +23,6 @@ "paths": { "@/*": ["./src/*"] }, - "types": [ - // https://github.com/ikenfin/vite-plugin-sentry#typescript - "vite-plugin-sentry/client" - ], + "types": [], } } diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 24e64b141..c34e8f15c 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -10,7 +10,7 @@ import {VitePWA} from 'vite-plugin-pwa' import UnpluginInjectPreload from 'unplugin-inject-preload/vite' import {visualizer} from 'rollup-plugin-visualizer' -import viteSentry, {type ViteSentryPluginOptions} from 'vite-plugin-sentry' +import { sentryVitePlugin, type SentryVitePluginOptions } from '@sentry/vite-plugin' import svgLoader from 'vite-svg-loader' import postcssPresetEnv from 'postcss-preset-env' import postcssEasingGradients from 'postcss-easing-gradients' @@ -26,29 +26,47 @@ const PREFIXED_SCSS_STYLES = `@use "sass:math"; /* ** Configure sentry plugin */ -// @ts-ignore -function getSentryConfig(env: ImportMetaEnv): ViteSentryPluginOptions { +function getSentryConfig(env: ImportMetaEnv): SentryVitePluginOptions { return { - skipEnvironmentCheck: true, + // keep these flags for easier debugging + disable: true, + debug: true, // print information about which files end up being uploaded + silent: false, - url: 'https://sentry.io', + // allow compilation to continue but still emit a warning + errorHandler: (err) => console.warn(err), + + // skipEnvironmentCheck: true, + + // url: 'https://sentry.io', // TODO add env authToken: env.SENTRY_AUTH_TOKEN, org: env.SENTRY_ORG, project: env.SENTRY_PROJECT, - cleanSourcemapsAfterUpload: true, - legacyErrorHandlingMode: true, - deploy: { - env: env.MODE, - }, - setCommits: { - auto: true, - ignoreMissing: true, - }, - sourceMaps: { - include: ['./dist/assets'], - ignore: ['node_modules'], - urlPrefix: '~/assets', + + telemetry: false, + + // sourcemaps: { + // assets: [], // TODO + // deleteFilesAfterUpload: [], // TODO define glob + // rewriteSources // might need that instead of `urlPrefix` + // }, + + release: { + // name: VERSION, // TODO release version + setCommits: { + auto: true, + ignoreMissing: true, + }, + deploy: { + env: env.MODE, + }, }, + + // sourceMaps: { + // include: ['./dist/assets'], + // ignore: ['node_modules'], + // urlPrefix: '~/assets', + // }, } } @@ -200,7 +218,8 @@ function getBuildConfig(env: Record) { vueDevTools({ launchEditor: env.VUE_DEVTOOLS_LAUNCH_EDITOR || 'code', }), - viteSentry(getSentryConfig(env)), + // Put the Sentry vite plugin after all other plugins + sentryVitePlugin(getSentryConfig(env)), ], resolve: { alias: [ @@ -219,7 +238,7 @@ function getBuildConfig(env: Record) { output: { manualChunks: { // by putting tracking related stuff in a separated file we try to prevent unwanted blocking from ad-blockers - sentry: ['./src/sentry.ts', '@sentry/vue', '@sentry/tracing'], + sentry: ['./src/sentry.ts', '@sentry/*'], }, }, build: {