Teachnique
      CourseRoadmaps
      Login

      Introduction

      Project SetupCLI

      IntroductionAPP RouterTemplateLoading UIError Handling404 Page

      Linking and Navigating

      Dynamic RoutesRoute groupsParallel RoutesIntercepting Routes

      Route handlersCacheCommon Questions

      Middleware

      CSRSSR & SSGISR

      React Server ComponentsServer-Side Rendering

      SuspenseStreaming

      Server & Client ComponentServer vs. Client ComponentBest Practices

      Server-Side Rendering Strategies

      Data Fetching & Caching & RedirectThird-Party Request Libraries on the Server SideBest Practices

      Request MemoizationData CacheFull Route CacheRouter Cache

      Server Actions IFormServer Actions IIOptimistic Update

      Tailwind CSSCSS-in-JSSass

      Environment VariablesAbsolute Imports& Module Path AliasesRoute Segment Config

      Image & LCPImage IImage IIOptimizing IOptimizing II

      Next FontFont ParameterApply Styles

      Feedback

      Submit request if you have any questions.

      Course
      Template

      Next.js Mastery: From Fundamentals to Full-Stack

      Unlock the power of Next.js with this comprehensive course! Starting with the basics, you’ll learn essential skills such as routing, data fetching, and styling. Progress through practical projects, including building your own React Notes app, to gain hands-on experience. Dive into the source code to understand the inner workings and core principles of Next.js. Perfect for developers with a basic knowledge of React and Node.js, this course ensures you’ll be ready to create high-performance full-stack applications efficiently. Join us and master Next.js, backed by industry experts and a supportive learning community.

      Template


      
      Templates function similarly to layouts in web development, especially in React, by being passed to each child layout or page. However, unlike layouts, templates do not retain state.
      
      When navigating between routes that use the same template, a new instance of each child is created. This results in component instances remounting and the DOM elements being recreated, thus not retaining state. This might seem abstract, so let’s break it down with an example.
      
      To define a template, create a file named template.js and export a React component that receives a children prop. For instance:
      
      Create a template.js file in the app directory:
      // app/template.js
      export default function Template({ children }) {
      return <div>{children}</div>
      }
      This is similar to using layouts, but with the crucial difference in state retention. If both template.js and layout.js are in the same directory, the structure will be:
      <Layout>
      {/* The template requires a unique key */}
      <Template key={routeParam}>{children}</Template>
      </Layout>
      Here, the layout wraps the template, and the template wraps the page.
      
      Templates are more suitable than layouts in certain cases:
      • Functions that depend on useEffect and useState, like recording page visits or resetting user feedback forms.
      • Modifying default framework behavior, such as showing fallback UI on each route change using Suspense.
      For specific scenarios where templates are appropriate, refer to the article "What is the use of template.js in Next.js v14?"
      

      Layouts VS. Templates


      
      To illustrate the differences, here’s a project directory setup:
      app
      └─ dashboard
      ├─ layout.js
      ├─ page.js
      ├─ template.js
      ├─ about
      │ └─ page.js
      └─ settings
      └─ page.js
      Code for dashboard/layout.js:
      'use client';
      import { useState } from 'react';
      import Link from 'next/link';
      
      export default function Layout({ children }) {
      const [count, setCount] = useState(0);
      return (
      <div className="flex min-h-screen flex-col space-y-6">
      <div className="container grid flex-1 gap-6 md:grid-cols-[200px_1fr]">
      <aside className="hidden w-[200px] flex-col justify-between rounded-lg border border-black m-4 p-4 backdrop-blur-[1.5px] md:flex">
      <div className="space-y-2 flex flex-col items-center">
      <Link
      href="/dashboard/about"
      className="px-14 border border-black rounded-md"
      >
      About
      </Link>
      <br />
      <Link
      href="/dashboard/settings"
      className="px-12 border border-black rounded-md"
      >
      Settings
      </Link>
      <h1>Layout count: {count}</h1>
      <button
      className=" px-11 border border-black rounded-md items-center justify-center bg-zinc-300 mt-2"
      onClick={() => setCount(count + 1)}
      >
      Increment
      </button>
      </div>
      </aside>
      <main className="flex w-full flex-1 flex-col">{children}</main>
      </div>
      </div>
      );
      }
      Code for dashboard/template.js:
      'use client';
      
      import { useState } from 'react';
      
      export default function Template({ children }) {
      const [count, setCount] = useState(0);
      return (
      <div className="m-4 w-full h-full border border-black rounded-lg flex flex-col items-center justify-center">
      <h1>Template count: {count}</h1>
      <button
      className=" px-11 border border-black rounded-md items-center justify-center bg-zinc-300 mt-2"
      onClick={() => setCount(count + 1)}
      >
      Increment
      </button>
      {children}
      </div>
      );
      }
      Code for dashboard/page.js:
      export default function Page() {
      return (
      <div className="flex items-center justify-center mt-40">
      <h1 className="text-3xl">Hello, Dashboard!</h1>
      </div>
      );
      }
      
      Code for dashboard/about/page.js:
      export default function Page() {
      return (
      <div className="flex items-center justify-center mt-40">
      <h1 className="text-3xl">Hello, About!</h1>
      </div>
      );
      }
      Code for dashboard/settings/page.js:
      export default function Page() {
      return (
      <div className="flex items-center justify-center mt-40">
      <h1 className="text-3xl">Hello, Settings!</h1>
      </div>
      );
      }
      

      Try it out


      
      
      When you click the Increment buttons, the counts will increase. However, switching routes (About or Settings) will show that the Layout count remains unchanged, while the Template count resets to 0. This demonstrates state retention.
      
      Note: Refreshing the page will reset both Layout and Template counts to 0.