Mühendislik//9 dk okuma

2026'da Internationalization Testi: Araçlar, Stratejiler ve Otomasyon

Eray Gündoğmuş
Paylaş

2026'da Internationalization Testi: Araçlar, Stratejiler ve Otomasyon

Çoğu ekip i18n'i bir deployment problemi olarak ele alır. İngilizce sürümü yayınlarlar, çevirmenlere devredip prodüksiyonun kendini düzelteceğini varsayarlar. Genellikle olmaz. Tarih formatları Japonya'da bozulur. Arapça metin, RTL için tasarlanmış bir sayfada soldan sağa akar. İngilizce'de 8 karakter olan bir Almanca kelime artık 24 karakter uzunluğundadır — ve kimsenin o uzunlukta test etmediği bir butondan taşmaktadır.

i18n testi, pahalı, belirsiz ve otomatize edilmesi zor göründüğü için sürekli atlanır. Bu yazı konuyu gizemden arındırıyor. Sonunda neyi test edeceğiniz, nasıl otomatize edeceğiniz ve locale regresyonlarının kullanıcılara ulaşmadan önce yakalanması için CI/CD'ye nasıl entegre edeceğiniz konusunda net bir fikre sahip olacaksınız.


i18n Testi ile Localization Testi: Fark Nedir?

Bu terimler çoğu zaman birbirinin yerine kullanılır, ancak farklı hata türlerini kapsar.

Internationalization (i18n) testi, uygulamanızın yapısal olarak birden fazla locale'i destekleyecek kapasitede olduğunu doğrular. Hardcoded string'leri, bozuk encoding'i, eksik locale fallback'lerini ve metin uzunluğu değiştiğinde yaşanan layout çökmelerini tespit eder. Bu bir mühendislik problemidir — kod tabanınızda yaşar, çeviri dosyalarında değil.

Localization (l10n) testi, çevrilen içeriğin belirli bir locale için doğru, bağlamsal olarak uygun ve kültürel açıdan doğru olduğunu doğrular. Bu, insan incelemesi, anadil konuşucuları ve alana özgü doğrulama içerir. Bu bir içerik problemidir — çeviri verilerinizde yaşar.

Her ikisi de gereklidir, ancak farklı araçlar ve farklı sahipler gerektirir. i18n testi tamamen otomatize edilebilir. l10n testi kısmen otomatize edilebilir (encoding, format doğrulama) ancak kalite için insan yargısı gerektirir.

Bu yazı i18n testine odaklanıyor çünkü sessiz prodüksiyon hatalarının büyük çoğunluğu burada yaşıyor. Test stratejilerine dalmadan önce, testlerinizin doğrulayacağı mimari kararlar olan localization ve internationalization'ın tam kapsamını anlamak faydalıdır; böylece test takımınız doğru hata türleri etrafında yapılandırılmış olur. Localization kalitesinin ürününüzün arama görünürlüğünü ve kullanıcı güvenini nasıl etkilediğine dair daha geniş bir bakış için SEO translations rehberimize bakın.


Katman 1: Fonksiyonel Test — Açık Hataları Bulmak

İlk i18n test katmanı kolay şeyleri yakalar: eksik çeviriler, encoding hataları ve hiç çıkarılmamış hardcoded string'ler.

Eksik Çeviri Tespiti

Çoğu i18n framework'ünde bir fallback mekanizması vardır — fr-FR'da bir çeviri anahtarı eksikse en-US'e geri döner. Bu geliştirme ortamında kullanışlıdır ancak prodüksiyonda tehlikelidir: herhangi bir hata olmaksızın Fransız kullanıcılara sessizce İngilizce içerik sunarsınız.

İyi bir otomatik test stratejisi, her locale rotasında bir assertion zorlar:

// Playwright test: eksik çevirileri tespit et
import { test, expect } from '@playwright/test';

const LOCALES = ['en', 'fr', 'de', 'ja', 'ar'];
const CRITICAL_ROUTES = ['/', '/pricing', '/features', '/docs'];

for (const locale of LOCALES) {
  for (const route of CRITICAL_ROUTES) {
    test(`[${locale}] ${route} has no missing translation keys`, async ({ page }) => {
      // Eksik anahtar uyarıları için console hatalarını yakala
      const missingKeys: string[] = [];
      page.on('console', (msg) => {
        if (msg.type() === 'warn' && msg.text().includes('missing translation')) {
          missingKeys.push(msg.text());
        }
      });

      await page.goto(`/${locale}${route}`);
      await page.waitForLoadState('networkidle');

      expect(missingKeys, `Missing translations on ${locale}${route}`).toHaveLength(0);
    });
  }
}

