Example Curriculum
Available in
days
days
after you enroll
- Course Outline (5:40)
- What is Remix? (2:20)
- Why Remix? (6:36)
- Remix vs React Router (2:12)
- Intro to the Master Project (3:51)
- The Recipe Page & Optimistic UI (7:23)
- Finishing the Tour of the Master Project (5:38)
- Exercise: Meet Your Classmates and Instructor
- ZTM Plugin + Understanding Your Video Player
- Course Resources
- Set Your Learning Streak Goal
Available in
days
days
after you enroll
- Installing NodeJS (2:02)
- Creating a React Router Project (1:29)
- The Vite Config File (1:09)
- Upgrading Remix and Future Flags (3:32)
- Owning Your Entry Points (2:12)
- What are Routes? (2:48)
- Exercise: Identifying Server and Client Components in Remix Routes
- Solution
- Let's Have Some Fun (+ More Resources)
Available in
days
days
after you enroll
- An Explanation of New Imports
- Nested Routing (6:31)
- Exercise: Nested Routing in Remix
- Solution
- The Root Route (3:15)
- Exercise: Understanding Matched Routes with useMatches
- Solution
- Remix's Special Components (3:41)
- The Link API (3:05)
- Adding Style with Links (7:13)
- Exercise: Utilizing the links Route Export in Remix
- Solution
- Techniques for Component-Level CSS (7:44)
- Setting Up Tailwind (3:38)
- Using Tailwind - Part 1 (4:26)
- Using Tailwind - Part 2 (5:45)
- Using Tailwind - Part 3 (5:09)
- Unlimited Updates
Available in
days
days
after you enroll
- What are Loaders? (9:34)
- Exercise: Remix Loaders
- Solution
- Pending UI (9:06)
- Exercise: Implementing Pending UI on Links in Remix
- Solution
- Why Load Before Route Transitions (9:43)
- Sharing Data Between Routes (3:53)
- Exercise: Revert the changes from the last lesson
- Errors and Error Boundaries (5:52)
- Exercise: Handling Errors with Error Boundaries in Remix
- Solution
- Installing Postgres with Docker (15:09)
- Setting Up Prisma with Postgres (7:15)
- Implement a New Life System
Available in
days
days
after you enroll
- Overview (2:25)
- Setting Up the Pantry Route (11:03)
- Redirects in Remix (7:04)
- Exercise: Experimenting with HTTP Status Codes
- Solution
- Setting Up the Pantry Database Tables (13:12)
- Seeding the Database (9:13)
- Database UI Tools (9:36)
- Loading Data into the Pantry UI (5:12)
- Creating a Model Abstraction (10:37)
- Building a Basic Shelf UI (10:53)
- Intro to HTML Forms (21:34)
- Exercise: Exploring Similarities Between HTML Forms and Anchor Tags in Remix
- Solution
- Enhancing the Search Bar with JavaScript (8:16)
- Exercise: The FormData Object
- Solution
- Creating Shelves (14:11)
- Enhancing the Create Shelf Button (8:09)
- Deleting Shelves (18:45)
- Handling Multiple Deletes (6:57)
- Introducing useFetcher (7:30)
- More Cases for useFetcher (2:05)
- Server State in Remix (4:27)
- Exercise: Understanding Concurrency in Remix
- Solution
- Editing Shelf Names (12:27)
- Validating Forms with Zod (18:44)
- Intro to Optimistic UI (9:19)
- Optimistically Deleting Shelves (12:56)
- Creating Shelf Items (7:21)
- Deleting Shelf Items (11:56)
- Optimistically Creating Shelf Items (21:45)
- Suppressing the Layout Effect Warning (4:23)
- Optimistically Deleting Shelf Items (8:17)
- Additional Enhancements (14:16)
- Course Check-In
Available in
days
days
after you enroll
- Overview (1:32)
- The User Model (7:40)
- The Login Route (10:10)
- Intro to Cookies (2:24)
- Setting Our First Cookie (3:41)
- Cookie Attributes (7:27)
- A Simple Auth Flow (6:20)
- Remix's Cookie Helper (5:04)
- Exercise: Cookies
- Solution
- Cryptographic Signatures (4:09)
- Signing Cookies (1:45)
- Signing Cookies in Remix (4:27)
- Sessions (3:42)
- Session Storage (4:02)
- Session Storage in Remix (7:10)
Available in
days
days
after you enroll
- Overview (2:45)
- What is Authentication (2:02)
- Overview of Magic Link Authentication (2:51)
- Magic Link Structure (1:51)
- Generating Magic Links (7:46)
- Updating the Login Route (3:57)
- Validation Route Overview (1:49)
- Parsing the Magic Link Payload (8:36)
- Validating the Expiration Time (3:09)
- Validating the Nonce (6:04)
- Finishing the Login (2:42)
- The Sign Up Form (8:12)
- The Sign Up Form Action (9:37)
- Signing Up for Mailgun (3:48)
- Setting Up the Mailgun Client (6:16)
- Sending the Magic Link Email (6:08)
- Showing the Check Email Message (2:19)
Available in
days
days
after you enroll
- Overview (2:52)
- Authorization Rules for the Login Page (2:26)
- Login Authorization Rule #1 (6:19)
- Login Authorization Rule #2 (1:06)
- Authorization Rules for the Pantry Page (5:54)
- Pantry Authorization Rule #1 (2:42)
- Pantry Authorization Rule #2 (1:40)
- Pantry Authorization Rules #3-4 (2:15)
- Pantry Authorization Rules #5-6 (3:43)
- Pantry Authorization Rule #7 (2:22)
- UI Updates Roadmap (2:15)
- Adding an Error Boundary (7:30)
- Hiding the App Nav Button (3:03)
- Creating a Logout Route (5:28)
Available in
days
days
after you enroll
- Overview (4:05)
- Revisiting the Remix Philosophy (3:28)
- Setting Up the Recipes Route (4:34)
- Setting Up the Recipe Database Tables (3:55)
- Updating the Seed Script (4:23)
- Recipe Page Components (1:44)
- The Recipes Loader (5:59)
- Rendering the Recipe List (4:19)
- Creating a Search Bar Component (7:46)
- Supporting Search in the Loader (2:09)
- The Create Recipe Form (4:51)
- Setting Up the Recipe Detail Route (4:44)
- Exercise: Exploring Dynamic Route Segments in Remix
- Solution
- Sorting the Recipes List (1:35)
- Preserving the Search Parameters (6:17)
- Recipe Link Pending UI (5:41)
- Exercise: Writing your own Hook to Delay the Pending UI
- Using Link Prefetch (8:19)
- Recipe Detail Route Overview (1:39)
- Overview of Step 1 - Creating an Input Component (6:40)
- Displaying the Name and Total Time (10:13)
- Rendering the Ingredients (7:24)
- Rendering the Instructions (6:30)
- Overview of Step 2 - Updating Recipes (1:03)
- Saving the Recipe Name, Total Time, and Instructions (8:32)
- FormData's getAll Function (4:01)
- Updating the validateForm Function (8:28)
- Updating the Ingredients (8:05)
- Creating New Ingredients (7:28)
- Addressing and Issue (4:08)
- Adding Error Messages to the UI (7:39)
- Exercise: Imposter Syndrome (2:55)
- Overview of Step 3 - Deleting Recipes and Ingredients (0:32)
- Deleting a Recipe (2:27)
- Deleting Ingredients (3:38)
- Authorization Rules for the Recipe Detail Route (1:50)
- Recipe Detail Authorization Rule #1 (2:55)
- Recipe Detail Authorization Rules #2-5 (2:07)
- Enhancement Overview (2:34)
- Overview of Step 1 - Saving Inputs on Change (1:19)
- Saving Recipe Inputs on Change (8:22)
- Creating an Ingredient Row Component (5:52)
- Saving Ingredient Inputs on Change (4:03)
- Persisting the Recipe Fetcher Data (6:50)
- Persisting the Ingredient Fetcher Data (5:06)
- Debouncing Form Inputs (2:06)
- Creating a Hook for Debouncing (7:03)
- Debouncing the Form Inputs (3:31)
- Overview of Step 2 - The Case for Optimistic UI in the Side Bar (2:01)
- Updating the Side Bar with useFetchers (5:46)
- Overview of Step 3 (3:39)
- Wiring up a Fetcher to Create New Ingredients (9:27)
- Creating a Hook for Optimistically Rendering Ingredients (5:17)
- Optimistically Rendering New Ingredients (4:58)
- Updating the Default Enter Key Behavior (4:14)
- Creating Mew Ingredients with the Enter Key (1:54)
- Focusing the Amount Input on Create (4:47)
- Optimistically Deleting Ingredients (3:43)
Available in
days
days
after you enroll
- Overview (1:22)
- Creating a File Input (3:26)
- The Urlencoded Content Type (5:35)
- The Multipart Content Type (5:29)
- Parsing Multipart Forms (1:26)
- Overview of Parsing Multipart Forms in Remix (5:16)
- Remix's Built-In Upload Handlers (3:47)
- Storing Images in the Public Directory (3:15)
- Writing the Image URL to the Database (3:09)
- Exercise: Implementing Custom File Upload Handler in Remix with Cloudinary Simulation
- Solution
Available in
days
days
after you enroll
- Overview (3:29)
- Updating the DB to Track Meal Plans (2:18)
- Modals in Remix (4:29)
- Setting up the Modal Route (4:59)
- Creating some Components for the Modal (5:25)
- Meal Plan Modal UI (5:43)
- Passing Context to the Outlet (4:46)
- Creating the Modal Action (5:22)
- The Update Meal Plan Action Case (6:18)
- Indicating which Recipes are in the Meal Plan (3:31)
- The Meal Plan Filter Button (7:00)
- The Meal Plan Filter Backend (2:26)
- Preserving the Search State when Filtering (5:17)
- Preserving the Filter State when Searching (3:48)
- Overview of Next Steps and Setting up the Grocery List Route (2:21)
- Defining the Grocery List Item Type (4:16)
- Building the Grocery List Item Component (6:16)
- Getting Started on the Grocery List Loader (6:16)
- Formatting the Missing Ingredients (3:35)
- Grouping Grocery List Items by the Ingredient Name (6:05)
- Rendering the Grocery List (2:35)
- Creating the Grocery List Route Action (4:28)
- Adding Grocery Items to the Pantry (6:20)
- The Grocery List Empty State (3:17)
- Clearing the Meal Plan (6:13)
Available in
days
days
after you enroll
- Overview (1:28)
- The PageLayout Component (4:05)
- Setting up the Settings Route (2:30)
- Intro to Resource Routes (2:38)
- MIME Types (5:45)
- Exercise: MIME Types
- Solution
- Overview of Customizing the Theme (2:33)
- Renaming the Resource Route (1:45)
- Controlling the Tailwind Theme with the Theme Resource Route (5:01)
- Building the Form to Change the Site Theme (3:49)
- Creating the Theme Cookie (2:08)
- The App Settings Route Action (4:04)
- The App Settings Route Loader (2:50)
- Fixing the Off-By-One Issue (5:19)
- Returning Dynamic CSS Based on the Theme Cookie (3:31)
Available in
days
days
after you enroll
- Overview (0:52)
- Redirecting the Home Page (1:17)
- The Discover Page UI (4:37)
- Discover Detail Page Setup (2:44)
- Discover Detail Page UI (3:06)
- Intro to Caching (1:47)
- Private vs Server Caches (3:09)
- Preview of Using the Browser Cache (3:41)
- Caching Vocabulary (2:35)
- The Default Browser Strategy (3:31)
- The No-Store Strategy (1:23)
- The Fixed-Time Strategy (1:21)
- The Cache-Busting Strategy (4:09)
- The Revalidate-Once-Stale Strategy (1:44)
- Etags (4:03)
- Responding to the If-None-Match Header (3:12)
- The Stale-While-Revalidate Strategy (4:21)
- Caching Full HTML Pages (2:28)
- Responding to If-None-Match on HTML Requests (5:39)
Available in
days
days
after you enroll
- Introduction to Testing (1:00)
- Setting Up Playwright (1:59)
- Writing our First Test (6:51)
- Creating Dynamic Routes (7:00)
- Implementing the Test Login Route (4:53)
- Testing a Typical Pantry Page Flow (7:17)
- Finishing up the Pantry Test (4:04)
- The Playwright UI (2:22)
- Creating a Delete User Test Endpoint (4:23)
- Deleting Test Users (1:41)
- Exercise: End-to-End Testing with Playwright
- Solution
Available in
days
days
after you enroll
Available in
days
days
after you enroll
Available in
days
days
after you enroll