İçeriğe atla

2026-02-16

React Native Expo ile Sentry Entegrasyonu: Pratik Hızlı Rehber

React Native Expo uygulamasına Sentry hata izleme entegrasyonu için adım adım rehber. SDK başlatma, Expo Router enstrümantasyonu, session replay, EAS Build ve EAS Update için source map yükleme ve sık karşılaşılan sorunları kapsar.

Bu rehber, Sentry’yi bir React Native Expo uygulamasına entegre etme sürecini kurulumdan production-grade source map yüklemesine kadar adım adım anlatıyor. Kritik yapılandırma detaylarını, Expo Go kısıtlamalarını, session replay kurulumunu ve hazırlıksız yakalandığında saatler kaybettirebilecek yaygın tuzakları kapsıyor. EAS Build ve EAS Update entegrasyonları production’da debug süresini önemli ölçüde kısaltır.

Ön Koşullar

Başlamadan önce şunlara ihtiyacın var:

  • SDK 50 veya üzeri kullanan bir Expo projesi (SDK 52+ önerilir)
  • Bir Sentry hesabı (ücretsiz plan aylık 5.000 hata sağlar)
  • Sentry panelinde oluşturulmuş bir React Native projesi
  • Sentry’den üç tanımlayıcı: Organization slug, Project name ve DSN
  • Sentry ayarlarından üretilmiş bir Organization Auth Token

Adım 1: Kurulum

Sentry wizard kurulumun büyük kısmını otomatize eder. Proje kök dizininden çalıştır:

npx @sentry/wizard@latest -i reactNative

Wizard Metro config, Expo plugin config ve temel SDK başlatmasını halleder. Manuel kurulum tercih ediyorsan veya wizard ortamında çalışmıyorsa, paketi doğrudan kur:

npx expo install @sentry/react-native

Manuel kurulum üç dosyayı kendin yapılandırmayı gerektirir, sonraki adımlarda bunları detaylı olarak ele alıyoruz.

Adım 2: Metro Yapılandırması

Sentry’nin source map üretimi için Metro bundler’a bağlanması gerekiyor. metro.config.js dosyanı şu şekilde güncelle:

// metro.config.js
const { getSentryExpoConfig } = require("@sentry/react-native/metro");

const config = getSentryExpoConfig(__dirname);

module.exports = config;

Zaten özel bir Metro config’in varsa, tamamen değiştirmek yerine mevcut config’ini getSentryExpoConfig ile sar.

Adım 3: Expo Plugin Yapılandırması

Sentry plugin’ini app.json (veya app.config.js) dosyana ekle:

{
  "expo": {
    "plugins": [
      [
        "@sentry/react-native/expo",
        {
          "url": "https://sentry.io/",
          "project": "my-expo-app",
          "organization": "my-org"
        }
      ]
    ]
  }
}

Warning: authToken değerini asla app.json veya app.config.js içine koyma. Bu yapılandırma dosyası uygulama paketine gömülür ve çalışma zamanında erişilebilir olur. Auth token’ı environment variable veya EAS secret olarak ayarla. Bu, Expo SDK 50 migration dokümantasyonunda belgelenmiş bir güvenlik sorunuydu.

Adım 4: Expo Router ile SDK Başlatma

Ana başlatma root layout dosyasında yapılır. Bu örnek, Expo Router navigasyon takibi ile performans izleme, ortam yapılandırması ve session replay içerir:

// app/_layout.tsx
import { Stack, useNavigationContainerRef } from "expo-router";
import * as Sentry from "@sentry/react-native";
import { isRunningInExpoGo } from "expo";
import React from "react";

const navigationIntegration = Sentry.reactNavigationIntegration({
  enableTimeToInitialDisplay: !isRunningInExpoGo(),
});

Sentry.init({
  dsn: "https://[email protected]/0",

  // Ortam yapılandırması
  environment: __DEV__ ? "development" : "production",

  // Performans izleme
  tracesSampleRate: __DEV__ ? 1.0 : 0.2,
  enableNativeFramesTracking: !isRunningInExpoGo(),

  // Session replay
  replaysOnErrorSampleRate: 1.0,
  replaysSessionSampleRate: __DEV__ ? 1.0 : 0.1,

  // Entegrasyonlar
  integrations: [
    navigationIntegration,
    Sentry.mobileReplayIntegration(),
  ],
});

