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
      Parallel Routes

      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.

      Parallel Routes


      
      Parallel routes offer a powerful way to render multiple pages either simultaneously or conditionally within the same layout.

      Conditional Rendering


      
      For example, in an admin dashboard, you might need to display both the team and analytics pages simultaneously:
      
      The usage of parallel routes involves naming folders with an @ prefix, such as @team and @analytics in the above example.
      
      These slots are passed as props to the shared parent layout. In the example, app/layout.js receives the @team and @analytics slots and renders them in parallel with children:
      // app/layout.js
      export default function Layout({ children, team, analytics }) {
      return (
      <>
      {children}
      {team}
      {analytics}
      </>
      )
      }
      
      Note: From above image, you can also see that the children prop is essentially an implicit slot, where app/page.js is equivalent to app/@children/page.js.
      
      Playground

      
      
      
      Besides rendering them simultaneously, you can also conditionally render them:
      
      In this example, the layout checks the user's role: if the role is admin, it shows the admin page; if not, it shows the user page. This approach keeps the code completely separate.

      Independent Route Handling


      
      Parallel routes allow you to define independent error handling and loading UI for each route:
      
      

      Tab Groups


      
      Note that when we refer to team and analytics, we still call them "pages" because they use page.js just like normal pages. Additionally, they can have sub-pages. For example, under @analytics, we can add two sub-pages: /page-views and /visitors:
      
      
      Parallel routes do not affect the URL, so /@analytics/page-views/page.js corresponds to /page-views, and /@analytics/visitors/page.js corresponds to /visitors. You can navigate to these routes:
      // app/layout.tsx
      import type { Metadata } from 'next';
      import { Inter } from 'next/font/google';
      import { Header } from '@/components/header';
      import { SiteFooter } from '@/components/site-footer';
      import '@/styles/globals.css';
      
      const inter = Inter({ subsets: ['latin'] });
      
      export const metadata: Metadata = {
      title: 'Create Next App',
      description: 'Generated by create next app',
      };
      
      export default function RootLayout({
      children,
      analytics,
      }: {
      children: React.ReactNode;
      analytics: React.ReactNode;
      }) {
      return (
      <html lang="en">
      <body className={inter.className}>
      <div className="flex min-h-screen flex-col">
      <Header />
      <main className="flex-1">
      {children}
      {analytics}
      </main>
      <SiteFooter />
      </div>
      </body>
      </html>
      );
      }
      
      When navigating to these sub-pages, the content of the sub-page replaces /@analytics/page.js and is injected into the layout as props, as shown below (Try clicking Views and Visitors and see the result):
      
      This means each slot can have its independent navigation and state management, like a mini-application. This feature is useful for building complex applications such as dashboards.

      Summary

      • Splitting a single layout into multiple slots makes code easier to manage, especially for team collaboration.
      • Each slot can define its loading UI and error state. For instance, if a slot loads slowly, you can add a loading effect without affecting the rendering and interaction of other slots. If an error occurs, only that specific slot shows an error message, improving user experience.
      • Each slot can have independent navigation and state management, allowing rich functionality. For example, under the @analytics slot, you can create sub-pages like /page-views and /visitors, allowing the same slot area to display different content based on the route.
      
      You might ask, "Can I just split components and handle loading and error states myself? Can I handle sub-routes on my own?"
      Of course, you can do that if you don't mind the extra complexity.
      Note: When using parallel routes, hot reloading might occasionally cause errors. If you encounter any inexplicable issues, try restarting npm run dev or building the production version to check the effect.
      

      default.js


      
      Now, you may have noticed that when clicking the Visitors link to navigate to the /visitors route and refresh the page. You will see a 404 error:
      
      Why is this happening? Why can we navigate from the home page to /visitors correctly, but directly accessing /visitors results in a 404 error?
      
      When navigating from the home page to /visitors, Next.js tracks the state of each slot. The content displayed in the specific slot depends on the type of navigation:
      • For soft navigation (e.g., using <Link />), Next.js performs partial rendering, changing the slot content to match the current URL, while maintaining the previous state for unmatched slots.
      • For hard navigation (e.g., refreshing the browser), Next.js cannot determine the state of unmatched slots and renders a 404 error.
      
      In simple terms, accessing /visitors causes a mismatch between slot content and the current URL, which should render a 404 error. However, for better user experience, Next.js maintains the previous state of unmatched slots during soft navigation and avoids rendering a 404 error. In other words, when accessing /visitors, it reads not only app/@analytics/visitors/page.js but also app/visitors/page.js.
      
      When a hard navigation occurs, Next.js renders the content defined in default.js for unmatched slots. If default.js is not defined, it renders a 404 error.
      Create app/default.js:
      export default function Page() {
      return (
      <div className="container flex max-w-[64rem] flex-col items-center gap-4 text-center px-14">
      <h1 className="text-2xl text-red-500">Hello, App default!</h1>
      </div>
      );
      }
      
      
      Now the effect is as follows: