Superfilter AI
Course Description
Level up your Next.js skills to build production-ready applications. Dive into advanced concepts like server actions, route slots, and data fetching strategies. Implement form authentication, protect routes with middleware, and optimize performance through caching and revalidation techniques. Create a full-stack application while exploring React 18+ features, database integration, and best practices for developing dynamic, responsive web apps.
This course and others like it are available as part of our Frontend Masters video subscription.
Preview
CloseLearn Straight from the Experts Who Shape the Modern Web
Your Path to Senior Developer and Beyond
- 200+ In-depth courses
- 18 Learning Paths
- Industry Leading Experts
- Live Interactive Workshops
Table of Contents
Introduction
Section Duration: 11 minutes
- Scott Moss begins the Intermediate Next.js course with an overview of the topics covered and a brief tour of the course repo and application that will be built. The code for the application can be found on the main branch in the repo or throughout the course notes.
- Scott walks through the instructions for cloning the repo and installing the project dependencies. The application's database will be SQLite hosted on Turso. Once an account and database are created in Turso, the TURSO_CONNECTION_URL and TURSO_AUTH_TOKEN environment variables can be added to the project.
Form Authentication Actions
Section Duration: 42 minutes
- Scott reviews some recent features added to React that are often thought to be developed by the Next.js team. These features are available in React 18+ and improve the developer experience and application performance.
- Scott talks through some key concepts for working with forms and form data in React and Next.js. Server Actions simplify form data handling by exposing a FormData object with the data sent to the server from the form.
- Scott creates server actions to handle authentication from the sign-up and sign-in forms. The actions are created in an actions directory outside the app directory. The registerUser action is then imported into the SignupForm component.
- Scott creates a SubmitButton component to submit the form and trigger the registerUser server action. Once a user is registered, the record in the database can be inspected by launching Drizzle Studio with the "npm run db:studio" command.
- Scott implements the sign-in form by adding the SubmitButton component and triggering the signinUser server action when the form is submitted. An error message for incorrect username and password combinations is also added to the UI. The current code can be found on the "step/1" branch.
Routing & Data Fetching
Section Duration: 1 hour, 24 minutes
- Scott introduces route slots, which are also called parallel routes. They enable simultaneous or conditional rendering of multiple pages or components within the same layout. This is beneficial for sections of an application that require dynamic content changes without navigating away from the page, like social media feeds or analytics dashboards.
- Scott creates route slots for the Events and RSVPs pages. This allows them to be used in the dashboard layout without requiring separate loading or error-handling logic.
- Scott adds default routes for each route slot to ensure something is returned if one of the slots is given a sub-route that isn't present in the other route slots.
- Scott introduces server-side data fetching and talks through a few common use cases. A utility function is created to get the current user, and a few other utility files are explained.
- Scott codes a utility function for getting the attendee count. It uses the Drizzle ORM to pull the data from the database and returns the total count. The count is then displayed on the dashboard home page.
- Scott fetches server data for the events and RSVPs. Utility functions are created for each to return the data from the database. The events and RSVPs are then displayed on their respective pages in the dashboard. The current code can be found on the "step/2" branch.
- Scott demonstrates per-request caching, which helps eliminate repeated database or server-side calls on a single request. To highlight this, the getCurrentUser utility function, which is called three times from the dashboard page, is wrapped in React's cache function. This reduces the number of invocations to one.
- Scott implements persistent caching for the RSVPs, events, and attendees. A third-party module that leverages React's caching along with memoization is imported and used as a wrapper just like the cache function. Revalidation tags are added so the cache can be revalidated at a later time.
- Scott creates loading spinners and handles page-specific errors. A loading spinner or any other UI element can be displayed by adding a loading.tsx file to the route. The same pattern can be used to handle errors with a errors.tsx file. The current code can be found on the "step/3" branch.
Active & Protected Routes
Section Duration: 22 minutes
- Scott enhances the application's UX by implementing active routes. This will highlight the current navigation item using the usePathname hook and applying active classes.
- Scott explains how middleware can be used to add route protection to the application. Middleware functions run on the edge, executing before the server processes cached content or matches routes. This allows the user to be redirected to the sign-in page if they aren't authenticated. Several other examples of middleware are shared, including conditional routing, managing cookies and headers, and CORS.
- Scott adds a middleware function to the application to protect the dashboard and root routes. For the dashboard route, the middleware will ensure the user is authenticated; otherwise, it redirects them to the sign-in page. Since there is no page for the root route, the middleware redirects to the dashboard. The current code can be found on the "step/4" branch
Advanced Server Actions & Revalidation
Section Duration: 41 minutes
- Scott discusses use cases for server actions that don't involve forms. Server actions can be integrated into other parts of an application, such as event handlers and React hooks. This allows for dynamic server-side operations responding to user interactions or lifecycle events.
- Scott codes a server action to create a new event. However, since the data is cached, a hard reload is required to view the newly created event. To fix this, the revalidateTag method is called to clear the events cache and immediately display the event. The current code can be found on the "step/5" branch
- Scott spends a few minutes answering questions about server actions. Questions include mixing tRPC and server actions and suspense vs. useTransition in React 19.
- Scott discusses additional strategies for revalidating cache manually and some of the ways Next.js will revalidate the cache for you.
- Scott implements the events page and creates a route to display an event by ID. The individual event page uses the params property to access the idea and load the details for the event. The behavior of the loading component with nested routes is also demonstrated in this lesson. The final code can be found on the "step/6" branch.
Wrapping Up
Section Duration: 8 minutes
- Scott wraps up the course by sharing some best practices and answering a question about strategies for limiting bundle size. He also shares some next steps and tips for getting better at building with Next.js.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops