تفاوت Layout و Template در Next.js: کی و چرا باید از template.tsx استفاده کنیم؟
اگر با App Router در Next.js کار کرده باشید، احتمالاً بیشتر وقتها سراغ layout.tsx میروید. اما Next.js فایل دیگری به نام template.tsx هم در اختیار ما قرار داده که در ظاهر رفتاری بسیار مشابه دارد، ولی یک فرق ساختاری با Layout دارد.
در این مقاله بررسی میکنیم که template چیست، چه فرقی با layout دارد و چرا باید در استفاده از آن هوشمندانه عمل کنیم.
تفاوت کلیدی: حفظ State در برابر ساخت مجدد (Remount)
اصلیترین تفاوت این دو کامپوننت، نحوه رفتار آنها هنگام جابهجایی بین صفحات (Navigation) است:
-
فایل
layout.tsx: هنگام جابهجایی بین routeهای همسطح، ناپدید نمیشود، State خود را حفظ میکند و از اول رندر (Remount) نمیشود. -
فایل
template.tsx: با هر بار تغییر Route، کامپوننتtemplateبهطور کامل Unmount شده و یک نمونه (Instance) جدید از آن ساخته میشود. این یعنی تمامی Stateها و Effectهای درون آن ریست میشوند.
نکته: هرگاه یک
template.tsxدر یک پوشه داشته باشید، Next.js آن را دقیقاً به عنوان فرزندِ Layout و والدِ Page رندر میکند:Layout ➔ Template ➔ Page
چه زمانی باید از template.tsx استفاده کنیم؟
زمانی که عدم حفظ State و اجرای مجدد کد با هر تغییر صفحه رفتار مطلوب ما باشد!
۱. انیمیشنهای ورود و خروج (Enter/Exit Animations)
یکی از کاربردیترین سناریوها، صفحاتی مثل ورود و ثبتنام (Sign In / Sign Up) است. اگر در این صفحات وکتورها، المانهای گرافیکی انتزاعی یا انیمیشنهای موشن (مثلاً با Framer Motion) دارید و میخواهید کاربر با رفتن از فرم Sign In به Sign Up، دوباره اجرای کامل انیمیشنها و ریست شدن حالتها را تجربه کند، template.tsx گزینه انتخابی شماست.
۲. لاگبرداری و Analytics بر اساس بازدید صفحه
اگر نیاز دارید با هربار ورود کاربر به هرکدام از صفحات فرعی، یک useEffect اجرا شده و اطلاعاتی مثل Page View ارسال شود.
۳. ریست شدن فرمها یا Stateهای وابسته به Route
وقتی میخواهید با جابهجایی بین مسیرها، حالتهای ورودی کاربر کلاً پاک شوند.
نمونه کد عملی
برای تعریف پروپهای کامپوننت در ریاکت و نکست، استفاده از type ساختار تمیزتر و یکدستتری ایجاد میکند:
// app/auth/template.tsx
import { ReactNode } from 'react';
type TemplateProps = {
children: ReactNode;
};
export default function AuthTemplate({ children }: TemplateProps) {
return (
<div className="auth-container animate-fade-in">
{/* المان گرافیکی یا وکتور دارای انیمیشن که در هر تغییر مسیر دوباره اجرا میشود */}
<div className="vector-illustration" />
<main>{children}</main>
</div>
);
}
چرا باید با احتیاط از آن استفاده کرد؟
استفاده بیمورد از template.tsx به جای layout.tsx میتواند روی تجربه کاربری و عملکرد برنامه تأثیر منفی بگذارد:
-
افت فریم و انیمیشنهای اضافی: اگر المانهای سنگینی درون Template قرار دهید، با هر جابهجایی کوچک فریمها مجدداً ساخته میشوند که میتواند باعث Perceived Latency (حس کندی) شود.
-
از دست رفتن Scroll Position یا حالتهای داخلی: فرمها یا کامپوننتهایی که انتظار دارید حالتشان حفظ شود، با هر Navigation کلاً ریست خواهند شد.
خلاصه تصمیمگیری
-
اگر میخواهید هدر، فوتر، Sidebar یا Stateها ثابت بمانند ➔ از
layout.tsxاستفاده کنید. -
اگر میخواهید با هر تغییر مسیر، انیمیشنها مجدداً اجرا شده و Effectها ریست شوند ➔ از
template.tsxاستفاده کنید.
