diff --git a/content/assets/images/guide/ns-sentry-android.png b/content/assets/images/guide/ns-sentry-android.png
new file mode 100644
index 00000000..58257664
Binary files /dev/null and b/content/assets/images/guide/ns-sentry-android.png differ
diff --git a/content/assets/images/guide/ns-sentry-ios-native.png b/content/assets/images/guide/ns-sentry-ios-native.png
new file mode 100644
index 00000000..ac376508
Binary files /dev/null and b/content/assets/images/guide/ns-sentry-ios-native.png differ
diff --git a/content/assets/images/guide/ns-sentry-ios.png b/content/assets/images/guide/ns-sentry-ios.png
new file mode 100644
index 00000000..7cd0db95
Binary files /dev/null and b/content/assets/images/guide/ns-sentry-ios.png differ
diff --git a/content/guide/crash-reporting-sentry.md b/content/guide/crash-reporting-sentry.md
new file mode 100644
index 00000000..3d52265a
--- /dev/null
+++ b/content/guide/crash-reporting-sentry.md
@@ -0,0 +1,284 @@
+---
+title: Crash Reporting with Sentry
+description: When your app breaks, fix it faster with Sentry.
+contributors:
+ - NathanWalker
+---
+
+
+
+Gain critical insights into app issues by integrating [Sentry](https://sentry.io), an advanced error tracking and performance monitoring service. Follow this guide to set up Sentry in your NativeScript application using the [@nativescript-community/sentry](https://github.com/nativescript-community/sentry) plugin.
+
+---
+
+## Step 1: Create a Sentry Account and Project
+
+First, [sign up](https://sentry.io) for a Sentry account and create a new project specifically for your NativeScript app.
+
+## Step 2: Install the Plugin
+
+Install the Sentry SDK into your NativeScript project:
+
+```bash
+npm install @nativescript-community/sentry
+```
+
+## Step 3: Set Up Environment Variables
+
+Create a `.env` file at the root of your project with these Sentry-related variables:
+
+- **`SENTRY_ORG_SLUG`**: Found under your project's Organization Settings.
+- **`SENTRY_PROJECT_SLUG_IOS` & `SENTRY_PROJECT_SLUG_ANDROID`**: Identifiers for your iOS and Android projects.
+- **`SENTRY_DSN_IOS` & `SENTRY_DSN_ANDROID`**: Obtain from `[Project] > Settings > Client Keys (DSN)`.
+- **`SENTRY_AUTH_TOKEN`**: Generate via your Sentry account under User Auth Tokens.
+
+Example `.env`:
+
+```bash
+SENTRY_ORG_SLUG=nativescript
+SENTRY_PROJECT_SLUG_IOS=myapp-ios
+SENTRY_PROJECT_SLUG_ANDROID=myapp-android
+SENTRY_DSN_IOS=your-ios-dsn
+SENTRY_DSN_ANDROID=your-android-dsn
+SENTRY_AUTH_TOKEN=your-auth-token
+```
+
+Replace the above placeholders with your actual Sentry details.
+
+## Step 4: Configure Webpack
+
+We will use Webpack to manage environment variables and source maps with plugins:
+
+```bash
+npm install plist @sentry/webpack-plugin dotenv -D
+```
+
+Update your `webpack.config.js` to configure Sentry integration:
+
+```js
+const webpack = require('@nativescript/webpack')
+const { resolve, join, relative } = require('path')
+const { readFileSync } = require('fs')
+const { parse } = require('plist')
+// load .env without having to specify cli env flags
+require('dotenv').config()
+
+const SentryCliPlugin = require('@sentry/webpack-plugin').sentryWebpackPlugin
+const SourceMapDevToolPlugin = require('webpack').SourceMapDevToolPlugin
+
+const SENTRY_PREFIX = process.env.SENTRY_PREFIX || 'app:///'
+const SENTRY_SOURCE_MAP_PATH = join(__dirname, 'dist', 'sourcemaps')
+
+module.exports = (env) => {
+ webpack.init(env)
+
+ webpack.chainWebpack((config) => {
+ const isStoreBuild = !!env.production
+ const sentryDev = !isStoreBuild && !!env['sentryDev']
+
+ const platform = webpack.Utils.platform.getPlatformName()
+ const projectSlug =
+ platform === 'android'
+ ? process.env.SENTRY_PROJECT_SLUG_ANDROID
+ : process.env.SENTRY_PROJECT_SLUG_IOS
+ const versionString =
+ platform === 'android'
+ ? readFileSync(
+ resolve(__dirname, 'App_Resources/Android/app.gradle'),
+ 'utf8',
+ ).match(/versionName\s+"([^"]+)"/)[1]
+ : parse(
+ readFileSync(
+ resolve(__dirname, 'App_Resources/iOS/Info.plist'),
+ 'utf8',
+ ),
+ )['CFBundleShortVersionString']
+
+ const SENTRY_DIST = sentryDev ? `dev-${Date.now()}` : `${Date.now()}`
+ const SENTRY_RELEASE = sentryDev ? SENTRY_DIST : versionString
+
+ config.plugin('DefinePlugin').tap((args) => {
+ Object.assign(args[0], {
+ __SENTRY_DIST__: `'${SENTRY_DIST}'`,
+ __SENTRY_RELEASE__: `'${SENTRY_RELEASE}'`,
+ __SENTRY_ENVIRONMENT__: `'${
+ isStoreBuild ? 'production' : 'development'
+ }'`,
+ __ENABLE_SENTRY__: isStoreBuild || sentryDev,
+ __SENTRY_PREFIX__: `'${SENTRY_PREFIX}'`,
+ __SENTRY_DSN_IOS__: JSON.stringify(process.env.SENTRY_DSN_IOS),
+ __SENTRY_DSN_ANDROID__: JSON.stringify(process.env.SENTRY_DSN_ANDROID),
+ })
+ return args
+ })
+
+ if (isStoreBuild || sentryDev) {
+ config.devtool(false)
+
+ config
+ .plugin('SourceMapDevToolPlugin|sentry')
+ .use(SourceMapDevToolPlugin, [
+ {
+ append: `\n//# sourceMappingURL=${SENTRY_PREFIX}[name].js.map`,
+ filename: relative(
+ webpack.Utils.platform.getAbsoluteDistPath(),
+ join(SENTRY_SOURCE_MAP_PATH, '[name].js.map'),
+ ),
+ },
+ ])
+
+ config
+ .plugin('SentryCliPlugin')
+ .init(() =>
+ SentryCliPlugin({
+ org: process.env.SENTRY_ORG_SLUG,
+ project: projectSlug,
+ // force ignore non-legacy sourcemaps
+ sourcemaps: {
+ assets: '/dev/null',
+ },
+ release: {
+ uploadLegacySourcemaps: {
+ paths: [
+ join(__dirname, 'dist', 'sourcemaps'),
+ webpack.Utils.platform.getAbsoluteDistPath(),
+ ],
+ urlPrefix: SENTRY_PREFIX,
+ },
+ dist: SENTRY_DIST,
+ cleanArtifacts: true,
+ deploy: {
+ env: sentryDev ? 'development' : 'production',
+ },
+ setCommits: {
+ auto: true,
+ ignoreMissing: true,
+ },
+ ...(SENTRY_RELEASE ? { name: SENTRY_RELEASE } : {}),
+ },
+ authToken: process.env.SENTRY_AUTH_TOKEN,
+ }),
+ )
+ .use(SentryCliPlugin)
+
+ config.optimization.minimizer('TerserPlugin').tap((args) => {
+ // we format here otherwise the sourcemaps will be broken
+ args[0].terserOptions.format = {
+ ...args[0].terserOptions.format,
+ max_line_len: 1000,
+ indent_level: 1,
+ }
+ return args
+ })
+ }
+ })
+
+ return webpack.resolveConfig()
+}
+```
+
+## Step 5: Initialize Sentry in Your App
+
+Create `sentry.ts` to initialize Sentry:
+
+```ts
+import { Application, Trace, TraceErrorHandler } from '@nativescript/core'
+import * as Sentry from '@nativescript-community/sentry'
+
+declare const __SENTRY_DIST__: string
+declare const __SENTRY_RELEASE__: string
+declare const __SENTRY_ENVIRONMENT__: string
+declare const __ENABLE_SENTRY__: boolean
+declare const __SENTRY_PREFIX__: string
+declare const __SENTRY_DSN_IOS__: string
+declare const __SENTRY_DSN_ANDROID__: string
+
+let initialized = false
+export function initSentry() {
+ if (initialized || !__ENABLE_SENTRY__) return
+ initialized = true
+
+ Sentry.init({
+ dsn: __APPLE__ ? __SENTRY_DSN_IOS__ : __SENTRY_DSN_ANDROID__,
+ debug: __DEV__,
+ enableAppHangTracking: false,
+ enableNativeCrashHandling: true,
+ enableAutoPerformanceTracking: true,
+ enableAutoSessionTracking: true,
+ attachScreenshot: false,
+ dist: __SENTRY_DIST__,
+ release: __SENTRY_RELEASE__,
+ environment: __SENTRY_ENVIRONMENT__,
+ appPrefix: __SENTRY_PREFIX__,
+ appHangsTimeoutInterval: 5,
+ })
+
+ Application.on('uncaughtError', (event) =>
+ Sentry.captureException(event.error),
+ )
+ Application.on('discardedError', (event) =>
+ Sentry.captureException(event.error),
+ )
+ Trace.setErrorHandler(errorHandler)
+}
+
+const errorHandler: TraceErrorHandler = {
+ handlerError(error: Error) {
+ if (__DEV__) {
+ // (development) - log it
+ console.error(error)
+ // (development) - or use Trace writing (categorical logging)
+ Trace.write(error, Trace.categories.Error)
+ // (development) - throw it
+ throw error
+ }
+
+ // (production) - send it to sentry
+ Sentry.captureException(error)
+ },
+}
+```
+
+In your main bootstrap file (`app.ts` or `main.ts`), initialize on launch:
+
+```ts
+import { initSentry } from './sentry'
+
+Application.on('launch', () => {
+ initSentry()
+})
+```
+
+## Step 6: Test Your Setup
+
+Trigger a test crash to verify setup:
+
+```ts
+throw new Error('Sentry test crash')
+```
+
+For native crashes:
+
+- iOS:
+
+```ts
+NSString.stringWithString(null)
+```
+
+- Android:
+
+```ts
+new java.lang.String(null)
+```
+
+Your crashes should appear in your Sentry dashboard shortly after triggering.
+
+
+
+
+
+
+
+---
+
+You're now successfully integrated with Sentry, gaining powerful insights into your app's performance and stability.
diff --git a/content/sidebar.ts b/content/sidebar.ts
index a4079e7f..599d93f5 100644
--- a/content/sidebar.ts
+++ b/content/sidebar.ts
@@ -209,6 +209,15 @@ export default [
}
],
},
+ {
+ text: 'Crash Reporting',
+ items: [
+ {
+ text: 'Using Sentry',
+ link: '/guide/crash-reporting-sentry',
+ },
+ ]
+ },
{
text: 'Developing with Vision Pro',
items: [