function RootLayout() {
  const ref = useNavigationContainerRef();

  React.useEffect(() => {
    if (ref?.current) {
      navigationIntegration.registerNavigationContainer(ref);
    }
  }, [ref]);

  return <Stack />;
}

export default Sentry.wrap(RootLayout);

Bu yapılandırmada dikkat edilmesi gereken birkaç nokta:

  • Production’da tracesSampleRate: 0.2 işlemlerin %20’sini yakalar. Bunu production’da 1.0 olarak ayarlamak kotanı hızla tüketir ve uygulama performansını etkileyebilir.
  • replaysOnErrorSampleRate: 1.0 her hata için session replay yakalar — en değerli kullanım senaryosu budur. 0.1 oranındaki genel session replay’ler aşırı veri olmadan bir örneklem sağlar.
  • isRunningInExpoGo() korumaları, Expo Go’da sessizce başarısız olacak veya çökecek native-only özelliklerin etkinleştirilmesini engeller.

Adım 5: Expo Go ve Development Build Farkları

Bu, en yaygın kafa karışıklığı kaynaklarından biri. Expo Go, Sentry’nin native modüllerini içermez, bu da işlevselliği önemli ölçüde kısıtlar.

Development Build / EAS Build

JS Hata Yakalama - Çalışıyor

Mesaj Yakalama - Çalışıyor

Breadcrumbs - Çalışıyor

Kullanıcı Context - Çalışıyor

Native Crash - Çalışıyor

Frame Takibi - Çalışıyor

Session Replay - Çalışıyor

Native Profiling - Çalışıyor

Expo Go

JS Hata Yakalama - Çalışıyor

Mesaj Yakalama - Çalışıyor

Breadcrumbs - Çalışıyor

Kullanıcı Context - Çalışıyor

Native Crash - Kullanılamıyor

Frame Takibi - Kullanılamıyor

Session Replay - Kullanılamıyor

Native Profiling - Kullanılamıyor

isRunningInExpoGo() koruması, Expo Go’da çalışırken native-only özelliklerin etkinleştirilmesini engeller:

Sentry.init({
  // ...
  enableNativeFramesTracking: !isRunningInExpoGo(),
  profilesSampleRate: isRunningInExpoGo() ? 0 : 1.0,
});

Tam Sentry işlevselliği için, göndermeden önce mutlaka development build veya EAS Build ile doğrula.

Adım 6: Error Boundary’ler

Sentry, React render hatalarını yakalayan ve otomatik olarak raporlayan bir ErrorBoundary bileşeni sağlar:

import * as Sentry from "@sentry/react-native";
import { View, Text, TouchableOpacity } from "react-native";

function ErrorFallback({
  error,
  resetError,
}: {
  error: Error;
  resetError: () => void;
}) {
  return (
    <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
      <Text style={{ fontSize: 18, fontWeight: "bold" }}>
        Bir şeyler ters gitti
      </Text>
      <Text style={{ color: "#666", marginTop: 8 }}>
        {error.message}
      </Text>
      <TouchableOpacity
        onPress={resetError}
        style={{
          marginTop: 16,
          padding: 12,
          backgroundColor: "#362d59",
          borderRadius: 8,
        }}
      >
        <Text style={{ color: "#fff" }}>Tekrar Dene</Text>
      </TouchableOpacity>
    </View>
  );
}

export function ScreenWithErrorBoundary() {
  return (
    <Sentry.ErrorBoundary
      fallback={({ error, resetError }) => (
        <ErrorFallback error={error} resetError={resetError} />
      )}
      beforeCapture={(scope) => {
        scope.setTag("component", "MainScreen");
      }}
    >
      <MainScreenContent />
    </Sentry.ErrorBoundary>
  );
}

beforeCapture callback’i context tag’leri eklemeyi sağlar, bu da hataları Sentry panelinde filtrelemeyi ve gruplamayı kolaylaştırır.

Note: React geliştirme modunda, error boundary’ler tarafından yakalanan hataları global error handler’a yeniden fırlatır ve bu da tekrarlayan raporlara neden olabilir. Error boundary davranışını production build’lerde test et.

Adım 7: Source Map’ler — EAS Build ve EAS Update

Production’da okunabilir stack trace’ler almak için düzgün yüklenmiş source map’ler gerekir. Süreç EAS Build ve EAS Update arasında farklılık gösterir.

EAS Build

EAS Update

Kod Değişikliği

Dağıtım Yöntemi

Native Build

Otomatik Source Map Yükleme

Sentry Release Oluşturuldu

