الوثائقNext.js مع App Router4 دقيقة قراءة

Next.js مع App Router

تعمل الحزمة على الجانبين، لكن كل جانب يريد شيئًا: مكوّن العميل يعيد الرسم، ومكوّن الخادم لا يستطيع. فاختَر لكل نص، لا لكل تطبيق.

lib/siyak.ts
import { init } from 'siyak-js';

// One module, two instances: the client one keeps localStorage, the server one
// must not touch it.
export const siyak = init({
  apiKey: process.env.NEXT_PUBLIC_SIYAK_KEY!,
  endpoint: process.env.NEXT_PUBLIC_SIYAK_URL!,
  target: 'ar',
  cache: typeof window === 'undefined' ? false : undefined,
});

مكوّنات العميل

app/(shop)/checkout/page.tsx
'use client';
import { siyak } from '@/lib/siyak';

export default function Checkout() {
  return <button>{siyak.t('Continue', 'screen:checkout')}</button>;
}

كما في React: أول رسم قد يكون بلغتك الأصلية ثم تصل الدفعة بعد لحظة. أضف أثرًا في التخطيط ينتظر siyak.onReady ويعيد العرض، فتنضبط كل صفحة أسفله.

مكوّنات الخادم ومعالجات المسار

app/[locale]/page.tsx
import { siyak } from '@/lib/siyak';

export default async function Page() {
  siyak.t('Continue', 'screen:checkout');
  await siyak.flush();                        // no repaint up here
  return <p>{siyak.t('Continue', 'screen:checkout')}</p>;
}
  • استدعِ flush() قبل إخراج الوسوم وإلا خرج HTML بلغته الأصلية: صحيح لكنه غير مترجم.
  • كل عرضٍ يستدعي flush يضيف رحلة ذهاب وعودة إلى زمن أول بايت. خزّن النتيجة بـ unstable_cache أو بتخزين المسار كاملًا، فالنص المعتمد يُجاب عليه من الذاكرة المؤقتة دون أي استدعاء للنموذج.
  • بادئة NEXT_PUBLIC_ تعني أن المفتاح داخل حزمة العميل، وهذا هو الأصل في مفاتيح المتصفح؛ واجعل للخادم مفتاحًا مستقلًا إن أردت رصيدًا مستقلًا.
  • الموجّه ووقت الحافة: تحتاج الحزمة fetch (متاحة) ولا تحتاج localStorage — مرّر cache: false.