i18n kütüphaneniz eksik anahtarlar için console uyarısı vermiyorsa, test ortamlarında bunu yapacak şekilde yapılandırın. Bu, hemen meyvesini veren tek seferlik bir kurulum işlemidir.

Hardcoded String Tespiti

Hardcoded string'ler en yaygın i18n hatasıdır. Bir geliştirici yeni bir UI öğesi ekler ve string'i bir çeviri çağrısına sarmayı unutur. İngilizce metin her locale'e gönderilir.

Bunların büyük çoğunluğunu statik analiz geçişiyle yakalayabilirsiniz:

# Kullanıcıya yönelik metin gibi görünen ancak çeviri çağrılarında olmayan string'leri bul
# i18n kütüphanenize göre kalıpları ayarlayın (t(), i18n.t(), useTranslation(), vb.)
grep -rn '"[A-Z][a-z]' src/components --include="*.tsx" \
  | grep -v "// i18n-ignore" \
  | grep -v "t('" \
  | grep -v "aria-label" # ayrıca ele alın

Bu kesin değildir — yanlış pozitifler alacaksınız — ancak CI'da çalıştırmak için yeterince hızlıdır ve yakaladıkları için gürültüye değer.


Katman 2: Locale'e Özgü Format Testi

Tarihler, sayılar ve para birimleri locale'e duyarlıdır. en-US'de 1,234.56 olarak biçimlendirilen bir sayı de-DE'de 1.234,56 olur. ABD'de 03/01/2026 olarak okunan bir tarih 1 Mart anlamına gelir; Avrupa'nın büyük bölümünde ise 3 Ocak anlamına gelir.

Bu hatalar, locale'e uygun verilerle aktif olarak test etmediğiniz sürece görünmezdir.

Tarih ve Sayı Format Doğrulama

// Playwright test: locale'e özgü biçimlendirmeyi doğrula
test.describe('Locale formatting', () => {
  test('de-DE formats numbers with correct separators', async ({ page }) => {
    await page.goto('/de/pricing');

    // Gösterilen fiyat öğesini bul
    const priceElement = page.locator('[data-testid="price-monthly"]');
    const priceText = await priceElement.textContent();

    // Almanca sayı formatı: binler ayırıcısı olarak nokta, ondalık olarak virgül
    expect(priceText).toMatch(/\d+\.\d+,\d{2}/);
    // en-US stili biçimlendirme İÇERMEMELİ
    expect(priceText).not.toMatch(/\d+,\d+\.\d{2}/);
  });

  test('ja-JP formats dates in Japanese convention', async ({ page }) => {
    await page.goto('/ja/blog/latest');

    const dateElement = page.locator('[data-testid="post-date"]');
    const dateText = await dateElement.textContent();

    // Japonca tarih formatı: YYYY年MM月DD日
    expect(dateText).toMatch(/\d{4}年\d{1,2}月\d{1,2}日/);
  });
});

Buradaki önemli nokta, her locale için "doğrunun" nasıl göründüğünü bilmeniz gerektiğidir. Beklenen kalıpları belgeleyen bir locale format fixture dosyası oluşturun, ardından bu kalıplere karşı programatik olarak assertion yapın.

Para Birimi Gösterimi

Para birimi özellikle hassastır. en-US için $100 uygundur. en-GB için £100 isteyebilirsiniz. de-DE için miktardan sonra sembol gelen 100 €. ja-JP için ondalık basamak olmayan ¥100.

const CURRENCY_EXPECTATIONS = {
  'en-US': { symbol: '$', position: 'before', decimals: 2 },
  'de-DE': { symbol: '€', position: 'after', decimals: 2 },
  'ja-JP': { symbol: '¥', position: 'before', decimals: 0 },
} as const;

test.describe('Currency formatting', () => {
  for (const [locale, expectations] of Object.entries(CURRENCY_EXPECTATIONS)) {
    test(`[${locale}] currency displays correctly`, async ({ page }) => {
      await page.goto(`/${locale}/pricing`);
      const priceText = await page.locator('[data-testid="price"]').textContent();

      expect(priceText).toContain(expectations.symbol);
      if (expectations.position === 'before') {
        expect(priceText?.indexOf(expectations.symbol)).toBeLessThan(
          priceText?.search(/\d/) ?? Infinity
        );
      }
    });
  }
});

Katman 3: Karakter Render'ı ve Layout

İşte i18n testinin görsel olarak ilginç hale geldiği yer burası. Farklı yazı sistemleri, yön veya karakter karmaşıklığına sahip betikler, layout'ları İngilizce'de tamamen görünmez biçimlerde bozabilir.

RTL Dil Testi

Arapça, İbranice, Farsça ve Urduca sağdan sola okunur. İngilizce'de mükemmel görünen bir layout, RTL locale'lerinde metin butonların üzerine binebilir, navigasyon hizasız olabilir veya form alanları bozulabilir.

test('Arabic layout renders correctly in RTL mode', async ({ page }) => {
  await page.goto('/ar/');

  // HTML dir attribute'ünün doğru ayarlandığını doğrula
  const dir = await page.getAttribute('html', 'dir');
  expect(dir).toBe('rtl');

  // Metin ağırlıklı öğelerin taşmadığını kontrol et
  const nav = page.locator('nav');
  const navBoundingBox = await nav.boundingBox();
  const viewportSize = page.viewportSize();

  expect(navBoundingBox?.width).toBeLessThanOrEqual(viewportSize?.width ?? 0);

  // Document body'nin doğru metin yönüne sahip olduğunu doğrula
  const bodyTextAlign = await page.evaluate(() =>
    window.getComputedStyle(document.body).direction
  );
  expect(bodyTextAlign).toBe('rtl');
});

Görsel regresyon testi, RTL layout'ları için özellikle değerlidir. İngilizce ve Arapça render'lar arasındaki piksel fark ekran görüntüsü karşılaştırması, yalnızca DOM assertion'larıyla tespit edilmesi imkânsız olan layout sorunlarını yakalayabilir.

Metin Genişleme Testi

Almanca, Fince ve Macarca string'ler genellikle İngilizce eşdeğerlerinden %30-40 daha uzundur. İngilizce kelime uzunlukları etrafında tasarlanan UI öğeleri taşar, kırpılır veya garip biçimde kaydırılır.

test('Buttons handle text expansion gracefully in de-DE', async ({ page }) => {
  await page.goto('/de/');

  // Tüm CTA butonlarını kontrol et
  const buttons = page.locator('button[data-cta], a[data-cta]');
  const buttonCount = await buttons.count();

  for (let i = 0; i < buttonCount; i++) {
    const button = buttons.nth(i);
    const box = await button.boundingBox();
    const text = await button.textContent();

    if (box && text) {
      // Metnin kırpılmadığından emin ol
      const scrollWidth = await button.evaluate((el) => el.scrollWidth);
      const clientWidth = await button.evaluate((el) => el.clientWidth);

      expect(scrollWidth, `Button "${text}" is overflowing`).toBeLessThanOrEqual(clientWidth + 2);
    }
  }
});

Latin Dışı Betik Render'ı

Çince, Japonca, Korece, Tayca ve Devanagari betikleri özel font ve render gereksinimleri içerir. Eksik bir font fallback'i, karakter yerine kutucuklar ("tofu" problemi) ile sonuçlanabilir.

test('Japanese characters render without tofu boxes', async ({ page }) => {
  await page.goto('/ja/');

  // Herhangi bir karakterin replacement char olarak render edilip edilmediğini kontrol et
  const hasTofu = await page.evaluate(() => {
    const textNodes: Text[] = [];
    const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
    let node;
    while ((node = walker.nextNode())) {
      textNodes.push(node as Text);
    }

    // Unicode replacement karakterini kontrol et (U+FFFD)
    return textNodes.some(n => n.textContent?.includes('\uFFFD'));
  });

  expect(hasTofu).toBe(false);
});

Katman 4: Locale Değiştirme ve Durum Kalıcılığı

Locale değiştirme, şaşırtıcı derecede zengin bir hata kaynağıdır. Dil tercihi, navigasyon, sayfa yenilemesi ve ideal olarak oturumlar arasında kalıcı olmalıdır. Bunlar, end-to-end test gerektiren davranışsal hatalardır.

test.describe('Locale switching', () => {
  test('Selected locale persists after navigation', async ({ page }) => {
    await page.goto('/');

    // Fransızca'ya geç
    await page.click('[data-testid="locale-switcher"]');
    await page.click('[data-locale="fr"]');

    // Navigasyonu bekle
    await page.waitForURL('/fr/**');

    // Başka bir sayfaya git
    await page.click('nav a[href*="pricing"]');
    await page.waitForLoadState('networkidle');

    // URL hâlâ /fr/ altında olmalı
    expect(page.url()).toContain('/fr/');

    // HTML lang attribute mevcut locale'i yansıtmalı
    const lang = await page.getAttribute('html', 'lang');
    expect(lang).toBe('fr');
  });

  test('Locale preference survives page refresh', async ({ page, context }) => {
    await page.goto('/de/');

    // Sayfayı yenile
    await page.reload();

    // Hâlâ Almanca'da olmalı
    expect(page.url()).toContain('/de/');
    const lang = await page.getAttribute('html', 'lang');
    expect(lang).toContain('de');
  });

  test('User can switch back to default locale', async ({ page }) => {
    await page.goto('/fr/pricing');

    await page.click('[data-testid="locale-switcher"]');
    await page.click('[data-locale="en"]');

    await page.waitForURL('/pricing');
    const lang = await page.getAttribute('html', 'lang');
    expect(lang).toBe('en');
  });
});

Katman 5: Çok Dilli Siteler için SEO Testi

Arama motorları için düzgün yapılandırılmamış çok dilli bir site, locale varyantlarının arama sıralamalarında birbiriyle rekabet etmesine — ya da basitçe doğru şekilde indekslenmemesine — neden olur. hreflang etiketleri, arama motorlarına locale ilişkileri hakkında bilgi vermenin birincil mekanizmasıdır. Bunun sıralamalarınız için neden önemli olduğuna kapsamlı bir genel bakış için localization SEO strategy rehberimize bakın.

test.describe('SEO: hreflang configuration', () => {
  const SUPPORTED_LOCALES = ['en', 'fr', 'de', 'ja'];

  test('Home page has correct hreflang tags for all locales', async ({ page }) => {
    await page.goto('/');

    // x-default hreflang'ı kontrol et
    const xDefault = await page.locator('link[rel="alternate"][hreflang="x-default"]').count();
    expect(xDefault).toBe(1);

    // Her locale'in bir hreflang etiketi olduğunu kontrol et
    for (const locale of SUPPORTED_LOCALES) {
      const hreflangTag = page.locator(`link[rel="alternate"][hreflang="${locale}"]`);
      await expect(hreflangTag).toHaveCount(1);

      const href = await hreflangTag.getAttribute('href');
      expect(href).toBeTruthy();
      // Her href locale'e özgü URL'ye işaret etmeli
      if (locale !== 'en') {
        expect(href).toContain(`/${locale}`);
      }
    }
  });

  test('Alternate hreflang URLs are canonical and correct', async ({ page }) => {
    await page.goto('/fr/pricing');

    // Mevcut sayfanın canonical'ı fr sürümüne işaret etmeli
    const canonical = await page.locator('link[rel="canonical"]').getAttribute('href');
    expect(canonical).toContain('/fr/pricing');

    // en için hreflang /pricing'e işaret etmeli (/en/pricing'e değil)
    const enHreflang = await page
      .locator('link[rel="alternate"][hreflang="en"]')
      .getAttribute('href');
    expect(enHreflang).not.toContain('/en/');
  });
});

Locale'e özgü meta etiketlerinizi de kontrol edin — og:locale, og:locale:alternate ve <title> öğesi mevcut locale'i yansıtmalıdır:

test('Meta tags reflect current locale', async ({ page }) => {
  await page.goto('/de/');

  const ogLocale = await page.locator('meta[property="og:locale"]').getAttribute('content');
  expect(ogLocale).toBe('de_DE');

  const title = await page.title();
  // Başlık Almanca metin içermeli, İngilizce fallback değil
  expect(title).not.toBe('Better i18n - Developer-First Localization');
});

Katman 6: Locale'ler Arası Performans Testi

Çeviri bundle'ları JavaScript payload'ınıza eklenir. Tüm locale'leri aynı anda gönderiyorsanız gereksiz yük ekliyorsunuz demektir. Locale bundle'larını lazy-load ediyorsanız, yükleme stratejisinin doğru çalıştığını ve fark edilir gecikme yaratmadığını test etmelisiniz.

