مڈل ویئر

⁦middleware.ts⁩: ہر درخواست سے پہلے ری ڈائریکٹس، ری رائٹس، ہیڈرز اور کوکیز، config.matcher کے ساتھ۔

مڈل ویئر درخواست مکمل ہونے سے پہلے کوڈ چلاتا ہے۔ یہ ری ڈائریکٹ، ری رائٹ، ہیڈرز اور کوکیز سیٹ کر سکتا ہے، یا خود جواب واپس کر سکتا ہے۔

طریقۂ کار

پروجیکٹ کی روٹ (یا src/) میں، app/ کے ساتھ middleware.ts فائل بنائیں۔ ایک middleware فنکشن (یا ڈیفالٹ ایکسپورٹ) اور اختیاری config ایکسپورٹ کریں۔

middleware.tsts
import { NextResponse, type NextRequest } from "@textjs/app/server";export function middleware(request: NextRequest) {  if (!request.cookies.has("session")) {    return NextResponse.redirect(new URL("/login", request.url));  }  return NextResponse.next();}export const config = {  matcher: ["/dashboard/:path*", "/api/:path*"],};

مڈل ویئر text dev، text start اور ہر سرور ڈیپلائے اڈاپٹر پر روٹ ہینڈلرز، اسٹیٹک فائلوں اور کونسول صفحات سے پہلے چلتا ہے۔ یہ Web کے Request اور Response استعمال کرتا ہے، اس لیے یہی فائل Node، Bun، ⁦Vercel Edge⁩ اور ⁦Cloudflare Workers⁩ پر چلتی ہے۔

پاتھ میچ کرنا

config.matcher کے بغیر، مڈل ویئر ہر درخواست کے لیے چلتا ہے۔ میچرز Next.js والا سنٹیکس استعمال کرتے ہیں:

میچرمیچ ہونے والے پاتھ
/about/about اور /about/
/blog/:slug/blog/hello
/docs/:path*/docs، /docs/a/b
/a/:rest+/a/b، مگر /a نہیں
/user/:id(\\d+)/user/42، مگر /user/ada نہیں
/((?!api/).*)/api/* کے سوا سب کچھ

has اور missing سے شرائط شامل کریں (ہیڈر، کوکی، کوئری یا ہوسٹ):

middleware.tsts
export const config = {  matcher: [{ source: "/beta/:path*", has: [{ type: "cookie", key: "beta", value: "1" }] }],};

میچرز basePath کے بغیر پاتھ نیم پر لاگو ہوتے ہیں۔ text dev میں، Vite کی اپنی ماڈیول درخواستیں (/@vite/*، سورس فائلیں) کبھی مڈل ویئر نہیں چلاتیں۔

ہر ہوسٹ مڈل ویئر چلنے سے پہلے ایک معیاری پاتھ نیم طے کرتا ہے، اور اسے میچنگ، request.nextUrl اور روٹ، ہینڈلر اور فائل کی تلاش کے لیے استعمال کرتا ہے۔ پرسنٹ ایسکیپس ڈی کوڈ ہوتے ہیں اور پاتھ دوبارہ اسی طرح ان کوڈ ہوتا ہے جیسے new URL() اسے لکھتا ہے، . اور .. حصے حل ہوتے ہیں، اور دہرائے گئے اور آخر میں موجود سلیش ہٹا دیے جاتے ہیں۔ /ad%6din//users/ مڈل ویئر تک /admin/users کی صورت میں پہنچتا ہے، جبکہ /café کی صورت /caf%C3%A9 ہی رہتی ہے۔ آخر میں سلیش کے ساتھ لکھا گیا میچر، جیسے /admin/، /admin سے میچ ہوتا ہے۔ جن درخواستوں کے پاتھ میں ان کوڈ شدہ سلیش یا بیک سلیش (%2F، %5C)، کنٹرول کریکٹر یا غلط پرسنٹ ان کوڈنگ ہو، انہیں 400 ملتا ہے۔ روٹس میں بڑے اور چھوٹے حروف کا فرق ہوتا ہے: /Admin، /admin سے میچ نہیں ہوتا، اور اسٹیٹک فائلیں صرف ان کے عین نام پر پیش ہوتی ہیں۔

ان URLs کو میچ کریں جن پر فائل پیش ہوتی ہے، صرف اس کے فائل نام کو نہیں۔ ⁦Cloudflare Pages⁩، report.html کو /report پر بھی پیش کرتا ہے، اس لیے /report.html کا میچر /report کو محفوظ نہیں کرتا۔ دونوں درج کریں، matcher: ["/report", "/report.html"]، یا محفوظ فائلیں ایک ڈائریکٹری میں رکھیں اور اسے میچ کریں، جیسے public/reports/ کی فائلوں کے لیے /reports/:path*۔

NextResponse

⁦API⁩اثر
NextResponse.next()روٹ کی طرف آگے بڑھنا
NextResponse.redirect(url, status?)ڈیفالٹ طور پر 307؛ url کا مطلق ہونا ضروری ہے
NextResponse.rewrite(url)دوسرا پاتھ پیش کرنا؛ بیرونی اوریجنز کو پراکسی کرنا
NextResponse.json(body, init?)JSON کے ساتھ جواب دینا
new Response(...)کسی بھی چیز کے ساتھ جواب دینا

بغیر تبدیلی آگے بڑھنے کے لیے کچھ واپس نہ کریں۔ next() اور rewrite() حتمی جواب کا اسٹیٹس بدلنے کے لیے { status } قبول کرتے ہیں۔ صرف NextResponse.next() / NextResponse.rewrite() سے بنے جواب روٹنگ کی سمت طے کرتے ہیں: کوئی بھی دوسرا Response، بشمول fetch() سے واپس آنے والا جواب، اپنے x-middleware-* ہیڈرز ہٹانے کے بعد جوں کا توں کلائنٹ کو بھیج دیا جاتا ہے۔

request.nextUrl اپنے pathname سے basePath کو خارج کرتا ہے، جبکہ اس کے href اور toString() میں یہ شامل ہوتا ہے۔ ایپ کے اندر رہنے کے لیے اسے کلون کریں: const url = request.nextUrl.clone(); url.pathname = "/login"; return NextResponse.redirect(url);۔

middleware.tsts
export function middleware(request: NextRequest) {  if (request.nextUrl.pathname === "/status") {    return NextResponse.rewrite(new URL("/api/health", request.url));  }}

ہیڈرز

بعد کے ہینڈلرز کو ملنے والی معلومات بدلنے کے لیے request.headers پاس کریں، اور جواب کے ہیڈرز شامل کرنے کے لیے headers پاس کریں:

middleware.tsts
export function middleware(request: NextRequest) {  const headers = new Headers(request.headers);  headers.set("x-user", "ada");  const response = NextResponse.next({ request: { headers } });  response.headers.set("x-frame", "▼");  return response;}

مڈل ویئر کے جواب کے ہیڈرز حتمی جواب میں شامل ہوتے ہیں، جب تک روٹ ہینڈلر وہی ہیڈر سیٹ نہ کرے۔

کوکیز

request.cookies، Cookie ہیڈر پڑھتا ہے؛ response.cookies، Set-Cookie لکھتا ہے۔

middleware.tsts
export function middleware(request: NextRequest) {  const theme = request.cookies.get("theme")?.value ?? "geistDark";  const response = NextResponse.next();  response.cookies.set("theme", theme, { httpOnly: true, sameSite: "lax", maxAge: 60 * 60 * 24 });  return response;}

next() یا rewrite() کے جواب پر سیٹ کی گئی کوکیز اسی درخواست میں روٹ ہینڈلر کو بھی نظر آتی ہیں۔

پس منظر کا کام

دوسرے آرگومنٹ میں waitUntil() ہوتا ہے، جو جواب بھیجنے کے بعد سرورلیس رن ٹائمز کو فعال رکھتا ہے:

middleware.tsts
import type { NextFetchEvent, NextRequest } from "@textjs/app/server";export function middleware(request: NextRequest, event: NextFetchEvent) {  event.waitUntil(fetch("https://analytics.example.com", { method: "POST", body: request.url }));}

نوٹس

  • کلائنٹ پر رینڈر ہونے والے صفحات براؤزر میں رینڈر ہوتے ہیں، اس لیے دوسرے صفحے پر ری رائٹ کرنے سے پیش ہونے والی فائل بدلتی ہے، وہ روٹ نہیں جسے کونسول ایپ رینڈر کرتی ہے۔ روٹ ہینڈلرز، اسٹیٹک فائلوں اور بیرونی اوریجنز کے لیے ری رائٹس توقع کے مطابق کام کرتی ہیں۔
  • مڈل ویئر درخواست کی باڈی پڑھ سکتا ہے؛ روٹ ہینڈلرز کو پھر بھی یہ ملتی ہے۔ میچر جن درخواستوں کو خارج کرتا ہے ان کی باڈی کو کبھی نہیں چھیڑا جاتا۔
  • request.url میں ہمیشہ سرور کا اوریجن ہوتا ہے: //other.host/x جیسے درخواست کے ٹارگٹس کو شروع میں ایک سلیش والی شکل دی جاتی ہے۔
  • اسٹیٹک اڈاپٹر مڈل ویئر نہیں چلا سکتا۔
⁦GitHub⁩ پر اس صفحے میں ترمیم کریں