Next.js App Router Entegrasyonu

@copypatch/next paketi, CopyPatch v3’ü Next.js App Router (React Server Components) ile doğrudan entegre eder. Same-origin rota işleyicilerini sağlar ve sunucu tarafı render sırasında doğrudan veritabanından yayınlanmış metinleri okur.

1. Paylaşılan Backend Singleton Nesnesini Tanımlayın

Kalıcılık adaptörünü ve CopyPatch backend çalışma zamanını başlatan bir sunucu modülü oluşturun:

lib/copypatch.ts
// lib/copypatch.ts
import { createCopyPatchBackend } from '@copypatch/backend';
import { createSQLitePersistence } from '@copypatch/storage-sqlite';

const persistence = createSQLitePersistence('./copypatch.sqlite');
await persistence.migrate();

const copypatch = createCopyPatchBackend({
  persistence,
  passphraseHash: process.env.COPYPATCH_PASSPHRASE_HASH!,
});

2. Same-Origin Rota İşleyicisini (Route Handler) Mount Edin

app/%5F%5Fcopypatch/api/v2/[…path]/route.ts dosya yolunda catch-all bir rota işleyicisi oluşturun:

app/%5F%5Fcopypatch/api/v2/[...path]/route.ts
// app/%5F%5Fcopypatch/api/v2/[...path]/route.ts
import { createCopyPatchRouteHandlers } from '@copypatch/next/server';
import { copypatch } from '@/lib/copypatch';

// Bunu deployment platformunuzun sağladığı ya da forwarding header'larına
// açıkça güvendiğiniz bir proxy'nin doğrulanmış adresiyle uygulayın.
declare function resolveTrustedClientAddress(request: Request): Promise<string>;

export const { GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS } =
  createCopyPatchRouteHandlers(copypatch, {
    resolveContext: async (request) => ({
      clientAddress: await resolveTrustedClientAddress(request),
    }),
  });

Güvenilir bir clientAddress çözümlenmezse unsafe istekler CLIENT_ADDRESS_UNAVAILABLE ile fail-closed olur. CopyPatch x-forwarded-for başlığına otomatik olarak güvenmez. Deployment’ınız bilinçli olarak tek bir paylaşımlı rate-limit bucket’ı kabul ediyorsa bunun yerine unsafeRequestWithoutClientAddress: ‘shared-bucket’ seçeneğini açıkça kullanın.

Neden %5F%5Fcopypatch? Next.js dosya sisteminde alt çizgi ile başlayan klasörleri (örn. _copypatch) özel (private) kabul eder ve bunları URL yönlendirmesinden hariç tutar. Alt çizgileri yüzde kodlamasıyla (URL percent-encoding) %5F%5Fcopypatch olarak adlandırarak, Next.js’in standart genel /__copypatch/api/v2/… yolunu sorunsuz sunması sağlanır.

3. Sunucu Bileşenlerinde Önceden Render Etme (SSR/RSC)

Sayfa veya Sunucu Bileşenlerinizde readPublishedSnapshot() fonksiyonunu çağırın. Bu fonksiyon dahili bir HTTP isteği yapmadan doğrudan depolama katmanından okuma yapar ve anlık görüntüyü NextCopyPatchProvider sağlayıcısına aktarır:

app/[locale]/page.tsx
// app/[locale]/page.tsx
import { NextCopyPatchProvider, EditableText } from '@copypatch/next';
import { readPublishedSnapshot } from '@copypatch/next/server';
import { copypatch } from '@/lib/copypatch';

export default async function Page({
  params,
}: {
  params: Promise<{ locale: string }>;
}) {
  const { locale } = await params;

  // Sunucu Bileşeni içinde doğrudan veritabanı okuması (Sıfır HTTP gecikmesi)
  const initialSnapshot = await readPublishedSnapshot(copypatch, locale, {
    fallback: {
      revision: 1,
      content: { 'home.hero.title': 'Platformumuza Hoş Geldiniz' },
    },
  });

  return (
    <NextCopyPatchProvider locale={locale} initialSnapshot={initialSnapshot}>
      <main className="container">
        <EditableText contentKey="home.hero.title" as="h1">
          Platformumuza Hoş Geldiniz
        </EditableText>
      </main>
    </NextCopyPatchProvider>
  );
}

Next.js Entegrasyonunun Avantajları

  • Sıfır Yerleşim Kayması (Zero Layout Shift): Metinler sunucu tarafında oluşturulan ilk HTML yanıtına gömülür.
  • Sıfır HTTP Ek Yükü: Sunucu bileşeni localhost adresine istek göndermeden doğrudan bellek veya veritabanı havuzundan okur.
  • Proxy veya Rewrite İhtiyacı Yok: Rota doğrudan Next.js uygulamanızın içinde yaşadığı için next.config.js içinde karmaşık yönlendirme kuralları gerekmez.

Statik Dışa Aktarma (Static Export) Uyarısı

Önemli: CopyPatch, serverless Node deployment’ları dahil Node.js sunucu runtime’ı gerektirir. Edge ve output: ‘export’ çalışma zamanları kimlik doğrulamalı düzenleme API’sini veya native veritabanı kalıcılığını barındıramaz.