الوثائق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.