test('Locale bundle loads within acceptable time', async ({ page }) => {
  const bundleRequests: { url: string; duration: number }[] = [];

  page.on('response', async (response) => {
    if (response.url().includes('/locales/') || response.url().includes('translations')) {
      const timing = response.timing();
      bundleRequests.push({
        url: response.url(),
        duration: timing.responseEnd - timing.requestStart,
      });
    }
  });

  await page.goto('/fr/');
  await page.waitForLoadState('networkidle');

  // Her locale bundle'ı hızlı bağlantıda 200ms'nin altında yüklenmeli
  for (const request of bundleRequests) {
    expect(request.duration, `Slow bundle: ${request.url}`).toBeLessThan(200);
  }
});

CI'da bundle boyutlarını açıkça ölçün. Bir eşiği aşan çeviri bundle'ı build'i başarısız kılmalıdır:

# CI'da: locale bundle boyutlarını ölç
node -e "
  const fs = require('fs');
  const path = require('path');
  const localesDir = './.next/static/chunks/';
  const MAX_BUNDLE_SIZE_KB = 50;

  fs.readdirSync(localesDir)
    .filter(f => f.includes('locale') || f.includes('i18n'))
    .forEach(file => {
      const sizeKB = fs.statSync(path.join(localesDir, file)).size / 1024;
      if (sizeKB > MAX_BUNDLE_SIZE_KB) {
        console.error(\`Bundle \${file} is \${sizeKB.toFixed(1)}KB — exceeds \${MAX_BUNDLE_SIZE_KB}KB limit\`);
        process.exit(1);
      }
    });
"

CI/CD Entegrasyonu: i18n Testini Otomatik Hale Getirmek

Önem taşıyan tek i18n testi otomatik olarak çalışanıdır. İşte her pull request'te tam i18n test takımını çalıştıran eksiksiz bir GitHub Actions workflow'u:

# .github/workflows/i18n-tests.yml
name: i18n Test Suite

on:
  pull_request:
    paths:
      - 'src/**'
      - 'locales/**'
      - 'public/locales/**'

jobs:
  i18n-functional:
    name: Functional i18n Tests
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - run: npm ci
      - run: npm run build

      - name: Install Playwright browsers
        run: npx playwright install --with-deps chromium

      - name: Run i18n tests
        run: npx playwright test --project=chromium tests/i18n/
        env:
          CI: true
          BASE_URL: http://localhost:3000

      - name: Upload test results
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: playwright-report
          path: playwright-report/

  i18n-visual:
    name: Visual RTL/LTR Regression
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build

      - name: Install Playwright
        run: npx playwright install --with-deps chromium

      - name: Visual regression tests
        run: npx playwright test tests/visual/rtl.spec.ts --update-snapshots=false

      - name: Upload diff screenshots
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: visual-diffs
          path: test-results/

  bundle-size-check:
    name: Locale Bundle Size Gate
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build

      - name: Check translation bundle sizes
        run: node scripts/check-bundle-sizes.js

Locale testini sistematik hale getirmek için Playwright yapılandırmanızı düzenleyin:

// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

const LOCALES = ['en', 'fr', 'de', 'ja', 'ar'];

export default defineConfig({
  testDir: './tests',
  fullyParallel: true,
  retries: process.env.CI ? 2 : 0,

  use: {
    baseURL: process.env.BASE_URL || 'http://localhost:3000',
    trace: 'on-first-retry',
  },

  projects: [
    // i18n testlerini tüm locale'lerde paralel olarak çalıştır
    ...LOCALES.map(locale => ({
      name: `i18n-${locale}`,
      testMatch: '**/i18n/**/*.spec.ts',
      use: {
        ...devices['Desktop Chrome'],
        locale,
        // Locale ile eşleşmesi için Accept-Language header'ı ayarla
        extraHTTPHeaders: {
          'Accept-Language': locale,
        },
      },
    })),

    // Görsel regresyon: RTL'yi ayrı test et
    {
      name: 'rtl-visual',
      testMatch: '**/visual/rtl*.spec.ts',
      use: { ...devices['Desktop Chrome'] },
    },
  ],
});

Better i18n'in Yaklaşımı: Varsayılan Olarak Type-Safe Test

i18n testi ile ilgili kalıcı problemlerden biri, bozuk çeviri anahtarlarının yalnızca runtime'da keşfedilmesidir. Yeni bir component eklersiniz, henüz mevcut olmayan bir anahtara başvurursunuz ve hata sessiz bir fallback olarak prodüksiyona gider.

Better i18n, bu hata sınıfını type sistemi düzeyinde ortadan kaldırır. Çeviri anahtarlarınız typed olduğunda, TypeScript mevcut olmayan bir anahtara başvurursanız derlemeyi reddeder. Runtime'da test edilecek bir şey kalmaz çünkü başarısız olabilecek bir şey yoktur — build başarılı olmaz.

Bu, hızla değişen bir kod tabanına sahip ekipler için özellikle değerlidir. Her çeviri çağrısı için savunmacı runtime kontrolleri yazmak yerine, desteklenen tüm locale'lerde derleme zamanı garantileri elde edersiniz.

Bunu CI'da pratikte mümkün kılan özellikler: çeviri doğrulama, build adımının bir parçası olarak çalışır, böylece herhangi bir locale'deki eksik anahtar, deployment'tan önce pipeline'ı başarısız kılar. Locale bundle'ları, locale başına cache header'larıyla CDN'den sunulur; bu nedenle performans testi daha basit hale gelir — bundle-splitting mantığını değil CDN teslimatını doğrularsınız.

i18n testini aşamalı olarak benimseyen ekipler için git tabanlı workflow kullanışlıdır. Çeviri değişiklikleri, kod değişiklikleriyle birlikte version-control'de tutulur; bu da ayrı bir çeviri yönetim platformuyla koordinasyon gerektirmeden belirli locale changeset'lerini izole olarak test edebileceğiniz anlamına gelir. Bu testlerin doğrulandığı tam Next.js i18n stack'ini nasıl kuracağınıza dair ayrıntılı bir bakış için 2026 için eksiksiz Next.js i18n rehberimize bakın. Web ürününüzün yanı sıra bir mobil uygulamayı da yerelleştiriyorsanız, React Native Expo localization rehberimiz mobil katman için eşdeğer test kalıplarını kapsar.


Özet: i18n Test Kontrol Listeniz

Hemen benimseyebileceğiniz pratik bir kontrol listesi:

Fonksiyonel testler (tam otomatize edin):

  • Tüm locale rotalarında eksik çeviri anahtarı tespiti
  • Statik analiz yoluyla hardcoded string tespiti
  • ASCII olmayan içerik için encoding doğrulama

Locale format testleri (fixture'larla otomatize edin):

  • Locale başına tarih format doğrulama
  • Locale başına sayı ayırıcı doğrulama
  • Locale başına para birimi sembolü ve konumu

Layout testleri (Playwright ile otomatize edin):

  • RTL dir attribute ve layout yönü
  • Uzun form dilleri için buton/CTA metin taşması
  • Latin dışı betik render'ı (tofu kutusu yok)

Davranışsal testler (end-to-end otomatize edin):

  • Locale switcher navigasyonu
  • Sayfa yenilemesi boyunca locale kalıcılığı
  • Varsayılan locale'e dönüş

SEO testleri (her build'de otomatize edin):

  • Tüm yerelleştirilmiş sayfalarda hreflang etiketleri
  • Locale başına canonical URL'ler
  • Locale'e özgü meta etiketler

Performans testleri (CI'da kapı koyun):

  • Locale bundle boyutu eşikleri
  • Çeviri bundle yükleme süresi

CI/CD entegrasyonu:

  • i18n testleri her PR'da çalışır
  • RTL layout'ları için görsel regresyon
  • Bundle boyutu kontrolleri regresyonda build'i başarısız kılar

Kaliteli çok dilli ürünler çıkaran ekipler, en fazla çevirmene sahip olanlar değil — i18n hatalarına fonksiyonel hatalarla aynı otomasyon titizliğiyle yaklaşanlar. Pipeline'ı bir kez kurun ve locale regresyonlarını gözden kaçırmak imkânsız hale gelsin.


Better i18n, modern frontend ekipleri için tasarlanmış geliştirici odaklı bir localization platformudur. Type-safe SDK'lar, Git tabanlı workflow'lar, CDN teslimatı ve glossary uygulamalı AI çevirisi — repo'nuzda locale dosyaları olmadan.

Comments

Loading comments...