OTA Bundle

npx expo export

npx sentry-expo-upload-sourcemaps dist

Source Map Yüklendi

Panelde Sembolik Stack Trace

EAS Build (Otomatik)

Native build’ler için source map yükleme otomatiktir. Sadece auth token’ı EAS secret olarak ayarla:

eas env:create --name SENTRY_AUTH_TOKEN --value "sntrys_YOUR_TOKEN_HERE" --scope project --visibility secret --environment production

Bu kadar. Sentry Expo plugin’i build sürecinde geri kalan her şeyi halleder.

EAS Update (Manuel)

OTA güncellemeleri source map’leri otomatik olarak yüklemez. Her eas update sonrası manuel olarak yüklemen gerekir:

npx expo export --platform all
npx sentry-expo-upload-sourcemaps dist

Okunamayan stack trace’lerle güncelleme göndermekten kaçınmak için bunu CI/CD pipeline’ında otomatize et.

Adım 8: EAS Update Metadata Etiketleme

OTA güncellemeleri kullanırken, Sentry olaylarını güncelleme metadata’sı ile etiketlemek hataları güncelleme sürümüne göre filtrelemeyi mümkün kılar:

import * as Sentry from "@sentry/react-native";
import * as Updates from "expo-updates";

function tagSentryWithUpdateInfo() {
  const manifest = Updates.manifest;
  const metadata =
    manifest && "metadata" in manifest ? manifest.metadata : undefined;
  const updateGroup =
    metadata && typeof metadata === "object" && "updateGroup" in metadata
      ? (metadata as { updateGroup: string }).updateGroup
      : undefined;

  const scope = Sentry.getGlobalScope();

  scope.setTag("expo-update-id", Updates.updateId ?? "embedded");
  scope.setTag("expo-is-embedded-update", String(Updates.isEmbeddedLaunch));

  if (updateGroup) {
    scope.setTag("expo-update-group-id", updateGroup);
  }
}

// Sentry.init() sonrası, uygulama yaşam döngüsünde erken çağır
tagSentryWithUpdateInfo();

Bu özellikle bir OTA güncellemesi regresyon getirdiğinde kullanışlıdır — hata artışına hangi güncelleme grubunun neden olduğunu hemen tespit edebilirsin.

Adım 9: Entegrasyonu Doğrulama

Production’a geçmeden önce, basit bir test bileşeni ile hataların Sentry panelinde doğru görünüp görünmediğini kontrol et:

import * as Sentry from "@sentry/react-native";
import { Button, View } from "react-native";

export function SentryTestButtons() {
  return (
    <View style={{ gap: 12, padding: 16 }}>
      <Button
        title="JS Hatası Test Et"
        onPress={() => {
          Sentry.captureException(new Error("Test JS error from Expo"));
        }}
      />

      <Button
        title="Yakalanmamış Hata Test Et"
        onPress={() => {
          throw new Error("Unhandled test error");
        }}
      />

      <Button
        title="Native Crash Test Et"
        onPress={() => {
          Sentry.nativeCrash();
        }}
      />
    </View>
  );
}

Her hatayı tetikledikten sonra Sentry panelini kontrol et. Stack trace’lerin düzgün sembolik hale getirildiğinden emin ol — minified kod yerine orijinal kaynak dosya adlarını ve satır numaralarını görmelisin.

Tip: Native crash testi sadece development build’lerde çalışır, Expo Go’da çalışmaz. Butona basınca hiçbir şey olmuyorsa, muhtemelen Expo Go’da çalışıyorsundur.

Sorun Giderme

Source Map’ler Minified Kod Gösteriyor

Neden: Source map’ler yüklenmemiş veya release/dist değerleri uygulama ile yüklenen map’ler arasında eşleşmiyor.

Çözüm: Otomatik release adlandırma kullan (varsayılan). Sentry.init() içinde özel release veya dist değerleri ayarlarsan, otomatik yükleme betiği bunları tespit edemez. Ya varsayılanlarla kal ya da eşleşen release/dist değerleriyle source map’leri manuel olarak yükle.

Neden: registerNavigationContainer navigasyon ref ile hiç çağrılmamış.

Çözüm: useNavigationContainerRef() fonksiyonunun Sentry’nin başlatıldığı aynı bileşende çağrıldığından ve ref’in bir useEffect içinde kayıt edildiğinden emin ol.

Geliştirmede Tekrarlayan Hata Raporları

