The Road to Next
Read more about the course
This is not just a video course. Step by step, you will create your own starter project to immediately apply the knowledge you gain. Build and deploy a SaaS product, gaining practical experience with the tools and techniques used by industry professionals. I have put all the experience I have accumulated over the past years of work, both in employment and freelancing, into this course, and I hope it will help you achieve success.
This course is for those who want to reach a senior level, for those seeking an advanced course in React or backend development, for those wanting to transition from frontend to full-stack development, and for those who want to create real SaaS products. It's perfect for beginner developers looking to deepen their understanding of complex engineering principles, and for those who want to master advanced concepts in React and Next.js in the context of full-stack development.
So, ready to become a full-stack developer with me?
Let's get started :)
Technology Stack
Next.js 15
The most popular full-stack framework for React
Used by the largest companies worldwide, Next.js allows you to create high-quality web applications using the power of React components.
React 19
The most popular frontend framework
React allows building user interfaces from individual pieces called components. Create your React components and combine them into entire screens, pages, and applications.
Prisma
The next-generation TypeScript ORM
Prisma offers the best DX for your team to work with databases. Even complex aspects like connection pooling, caching, and real-time subscriptions become feasible.
Supabase
Serverless Postgres
Supabase is an open alternative to Firebase. Start your project with a Postgres database and add additional services as needed.
TypeScript
Type-safe JavaScript as the industry standard
Unlock the power of TypeScript: dive into a world where strict typing makes code more reliable. Gain confidence to tackle complex tasks.
Zod
TypeScript-based schema validation
Zod provides safe schema validation in TypeScript, reducing errors and maintaining data integrity through concise syntax and seamless integration with TypeScript.
Oslo
Vendor-neutral authentication
Oslo.js is a lightweight, typed authentication library offering support for JWT, OAuth2, password hashing, WebAuthn verification, and cryptographic tools for secure authentication.
Vercel
The best platform for deploying Next.js
Vercel is a cloud platform for quickly deploying and scaling modern web projects. Offering seamless integration with Next.js, Vercel is perfectly suited for this technology stack.
Tailwind
Industry standard for CSS styles
Tailwind CSS is a highly customizable utility-first CSS framework that simplifies the styling process by providing a comprehensive set of ready-to-use classes.
Shadcn/UI
Popular library of reusable components
Discover a collection of meticulously crafted components ready for seamless integration into your applications. The components are accessible, fully customizable, and open-source.
Watch Online The Road to Next
# | Title | Duration |
---|---|---|
1 | Welcome to The Road to Next | 06:56 |
2 | Software to create Software | 01:33 |
3 | Visual Studio Code (VSCode) | 02:32 |
4 | External Terminal (Optional) | 01:44 |
5 | Browser | 02:26 |
6 | Node | 02:53 |
7 | NPM | 02:02 |
8 | Manual setup in Next | 09:38 |
9 | JSX | 02:34 |
10 | Components | 03:22 |
11 | Props | 03:07 |
12 | Styling | 01:14 |
13 | Interactions | 02:28 |
14 | State | 03:01 |
15 | Composition | 03:34 |
16 | File Extraction | 01:07 |
17 | Outro | 01:48 |
18 | What are pitfalls? | 01:21 |
19 | Restarting Things | 02:22 |
20 | Wrong (Auto) Imports | 01:49 |
21 | npm install --force | 02:13 |
22 | Breaking Changes | 02:05 |
23 | create-next-app | 06:59 |
24 | Next 15 & React 19 | 02:53 |
25 | Exploring the Starter | 06:54 |
26 | Git & GitHub | 05:55 |
27 | Deploy | 04:18 |
28 | Exploring the finished Project | 09:30 |
29 | Script | 04:22 |
30 | Import Sort | 03:05 |
31 | Pages | 05:01 |
32 | Static and Dynamic Routes [B] | 05:06 |
33 | Link Components | 07:07 |
34 | Absolute Imports | 00:48 |
35 | Path Constants | 02:08 |
36 | Layout | 05:21 |
37 | Script | 02:22 |
38 | const Assertions | 04:06 |
39 | Tailwind CSS [C] | 04:45 |
40 | Tailwind CSS in Next | 08:26 |
41 | Conditional Style | 01:50 |
42 | Animations with Tailwind | 02:30 |
43 | SVGs | 02:15 |
44 | Setup [B] | 06:05 |
45 | Button | 04:40 |
46 | Card | 06:25 |
47 | Separator | 02:14 |
48 | Icons [C] | 05:17 |
49 | Theming | 02:22 |
50 | Heading | 04:34 |
51 | Header | 02:23 |
52 | Placeholder | 09:43 |
53 | Intro [B] | 01:48 |
54 | Extract | 04:35 |
55 | Modify | 04:26 |
56 | Reuse | 05:00 |
57 | Recap | 03:52 |
58 | Implementation | 13:16 |
59 | Data Fetching in Client Components | 09:45 |
60 | Characteristics of Client Components | 02:17 |
61 | Client-Server Boundary [C] | 05:04 |
62 | Client-Server Composition | 04:00 |
63 | Data Fetching in Server Components | 06:18 |
64 | SSR vs Server Components | 02:41 |
65 | Server-Side Rendering | 04:11 |
66 | Streaming | 03:41 |
67 | Suspense | 02:50 |
68 | Introduction | 00:54 |
69 | Loading Route | 03:21 |
70 | Error Route | 03:34 |
71 | Error Boundary (Optional) | 02:56 |
72 | Not Found Route | 02:00 |
73 | Nearest Boundary Bubbling | 03:11 |
74 | Connect to Database | 07:22 |
75 | Prisma | 01:30 |
76 | Prisma Schema | 09:29 |
77 | Seeding the Database | 07:31 |
78 | Prisma Studio | 01:54 |
79 | Prisma Client | 02:21 |
80 | Database Queries | 06:03 |
81 | ORM generated Types | 01:52 |
82 | Typed APIs (Optional) | 04:40 |
83 | Server Actions in Client Components | 08:58 |
84 | Server Actions in Server Components | 04:03 |
85 | redirect | 01:14 |
86 | Development vs Production | 01:38 |
87 | Router Cache | 05:36 |
88 | Full Route Cache | 01:41 |
89 | Static vs Dynamic Rendering | 06:59 |
90 | Time-Based Cache (ISR) | 02:45 |
91 | On-Demand Caching (ISR) | 02:56 |
92 | Where do we cache? | 01:02 |
93 | Request Memoization | 05:46 |
94 | Generate Static Params (Optional) | 03:19 |
95 | Recap | 02:19 |
96 | Create Form | 12:13 |
97 | Configuration over Composition (Software Craftsmanship) | 03:46 |
98 | Edit Form [B] | 13:05 |
99 | DRY with Abstractions (Software Craftsmanship) | 08:17 |
100 | Progressive Enhancement | 02:50 |
101 | useTransition | 03:34 |
102 | useFormStatus | 04:24 |
103 | useActionState | 03:34 |
104 | Form Validation | 06:10 |
105 | Form Reset | 03:27 |
106 | Error Handling | 06:41 |
107 | Field Errors in Forms | 07:29 |
108 | Premature Optimization (Software Craftsmanship) | 07:31 |
109 | Action Callbacks | 12:50 |
110 | Debugging (Software Craftsmanship) | 07:58 |
111 | Toast Feedback | 05:58 |
112 | Form Abstraction | 04:55 |
113 | Cookie API [B] | 05:12 |
114 | Set Cookie [B] | 02:19 |
115 | Read Cookie [B] | 09:58 |
116 | Pages vs Layouts | 04:59 |
117 | Layouts vs Templates | 05:15 |
118 | Schema Changes | 05:48 |
119 | Working with Currencies (Bonus) | 10:39 |
120 | Working with Dates (Bonus) | 10:07 |
121 | Close DatePicker (Controlled Component) | 03:47 |
122 | Reset DatePicker (key) | 04:25 |
123 | Exposing Callback Handlers | 03:22 |
124 | Reset DatePicker (useImperativeHandle) | 04:56 |
125 | Dropdown Component | 06:23 |
126 | Ticket Status (Read) | 04:21 |
127 | Ticket Status (Write) | 06:31 |
128 | Update Toast Feedback | 02:20 |
129 | Confirm Dialog | 07:32 |
130 | Confirm Dialog from Dropdown (Advanced) | 07:53 |
131 | Delete Toast Feedback | 06:42 |
132 | Development vs Production | 04:39 |
133 | Vercel | 04:18 |
134 | Environment Variables | 02:57 |
135 | Other Environment Variables | 03:37 |
136 | Lucia [B] | 07:30 |
137 | Paths for Authentication | 01:42 |
138 | Sign Up | 12:07 |
139 | Sign In | 06:22 |
140 | Regression Bugs (Software Craftsmanship) | 04:01 |
141 | Authentication Status | 06:02 |
142 | Sign Out | 09:23 |
143 | Header (Server Component) | 04:42 |
144 | Header (Client Component) | 03:08 |
145 | The Authentication Flicker | 06:50 |
146 | One-to-Many Relation | 09:25 |
147 | Referential Actions | 02:37 |
148 | Non-Nullable Relation | 03:15 |
149 | Relation Queries | 02:21 |
150 | Exclude Sensitive Information | 03:12 |
151 | Protected Routes | 08:05 |
152 | Ownership | 05:36 |
153 | Protected APIs | 08:16 |
154 | Protected UI | 02:20 |
155 | All Tickets vs My Tickets | 04:34 |
156 | Sidebar | 09:52 |
157 | Authenticated Sidebar | 03:52 |
158 | Breadcrumbs | 06:11 |
159 | Tabs | 07:40 |
160 | Active Path (Fastest Levenshtein) | 08:34 |
161 | Account Dropdown | 04:34 |
162 | Route Groups | 03:09 |
163 | Private Folders | 05:33 |
164 | useSearchParams | 07:41 |
165 | searchParams [B] | 05:32 |
166 | Debounce Requests | 01:55 |
167 | Sort | 10:51 |
168 | Typed Search Params [B] | 08:05 |
169 | useQueryState | 09:53 |
170 | useQueryStates | 06:41 |
171 | Composite Key | 02:29 |
172 | Mediator Components | 06:19 |
173 | URL State | 10:50 |
174 | Offset-Based Pagination | 03:55 |
175 | Metadata in Pagination with Prop Drilling | 07:30 |
176 | Database Transactions | 02:09 |
177 | Interplay between Interactions (UX) | 06:13 |
178 | Dynamic Page Size | 03:24 |
179 | Route Handler | 05:36 |
180 | Route Params in Route Handler [B] | 03:40 |
181 | Search Params in Route Handler | 05:43 |
182 | Intro (with Challenge) | 01:38 |
183 | Many-to-One Relation | 06:25 |
184 | Read Comments | 10:53 |
185 | Create Comment | 11:24 |
186 | Delete Comment | 14:42 |
187 | Sequential Data Fetching | 08:06 |
188 | Parallel Data Fetching | 06:14 |
189 | Explicit Client Components | 10:36 |
190 | Implicit Client Components | 06:25 |
191 | Hydration Mismatch | 03:01 |
192 | Async Client Components | 02:29 |
193 | Client-Server Boundary | 01:33 |
194 | Client-Server Composition | 08:31 |
195 | “use client”; | 04:45 |
196 | “use server”; | 03:16 |
197 | Continuous Offset-Based Pagination | 06:50 |
198 | Initial State | 02:35 |
199 | Sliding Window | 02:59 |
200 | Client-Side State: Remove Comment | 06:03 |
201 | Client-Side State: Add Comment | 10:08 |
202 | TypeScript Generics (Bonus) | 02:45 |
203 | Delete Feedback (Toast) | 09:09 |
204 | Delete Feedback (Button) | 04:34 |
205 | Cursor-Based Pagination (Timestamp) | 05:58 |
206 | Cursor-Based Pagination (Unique ID) | 04:00 |
207 | Deliberate Over-Fetching | 03:53 |
208 | TypeScript Generics (Bonus) | 04:42 |
209 | React Query Provider | 05:05 |
210 | useInfiniteQuery | 07:47 |
211 | initialData | 05:36 |
212 | Refetch (Option 1) | 03:19 |
213 | Invalidate Query (Option 2) | 02:15 |
214 | Infinite Scroll | 04:50 |
215 | Custom Domain | 09:53 |
216 | 001 - The Plan | 04:39 |
217 | 002 - Forgot Password (Public Page) | 06:43 |
218 | 003 - Password Reset Token | 02:49 |
219 | 004 - Password Reset Link | 09:12 |
220 | 005 - Reset Password (Public Page) | 10:00 |
221 | 006 - Reset Password (Public Page) | 04:53 |
222 | 007 - Change Password (Protected Page) | 08:26 |
223 | 008 - Many vs One Password Reset Token (Discussion) | 03:30 |
224 | 009 - Render Emails | 06:23 |
225 | 010 - Preview Emails | 03:34 |
226 | 011 - Resend | 03:44 |
227 | 012 - Custom Email Domain | 05:19 |
228 | 013 - Send Emails | 05:48 |
229 | 014 - Resend Dashboard | 02:16 |
230 | 015 - Why a Queue_ | 03:25 |
231 | 016 - Inngest | 03:40 |
232 | 017 - Receive Events with Functions | 05:23 |
233 | 018 - Send Events | 04:58 |
234 | 019 - Recap | 02:13 |
235 | 020 - Type-Safe Events | 02:25 |
236 | 021 - Retries | 05:39 |
237 | 022 - Inngest + Vercel (Integration) | 03:24 |
238 | 023 - Explore Inngest | 00:36 |
239 | 024 - Is Verified Email | 03:18 |
240 | 025 - Redirect if not Verified | 02:04 |
241 | 026 - Email Verification Token | 02:33 |
242 | 027 - Generate Random Code | 01:30 |
243 | 028 - Email Verification Code | 04:24 |
244 | 029 - Verify Email with Code | 04:26 |
245 | 030 - Verify Email with Code | 04:56 |
246 | 031 - Verify Email with Code | 06:03 |
247 | 032 - Fine-Grained Authorization | 07:42 |
248 | 033 - Send Email Verification | 05:20 |
249 | 034 - Queue Email Verification | 05:41 |
250 | 035 - Resend Verification Email | 06:54 |
251 | 036 - Many-to-Many, Users-to-Organizations | 08:38 |
252 | 037 - Read Organizations | 06:30 |
253 | 038 - Never Trust the Client, Trust the Server | 02:52 |
254 | 039 - Do not Over-Fetch ... | 03:42 |
255 | 040 - ... but keep the information you need | 02:11 |
256 | 041 - Redirect if no Organization ... | 02:09 |
257 | 042 - ... but do not introduce Regression Bugs (Software Craftsmanship) | 05:17 |
258 | 043 - Require Organization during Onboarding | 05:16 |
259 | 044 - Create More Organization | 05:41 |
260 | 045 - Manage Organization | 04:18 |
261 | 046 - One-Way Relation and Referential Integrity | 08:07 |
262 | 047 - Switch Organization (Idempotent Operation) [C] | 13:16 |
263 | 048 - Switch Organization (Idempotent Operation) [C] | 02:22 |
264 | 049 - Investigating (Software Craftsmanship) | 03:22 |
265 | 050 - Compound Key | 02:46 |
266 | 051 - Require Default Organization | 05:01 |
267 | 052 - Require Default Organization | 05:58 |
268 | 053 - Require Default Organization | 08:09 |
269 | 054 - Impossible States (Interactive Transactions) | 05:51 |
270 | 055 - Delete Organization | 09:14 |
271 | 056 - Client-Side Refresh | 03:33 |
272 | 057 - Limited Access | 03:18 |
273 | 058 - Read Memberships | 08:32 |
274 | 059 - Delete Membership | 08:42 |
275 | 060 - Leave Organization | 02:40 |
276 | 061 - Database Schema | 02:56 |
277 | 062 - Protected Admin Routes | 09:00 |
278 | 063 - Protected Admin UI | 03:51 |
279 | 064 - Protected Admin API | 03:25 |
280 | 065 - Protected Admin API | 11:29 |
281 | 066 - Change Role | 08:21 |
282 | 067 - Actual Use Case Tickets belong to Organizations | 03:00 |
283 | 068 - Create Ticket in Organization | 06:36 |
284 | 069 - Read Tickets by Organization | 10:16 |
285 | 070 - Manage Permissions | 08:56 |
286 | 071 - Authorize based on Permission (1) | 07:54 |
287 | 072 - Authorize based on Permission (2) | 09:49 |
288 | 073 - Do not trust the UI | 01:38 |
289 | 074 - Database Model | 03:23 |
290 | 075 - Unique Constraints | 01:16 |
291 | 076 - Read Invitations | 06:35 |
292 | 077 - Read Invitations | 05:30 |
293 | 078 - Invite by Email | 07:20 |
294 | 079 - Invitation Token & Link | 06:00 |
295 | 080 - Invitation Email | 03:19 |
296 | 081 - Queue Invitation | 03:43 |
297 | 082 - Queue and Send Invitation | 02:04 |
298 | 083 - Accept Invitation Strategies | 03:45 |
299 | 084 - Accept Invitation as User | 06:57 |
300 | 085 - Accept Invitation as Anonymous [C] | 09:38 |
301 | 086 - Revoke Invitation | 06:53 |
302 | 087 - Amazon AWS S3 | 04:13 |
303 | 088 - Amazon AWS IAM | 05:26 |
304 | 089 - AWS SDK for JavaScript | 03:06 |
305 | 090 - Tickets with Attachments | 05:07 |
306 | 091 - Upload Files | 06:37 |
307 | 092 - File Validation | 04:59 |
308 | 093 - Store Files in Amazon S3 | 06:27 |
309 | 094 - List Attachments | 02:17 |
310 | 095 - Delete Attachments from Database | 05:22 |
311 | 096 - Delete Files from Amazon S3 | 05:01 |
312 | 097 - Synchronize AWS S3 with Database | 03:23 |
313 | 098 - Download Files with Presigned URLs | 09:13 |
314 | 099 - From Files to Folders | 03:17 |
315 | 100 - Custom Hook Extraction | 05:13 |
316 | 101 - Variable Extraction | 02:27 |
317 | 102 - Component Extraction | 02:58 |
318 | 103 - Render Prop Component | 06:14 |
319 | 104 - Polymorphic Relationship | 04:43 |
320 | 105 - Read Polymorphic Relations | 05:11 |
321 | 106 - Create a Polymorphic Relation | 10:35 |
322 | 107 - Type Guards in TypeScript | 03:55 |
323 | 108 - Helper Functions | 01:32 |
324 | 109 - Delete a Polymorphic Relation | 07:13 |
325 | 110 - Sign a Polymorphic Relation | 04:30 |
326 | 111 - Intro (Challenge) | 02:30 |
327 | 112 - Polymorphic Comments | 09:09 |
328 | 113 - Limits of the Client-Server Boundary (Discussion) | 02:52 |
329 | 114 - N+1 Problem (Discussion) | 02:32 |
330 | 115 - Nested Fetch | 06:53 |
331 | 116 - Invalidate Client-Side Cache | 05:07 |
332 | 117 - Isomorphic Components (Discussion) | 04:23 |
333 | 118 - Use Case for Layer(s) | 04:30 |
334 | 119 - Service Layer | 03:35 |
335 | 120 - Descriptive Layers | 01:59 |
336 | 121 - The Case for Barrel Files | 03:02 |
337 | 122 - Error Handling across Layers | 05:12 |
338 | 123 - Reuse Schema | 02:19 |
339 | 124 - Reuse Service | 04:23 |
340 | 125 - Service Layer to Data Layer | 03:31 |
341 | 126 - API Layer to Data Layer | 03:10 |
342 | 127 - Dynamic Include Statement | 04:00 |
343 | 128 - Function Overloads (Discussion) | 08:30 |
344 | 129 - Why DTOs | 01:40 |
345 | 130 - Implement DTO | 03:27 |
346 | 131 - Usage DTO (Create Attachments) | 02:45 |
347 | 132 - Usage DTO (Delete Attachment) | 02:29 |
348 | 133 - Usage DTO (Sign Attachment) | 03:05 |
349 | 134 - Usage DTO (Create Comment) | 03:21 |
350 | 135 - Ticket-to-Ticket Relations | 01:23 |
351 | 136 - List Ticket References | 03:42 |
352 | 137 - Connect Ticket Reference | 06:08 |
353 | 138 - Disconnect Ticket Reference | 05:46 |
354 | 139 - Embed Ticket Reference by ID | 05:30 |
355 | 140 - Organization-Level Creadentials | 03:46 |
356 | 141 - Create Credential | 06:03 |
357 | 142 - Show Once, Copy Secret | 03:16 |
358 | 143 - Obfuscate Secrets | 03:19 |
359 | 144 - Protected API | 02:13 |
360 | 145 - Bearer Authorization | 07:45 |
361 | 146 - Exclude Sensitive Information (Discussion) | 03:20 |
362 | 147 - Timing Attack | 06:33 |
363 | 148 - Enumeration Attack | 02:30 |
364 | 149 - Throttling Token Generation | 04:36 |
365 | 150 - Client-Side Guardrails Preventing UI-Level Misuse | 03:52 |
366 | 151 - Server-Side Guardrails Stricter Validation | 03:45 |
367 | 152 - Injection & Sanitization (Discussion) | 02:52 |
Similar courses to The Road to Next

The Complete Guide to Advanced React Patterns (2020)udemy

Build a Realtime App with React Hooks and GraphQLudemy

MERN Stack React, Socket io, Next.js Express,MongoDb, Nodejsudemy

MERN Stack From ScratchBrad Traversy

Build a Youtube CloneCode With Antonio

React Supabase Full Coursefireship.io

Build A Slack CloneCode With Antonio
