- Always use lowercase for folder names.
- By default, all components are server components.
- They can:
- Run tasks like fetching data.
- Read files.
- They cannot:
- Use React Hooks.
- Handle user interactions.
- Add
'use client'at the top to create a client component. - They can:
- Use React Hooks.
- Handle user interactions.
- They cannot:
- Run server tasks or read files.
- Routes are defined by files and folders in the
appdirectory. - Files named
page.tsxorpage.jsrepresent routes. - Folders define URL path segments.
- Create a folder inside another folder to create nested routes.
- Add a
page.tsxfile in the nested folder.
- Use brackets
[ ]for dynamic routes, e.g.,[productId]. - Access the route parameters with
params.
- Combine nested and dynamic routing:
- Example:
[productId]/reviews/[reviewId].
- Example:
- Use
[...slug]to capture all URL segments after a certain point. - For optional segments, use
[[...slug]].
- Create a
not-found.tsxfile in theappfolder to customize the 404 page. - Use the
notFound()function for conditional redirection.
- Prefix folder names with
_or%5Fto make them private. - Private folders are excluded from routing.
- A
layout.tsxfile wraps components with shared elements like headers or footers. - Place it in a folder to apply to all child routes.
- Create a
layout.tsxinside specific folders for localized layouts.
- Similar to layouts, but templates remount shared components.
- Use templates when shared components need to reinitialize on route changes.
- Add metadata for better SEO using:
- A static
metadataobject. - A dynamic
generateMetadatafunction.
- A static
- Layout metadata applies to all child routes.
- Page metadata overrides layout metadata for the same properties.
- Define metadata for dynamic routes, e.g.,
[productId]. - Use either
metadataorgenerateMetadata, not both.
absolute: Ignores root layout templates.default: Used if no title is defined in child pages.template: Combines with child titles, e.g.,"%s | My App".
- Use the
Linkcomponent for navigation. - Use
replaceto replace the current history entry.
- Use
useRouterfor actions like:router.push("/")router.back()router.refresh()
- Add a
loading.tsxfile to display a loading state for routes. - Great for showing spinners or skeletons during data fetching.
- Add an
error.tsxfile to handle errors in specific routes. - Use
resetin the error file for recovery options like "Try Again".
- Place
error.tsxfiles at different levels for granular error management. - Errors bubble up to the nearest
error.tsx.
- Private Folders: Separate UI logic from routing logic.
- Layouts: Maintain shared elements across routes.
- Templates: Reinitialize shared components when switching routes.
- Error Pages: Isolate errors to specific segments.
- Loading States: Enhance user experience during data fetching.
- Error Boundary Location: An
_error.tsx_file handles errors for all its child segments. - Error Boundary Limitation: If the error boundary resides inside a layout, it does not catch errors for the layout itself.
- Solution: To handle layout errors, move the
_error.tsx_file to the parent folder of the layout. This prevents crashing and displays error messages.
- Create an
_error.tsx_file inside the[productId]folder. - Simulate an error in the
[productId]/page.tsxfile:- Use a
getRandomIntfunction to generate a random number (0 or 1). - If the number is
1, throw an error to demonstrate error handling.
- Use a
- Ensure the
page.tsxfile is client-side rendered to support this behavior.
- Definition: Parallel routes are defined using "slots" in Next.js.
- Naming Convention: Use the "@" prefix (e.g.,
@folderName) for slot folders. - Behavior: Slots act as props in the corresponding
_layout.tsx_file. - Children Prop: The
childrenprop is also considered a slot.
- In a complex dashboard route, define three slots:
@revenue,@notification, and@users. - Pass them to the layout as props with their folder names.
- Each slot manages its own loading and error states independently.
- Independent Route Handling:
- Each slot has isolated loading and error states.
- Issues in one slot do not affect others.
- Sub-navigation:
- Slots can function as mini-applications with their own state and navigation.
- Ideal for complex dashboards.
-
Navigation from UI:
- Slots retain their state even when navigating between different sections.
- For example, navigating from
@notificationto its child folder (@notification/archived) does not impact other slots.
-
Page Reload:
- Upon reload, unmatched slots require a
_default.tsx_file to display default content. - Missing
_default.tsx_results in a 404 error.
- Upon reload, unmatched slots require a
- Display different content based on conditions (e.g., user authentication).
- Restart Note: Restart the server to ensure conditional routes function properly.
- Stops default routing behavior to present alternative views while preserving route context.
- Usage: Create a folder at the same level as the route with the same name but prefixed by
(.)(e.g.,(.)f2).
- (.): Matches the current level.
- (..): Matches one level above.
- (...): Matches the root directory.
- Combine both parallel and intercepting routes, such as in a
photo-feedroute. - Allows seamless integration of multiple features.
- Used for creating custom RESTful endpoints.
- Handlers execute server-side, keeping sensitive data secure.
- Conflict Resolution: If
_route.ts_and_page.tsx_exist in the same folder, move_route.ts_to anapisubfolder.
-
CSR (Client-Side Rendering):
- Renders content in the browser.
- Increases initial load time and reduces SEO benefits.
-
SSR (Server-Side Rendering):
- Renders HTML on the server.
- Improves SEO and reduces initial load time.
-
Hydration:
- Combines server-rendered HTML with client-side JavaScript.
-
Use Suspense SSR for:
- HTML streaming on the server.
- Selective hydration on the client.
-
Implement Code Splitting:
- Load components on demand to optimize performance.
This is a detailed explanation of React Server Components (RSC) and their integration with Next.js App Router, including the distinctions between server and client components, rendering strategies, and data-fetching techniques.
RSC enables dual-environment execution, allowing applications to combine the strengths of both server and client rendering:
- Server Components: Handle data fetching, static rendering, and server-specific tasks (e.g., database access).
- Client Components: Render interactive UI elements and manage browser APIs/events.
- Reduced bundle size.
- Enhanced security with server-side rendering.
- Improved SEO and performance (e.g., initial page load, FCP).
- Efficient streaming and caching for smoother user experiences.
- Default behavior: All components in Next.js are server components unless specified otherwise.
- Execution: Logs appear in the server terminal.
- Limitations: Cannot use React hooks (e.g.,
useState,useEffect) or browser-specific events (e.g.,onClick).
- Require
"use client"directive. - Can access browser APIs and handle interactivity.
- Pre-rendered on the server for SEO benefits but hydrate on the client.
Best Practice: Place client components as leaf nodes to minimize performance overhead.
-
Static Rendering:
- HTML is generated during the build process.
- Ideal for pages with static content (e.g., blogs, marketing pages).
- Prefetching is supported for faster navigation.
- Cached and CDN-served for performance.
-
Dynamic Rendering:
- HTML is generated at request time for each user.
- Suitable for personalized content (e.g., user-specific dashboards).
- Automatically activated in Next.js when dynamic functions like
cookies(),headers(), orsearchParamsare used.
-
Streaming:
- Progressive UI rendering in chunks.
- Enhances user experience by displaying partial content immediately.
- Useful for slow data-fetching scenarios.
- Recommended for efficiency and caching.
- Data resides on the server, reducing client-side computation.
- Features like Request Memoization optimize repeated requests within a single render tree.
- Requires third-party libraries like TanStack Query for caching and revalidation.
- Can invoke server-side route handlers for optimized API calls.
-
Opting Out of Caching:
- Use
{ cache: "no-store" }in fetch requests to bypass caching. - Dynamic functions disable caching for all subsequent requests in a file.
- Use
-
Request Memoization:
- Prevents redundant requests for the same data within the React tree.
- Improves performance and avoids unnecessary prop drilling.
- Certain packages (e.g.,
react-slick) may have compatibility issues with server components. Resolve this by isolating them in client components.
- Server components can only render when wrapped by client components.
- This approach ensures optimal use of server resources alongside client interactivity.
- Server-Only Package: Ensures components execute exclusively on the server.
- Client-Only Package: Prevents server-side usage of client-specific code.
If you'd like to explore further or need examples, feel free to ask!