⏱️4 min read · 828 words
يعمل Next.js 15 على ترسيخ مستقبل React الكامل. مع استقرار App Router، ومكونات React Server كمكونات افتراضية، واستبدال Turbopack لـ Webpack، أصبح إنشاء تطبيقات Next.js للإنتاج في عام 2026 أسرع وأقوى من أي وقت مضى.
📋 Table of Contents
ما الجديد في Next.js 15
- Turbopack مستقر– إنشاءات أسرع بـ 10 مرات، وHMR أسرع بـ 700 مرة مقارنة بـ Webpack
- رد فعل 19 دعم من الدرجة الأولى— مكونات الخادم، الإجراءات، الخطاف use()
- العرض المسبق الجزئي (PPR)— غلاف ثابت + جزر ديناميكية في نفس الصفحة
- تحسين التخزين المؤقت– لا مزيد من السلوك المفاجئ لذاكرة التخزين المؤقت الافتراضية
- واجهات برمجة التطبيقات الديناميكية— ملفات تعريف الارتباط ()، والرؤوس ()، وsearchParams أصبحت الآن غير متزامنة
إعداد المشروع
# Create new Next.js 15 project
npx create-next-app@latest my-app --typescript --tailwind --app --turbopack
cd my-app
# Project structure
# app/
# layout.tsx — root layout
# page.tsx — home page
# globals.css
# (dashboard)/ — route group (no URL segment)
# page.tsx
# blog/
# [slug]/
# page.tsx — dynamic route
# api/
# users/
# route.ts — API route handler
أساسيات جهاز توجيه التطبيق
// app/layout.tsx — Root Layout (required)
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: { template: "%s | My App", default: "My App" },
description: "Built with Next.js 15",
openGraph: {
type: "website",
locale: "en_US",
url: "https://myapp.com",
siteName: "My App",
},
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}
مكونات الخادم مقابل مكونات العميل
// Server Component (default) — runs on server, no JavaScript sent to client
// app/blog/page.tsx
async function BlogPage() {
// Direct database/API access — no useEffect needed
const posts = await db.query("SELECT * FROM posts ORDER BY created_at DESC");
return (
<main>
<h1>Blog</h1>
{posts.map(post => (
<article key={post.id}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</main>
);
}
// Client Component — add "use client" directive
"use client";
import { useState } from "react";
function SearchBar({ onSearch }: { onSearch: (q: string) => void }) {
const [query, setQuery] = useState("");
return (
<input
value={query}
onChange={e => setQuery(e.target.value)}
onKeyDown={e => e.key === "Enter" && onSearch(query)}
placeholder="Search..."
/>
);
}
جلب البيانات باستخدام مكونات الخادم
// Parallel data fetching — no waterfalls
async function Dashboard() {
// These run in parallel
const [user, posts, stats] = await Promise.all([
fetchUser(),
fetchPosts(),
fetchStats(),
]);
return (
<div>
<UserCard user={user} />
<PostList posts={posts} />
<StatsPanel stats={stats} />
</div>
);
}
// Dynamic rendering with searchParams (Next.js 15: async)
export default async function SearchPage({
searchParams,
}: {
searchParams: Promise<{ q?: string; page?: string }>;
}) {
const { q = "", page = "1" } = await searchParams;
const results = await searchPosts(q, parseInt(page));
return <SearchResults results={results} query={q} />;
}
إجراءات الخادم
تتيح لك إجراءات الخادم تشغيل تعليمات برمجية للخادم من النماذج ومعالجات الأحداث:
// app/actions.ts
"use server";
import { revalidatePath } from "next/cache";
import { redirect } from "next/navigation";
export async function createPost(formData: FormData) {
const title = formData.get("title") as string;
const content = formData.get("content") as string;
// Validate
if (!title || title.length < 3) {
return { error: "Title must be at least 3 characters" };
}
// Save to database
await db.posts.create({ title, content });
// Revalidate and redirect
revalidatePath("/blog");
redirect("/blog");
}
// Use in a form
export default function NewPostForm() {
return (
<form action={createPost}>
<input name="title" placeholder="Title" required />
<textarea name="content" placeholder="Content" />
<button type="submit">Publish</button>
</form>
);
}
معالجات المسار (طرق API)
// app/api/users/route.ts
import { NextRequest, NextResponse } from "next/server";
export async function GET(request: NextRequest) {
const { searchParams } = request.nextUrl;
const page = parseInt(searchParams.get("page") ?? "1");
const users = await db.users.findMany({
skip: (page - 1) * 10,
take: 10,
});
return NextResponse.json({ users, page });
}
export async function POST(request: NextRequest) {
const body = await request.json();
const user = await db.users.create({ data: body });
return NextResponse.json(user, { status: 201 });
}
// app/api/users/[id]/route.ts
export async function DELETE(
request: NextRequest,
{ params }: { params: Promise<{ id: string }> }
) {
const { id } = await params;
await db.users.delete({ where: { id } });
return new NextResponse(null, { status: 204 });
}
العرض المسبق الجزئي (PPR)
يتيح لك PPR دمج المحتوى الثابت والديناميكي في صفحة واحدة:
// next.config.ts
import type { NextConfig } from "next";
const config: NextConfig = {
experimental: {
ppr: true,
},
};
export default config;
// page.tsx — static shell + dynamic island
import { Suspense } from "react";
export default function ProductPage({ params }: { params: { id: string } }) {
return (
<div>
{/* Static — generated at build time */}
<ProductDetails id={params.id} />
{/* Dynamic — rendered per request */}
<Suspense fallback={<PriceSkeleton />}>
<DynamicPrice id={params.id} />
</Suspense>
<Suspense fallback={<ReviewsSkeleton />}>
<UserReviews id={params.id} />
</Suspense>
</div>
);
}
الوسيطة
// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const token = request.cookies.get("auth-token")?.value;
const isProtected = request.nextUrl.pathname.startsWith("/dashboard");
if (isProtected && !token) {
return NextResponse.redirect(new URL("/login", request.url));
}
// Add security headers
const response = NextResponse.next();
response.headers.set("X-Frame-Options", "DENY");
response.headers.set("X-Content-Type-Options", "nosniff");
return response;
}
export const config = {
matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
};
تحسين الصورة
import Image from "next/image";
// Optimized image — auto WebP/AVIF, lazy loading, size hints
export function HeroImage({ src, alt }: { src: string; alt: string }) {
return (
<Image
src={src}
alt={alt}
width={1200}
height={630}
priority // LCP image — eager load
quality={85}
placeholder="blur"
blurDataURL="data:image/jpeg;base64,/9j..." // low-quality placeholder
/>
);
}
// Fill container
<div style={{ position: "relative", aspectRatio: "16/9" }}>
<Image src="/hero.jpg" alt="Hero" fill sizes="100vw" />
</div>
النشر والإنتاج
- فيرسل— تكوين صفري، شبكة طرفية، PPR تلقائي
- استضافة ذاتية —
next build && next startمع Node.js - عامل ميناء— ملف Next.js Dockerfile الرسمي بمخرج مستقل
Next.js 15 هو إطار عمل React الأكثر اكتمالاً لعام 2026. تعمل مكونات الخادم على التخلص من الجلب الزائد، وتبسط إجراءات الخادم الطفرات، ويقدم PPR أفضل عرض ثابت وديناميكي على نفس الصفحة.
🔗 Share this article
✍️ Leave a Comment