Neden: React’in geliştirme modu, error boundary’ler tarafından yakalanan hataları global handler’a yeniden fırlatır.

Çözüm: Error boundary davranışını production build’lerde test et. Gürültü rahatsız ediyorsa enabled: !__DEV__ ile Sentry’yi geliştirmede devre dışı bırakabilirsin.

sentry-expo Paketi Hataları

Neden: sentry-expo paketi Expo SDK 50 ile birlikte kullanımdan kaldırılmıştır ve artık bakımı yapılmamaktadır.

Çözüm: Doğrudan @sentry/react-native paketine geç. Sentry, dokümantasyonunda bir geçiş rehberi sağlıyor.

Yüksek Olay Hacmi Kotayı Tüketiyor

Neden: Production için örnekleme oranları çok yüksek ayarlanmış.

Çözüm: Düşük oranlar kullan: tracesSampleRate: 0.1-0.2, replaysSessionSampleRate: 0.1. Hata replay’leri en değerli olduğu için replaysOnErrorSampleRate: 1.0 tut.

Sürüm Uyumluluğu

BileşenMinimum SürümÖnerilen
@sentry/react-native7.x8.x (güncel)
Expo SDK5052+
React Native0.73+0.76+
iOS Deployment Target15.0 (v8 için)15.0+
Android Gradle Plugin7.4.0 (v8 için)8.x

Note: Sürüm 8, native SDK’ları (Cocoa v9, CLI v3, Android Gradle Plugin v6) minimum sürüm gereksinimleri ve build araçlarında köklü değişikliklerle günceller. Yükseltmeden önce release notlarını kontrol et.

Temel Çıkarımlar

  1. Wizard kullannpx @sentry/wizard@latest -i reactNative kurulumun büyük bölümünü otomatik halleder.
  2. Development build’ler gerekli — Expo Go yalnızca JavaScript hatalarını yakalar. Native crash’ler, frame takibi ve session replay için development build gerekir.
  3. Auth token’ını güvende tutSENTRY_AUTH_TOKEN değerini asla app.json içine koyma. EAS secret’ları veya environment variable’lar kullan.
  4. EAS Update manuel source map yüklemesi gerektirir — EAS Build’den farklı olarak, OTA güncellemeleri source map’leri otomatik yüklemez. CI pipeline’ında sentry-expo-upload-sourcemaps komutunu otomatize et.
  5. Production’da düşük örnekleme oranları kullan — Trace’ler için %10-20, session replay’ler için %10, hata replay’leri için %100.
  6. OTA güncellemelerini etiketle — Hataları güncelleme sürümüne göre filtreleyebilmek için expo-updates metadata’sını Sentry scope’unda kullan.

Kaynaklar

İlgili yazılar

Mobil Micro Frontend'ler: Production'da Çok Kanallı Deneyimler

React Native ve WebView'lar ile mobil micro frontend'ler oluşturma. Çok kanallı uygulamalar için production stratejileri ve performans optimizasyonu.

expoperformancere-pack+4
DynamoDB Rate Limiting: Single Table Design'da Ölçekte Stratejiler

Single Table Design uygulamalarında DynamoDB throttling'i önleme ve yönetme stratejileri. Partition key tasarımı, write sharding, kapasite modları, DAX caching, retry pattern'leri ve yüksek throughput sistemler için CloudWatch monitoring konularını kapsar.

dynamodbawsrate-limiting+5
TypeScript Formatlama ve Linting Araçları Karşılaştırması: Biome, Oxlint, ESLint ve Prettier

Modern TypeScript linting ve formatlama araçlarının kapsamlı karşılaştırması - ESLint, Prettier, Biome ve Oxlint - performans ölçümleri, konfigürasyon örnekleri ve migration stratejileriyle.

typescripteslintprettier+7
LangChain Production'da: Çalışan Patternler ve İşe Yaramayan Anti-Patternler

LangChain uygulamalarını production'a taşırken öğrendiklerim. Başarısızlığa yol açan anti-patternler, başarıyı sağlayan patternler, çalışan kod örnekleri ve maliyet optimizasyon stratejileri.

langchainllmproduction+5
Veritabanı Query Profiling: Sistematik Optimizasyon Yolculuğu

Sistematik veritabanı profiling ve optimizasyonu ile yıllık altyapı maliyetlerini 100K dolar azalttığımız hikaye. PostgreSQL ve MongoDB performance deneyimleri.

database-optimizationpostgresqlmongodb+7