1
Copyright 2023 Code with Mosh codewithmosh.com
2
Hi! I am Mosh Hamedani. I’m a software engineer with over 20
years of experience and I’ve taught millions of people how to code
and become professional software engineers through my YouTube
channel and coding school (Code with Mosh).
This PDF is part of my Next.js course where you will learn
everything you need to build full-stack applications with Next.js 13
and TypeScript.
https://codewithmosh.com
https://www.youtube.com/c/programmingwithmosh
https://twitter.com/moshhamedani
https://www.facebook.com/programmingwithmosh/
Copyright 2022 Code with Mosh codewithmosh.com
3
Table of Content
Getting Started………………………………………………………………………………..4
Styling…………………………………………………..……………………….……………..7
Routing and Navigation………..……………………………………………………………8
Building APIs……………….……………………………………………….……………….11
Database Integration……………………………………………………………..…………14
Uploading Files……………………………………………………………………………..16
Authentication………………………………………………………………………………17
Sending Emails…………………………………………………………………………..….20
Optimizations….………………………………………………………………………….…21
Copyright 2022 Code with Mosh codewithmosh.com
4
Getting Started
Terms
Client components Server components
Client-side Rendering (CSR) Server-side Rendering (SSR)
Dynamic rendering Static rendering
Node.js runtime Static Site Generation (SSG)
Summary
• Next.js is a framework for building fast, and search-engine friendly applications.
• It includes a compiler for transforming and minifying JavaScript code, a Command-line
Interface (CLI) for building and starting our application, and a Node.js runtime for
running backend code. This enables full-stack development.
• With Next.js, we can render our components on the server and return their content to
the client. This technique is called Server-side Rendering (SSR) and makes our
applications search-engine friendly.
• To further improve performance, we can pre-render pages and components that have
static data during the build and serve them whenever needed. This technique is called
Static Site Generation (SSG).
• The new app router in Next.js 13 makes it incredibly easy to create routes. We can
de ne route segments by creating directories. To make a route public, we add a page
le (page.js, page.jsx, or page.tsx) in the corresponding directory.
Copyright 2023 Code with Mosh codewithmosh.com
fi
fi
5
• Next.js provides the Link component to enable client-side navigation. This means as
the user navigates between pages, the new content is loaded quickly and smoothly
without the entire page being reloaded.
• Next.js 13 supports client and server components introduced in React 18. Client
components are rendered on the client within a web browser. This technique is
called Client-side Rendering (CSR) and it’s how traditional React apps work. Server
components are rendered on the server within a Node.js runtime. This technique is
called Server-side Rendering (SSR).
• Server components lead to reduced bundle sizes, better performance, increased
search engine visibility, and enhanced security. But they cannot handle browser
events, access browser APIs, or use the state or effect hooks. These functionalities
are only available in client components. So we should use them whenever possible
unless we need interactivity.
• All the components and pages in the /app directory are server components by
default. To make a component a client component, we add the ‘use client’ directive
on top of the component le.
• Server components are great for fetching data because they don’t require extra
server trips, making our application faster and more search-engine friendly.
• Next.js enhances the fetch() function by adding automatic caching. This boosts
performance and reduces the need to retrieve the same piece of data twice.
• In Next.js, components can be rendered at build time (called Static Rendering) or at
request time (called Dynamic Rendering). If we have pages or components with
static data, we can pre-render them during build time to improve our application’s
performance.
Copyright 2023 Code with Mosh codewithmosh.com
fi
6
Key Commands
Copyright 2023 Code with Mosh codewithmosh.com
Styling Next.js Applications 7
Styling
Terms
CSS modules PostCSS
Daisy UI Tailwind
Global styles
Summary
• In Next.js projects, we de ne global styles in /app/global.css. Reserve this le for global
styles that need to be applied across multiple pages and components. Avoid adding
excessive styles to this le, as it can quickly grow out of hand and become dif cult to
maintain.
• In traditional CSS, if we de ne the same class in two different les, one will overwrite
the other depending on the order in which these les are imported. CSS modules help us
prevent this problem. A CSS module is a CSS le that is scoped to a page or component.
• During the build process, Next.js uses a tool called PostCSS to transform our CSS class
names and generate unique class names. This prevents clashes between different CSS
classes across the application.
• Tailwind is a widely-used CSS framework for styling application. It offers a
comprehensive set of small, reusable utility classes. We can combine these classes to
create beautiful user interfaces.
• DaisyUI is a component library built on top of Tailwind. It provides a collection of pre-
designed and reusable components such as accordion, badge, card, etc.
Copyright 2023 Code with Mosh codewithmosh.com
fi
fi
fi
fi
fi
fi
fi
fi
Routing and Navigation 8
Routing and Navigation
Terms
Client cache Prefetching
Dynamic routes
Layout
Summary
• The new App router in Next.js uses convention over con guration to de ne routes. It
looks for special les such as page.tsx, layout.tsx, loading.tsx, route.tsx, etc.
• With the App router, we can colocate our pages and their building blocks (eg
components, services, etc). This helps us better organize our projects as we can keep
highly related les next to each other. No need to dump all the components in a
centralized components directory.
• A dynamic route is one that takes one or more parameters. To add parameters to our
routes, we wrap directory names with square brackets (eg [id]).
• In standard React applications, we use the state hook for managing component state. In
server-rendered applications, however, we use query string parameters to keep state.
This also allows us to bookmark our pages in speci c state. For example, we can
bookmark a ltered and sorted list of products.
• We use layout les (layout.tsx) to create UI that is shared between multiple pages. The
root layout (/app/layout.tsx) de nes the common UI for all our pages. We can create
additional layouts for speci c areas of our application (eg /app/admin/layout.tsx).
Copyright 2023 Code with Mosh codewithmosh.com
fi
fi
fi
fi
fi
fi
fi
fi
fi
Routing and Navigation 9
• To provide smooth navigation between pages, the Link component prefetches the links
that are in the viewport.
• As the user moves around our application, Next.js stores the page content in a cache on
the client. So, if they revisit a page that already exists in the cache, Next.js simply grabs
it from the cache instead of making a new request to the server. The client cache exists
in the browser’s memory and lasts for an entire session. It gets reset when we do a full
refresh.
Copyright 2023 Code with Mosh codewithmosh.com
Routing and Navigation 10
File Conventions
Accessing Route and Query String Parameters
Programmatic Navigation
Copyright 2023 Code with Mosh codewithmosh.com
Building APIs 11
Building APIs
Terms
API endpoint HTTP status codes
Data validation libraries Postman
HTTP methods Route handlers
Summary
• To build APIs, we add a route le (route.tsx) in a directory. Note that within a single
directory, we can either have a page or a route le but not both.
• In route les, we add one or more route handlers. A route handler is a function that
handles an HTTP request.
• HTTP requests have a method which can be GET (for getting data), POST (for creating
data), PUT/PATCH (for updating data), and DELETE (for deleting data).
• HTTP protocol de nes standard status codes for different situations. A few commonly
used ones include: 200 (for success), 201 (when a resource is created), 400 (indicating a
bad request), 404 (if something is not found), and 500 (for internal server errors).
• To create an object, the client should send a POST request to an API endpoint and
include the object in the body of the request.
• We should always validate objects sent by clients. We can validate objects using simple
if statements but as our applications get more complex, we may end up with complex
and nested if statements.
Copyright 2023 Code with Mosh codewithmosh.com
fi
fi
fi
fi
Building APIs 12
• Data validation libraries, such as Zod, allow us to de ne the structure of our objects
using a simple syntax, taking care of all the complexity involved in data validation.
• To update an object, the client should send a PUT or PATCH request to an API endpoint
and include the object in the request body. PUT and PATCH are often used
interchangeably. However, PUT is intended for replacing objects, while PATCH is
intended for updating one or more properties.
• To delete an object, the client should send a DELETE request to an API endpoint. The
request body should be empty.
• We can use Postman for testing APIs. With Postman we can easily send HTTP requests
to API endpoints and inspect the responses.
Copyright 2023 Code with Mosh codewithmosh.com
fi
Building APIs 13
Creating Route Handlers
Copyright 2023 Code with Mosh codewithmosh.com
Database Integration 14
Database Integration
Terms
Databases Models
Database Engines Object-relational Mapper (ORM)
Migrations Prisma
Summary
• We use databases to permanently store data. There are many database engines available.
Some of the popular ones are MySQL, PostgreSQL, MongoDB, etc.
• To connect our applications to a database, we often use an Object-relational Mapper
(ORM). An ORM is a tool that sits between a database and an application. It’s
responsible for mapping database records to objects in an application. Prisma is the
most widely-used ORM for Next.js (or Node.js) applications.
• To use Prisma, rst we have to de ne our data models. These are entities that represent
our application domain, such as User, Order, Customer, etc. Each model has one or
more elds (or properties).
• Once we create a model, we use Prisma CLI to create a migration le. A migration le
contains instructions to generate or update database tables to match our models. These
instructions are in SQL language, which is the language database engines understand.
• To connect with a database, we create an instance of PrismaClient. This client object gets
automatically generated whenever we create a new migration. It exposes properties
that represent our models (eg user).
Copyright 2023 Code with Mosh codewithmosh.com
fi
fi
fi
fi
fi
Database Integration 15
Key Commands
Working with Prisma Client
Copyright 2023 Code with Mosh codewithmosh.com
Uploading Files 16
Uploading Files
Uploading Files
Copyright 2023 Code with Mosh codewithmosh.com
Authentication 17
Authentication
Terms
Authentication session Middleware
Database adapter Next Auth
JSON Web Token (JWT)
Summary
• NextAuth.js is a popular authentication library for Next.js applications. It simples the
implementation of secure user authentication and authorization. It supports various
authentication providers (eg Google, Twitter, GitHub, Credentials, etc).
• When a user signs in, Next Auth creates an authentication session for that user. By
default, authentication sessions are represented using JSON Web Tokens (JWTs). But
sessions can also be stored in a database.
• To access the authentication session on the client, we have to wrap our application with
SessionProvider. This component uses React Context to pass the authentication session
down the component tree. Since React Context is only available in client components,
we have to wrap SessionProvider with a client component.
• Using middleware we can execute code before a request is completed. That’s an
opportunity for us to redirect the user to the login page if they try to access a private
part of our application without having a session. Next Auth includes built-in
middleware for this purpose.
• Next Auth comes with many database adapters for storing user and session data.
Copyright 2023 Code with Mosh codewithmosh.com
Authentication 18
Setting Up Next Auth
Auto-generated Endpoints
Copyright 2023 Code with Mosh codewithmosh.com
Authentication 19
Protecting Routes
Accessing the Session
Copyright 2023 Code with Mosh codewithmosh.com
Sending Emails 20
Sending Emails
Setting Up React Email
Creating a Template
Sending an Email
Copyright 2023 Code with Mosh codewithmosh.com
Optimizations 21
Optimizations
Terms
Image component Link component
Metadata Script component
Lazy loading
Summary
• The Image component in Next.js automatically optimizes and serves images in various
formats and sizes, reducing loading times and bandwidth usage for improved site
performance.
• The Link component enables client-side navigation between pages within our Next.js
application, eliminating full page reloads and creating a smoother user experience.
• The Script component allows you to load and manage external scripts ef ciently.
• Next.js automatically optimizes our fonts and removes external network requests for
improved privacy and performance.
• To make our applications search engine friendly, we can export a metadata object from
our pages and layouts. Metadata exported from a page overwrite metadata de ned in
the layouts.
• Lazy loading helps us improve the initial loading performance of a page by reducing
the amount of JavaScript needed to render the page. With lazy loading we can defer
loading of client components and external libraries until when they’re needed.
Copyright 2023 Code with Mosh codewithmosh.com
fi
fi
Optimizations 22
Creating Metadata
Lazy Loading
Copyright 2023 Code with Mosh codewithmosh.com