About Next.js
- React is a JavaScript library for building interactive user interfaces.
- Next.js is a React framework that gives you building blocks to create web applications.
From JavaScript to React
- Rendering user interfaces
- Browser reads HTML to create DOM( an object representation of the HTML elements, acts an bridge between code and the UI)
- You can use DOM methods and a programming language to listen to user events and manipulation the DOM by selecting, adding, updating, and deleting elements in the UI.
- Updating the UI with JavaScript and DOM methods
- HTML represents the initial page content, DOM represents the updated page content, so they can be different
- Imperative programming gives steps, declarative programming gives the result
- React is a declarative UI library: you can tell React what you want to happen to the user interface, and React will figure ou the steps how to update the DOM on your behalf
- Getting started with React
- Use the following script to include React in your page
1
2<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> react
is the core React libraryreact-dom
provides DOM-specific methods that enable you to use React with the DOM- You cannot directly write HTML in JavaScript, you need to do so with JSX
- JSX is a syntax extension for JavaScript that allows you to describe your UI in a familiar HTML-like syntax. Apart from the three JSX rules, you do not need to learn any new symbols or syntax outside of HTML and JavaScript
- Three rules of JSX:
- Return a single root element
- Close all the tags: self-closing tags like
<img>
should be<img />
- Use camelCase all most of the things
- Browsers do not understand JSX, so you need to provide a JavaScript
compiler to transform JSX code into regular JavaScript. Also use
<script type="text\jsx">
instead of<script>
to tell the compiler that the code is JSX1
2<!-- Include the Babel compiler -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> ReactDOM.render(element, container[, callback])
- Use the following script to include React in your page
- Essential JavaScript for React: omitted
- React Core Components
- Components
- Props
- State
- Building UI with components
- UI can be broken into smaller building blocks called components
- Components allow you to build self-contained, reusable snippets of code
- Components are JavaScript functions that return UI elements
- React components should be capitalized and wrapped with angle brackets
- Nesting components is possible
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<script type="text/jsx">
const app = document.getElementById('app');
const Header = () => {
return (
);
}
const HomePage = () => {
return (
);
);
}
ReactDOM.render(<HomePage />, app);
</script>
- Displaying data with props
- You can pass data to components using props
props
is an object- Use curly braces to access variable in JSX
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30<script type="text/jsx">
const app = document.getElementById('div1');
const HomePage = () => {
const list = [1, 2, 3];
const props = {
title: "Hello world!",
info: "This is a test page."
}
return (
{list.map((item) => {
return (<li key={item}>{item}</li>);
})}
)
}
const Header = (props) => {
return (
);
}
ReactDOM.render(<HomePage />, app);
</script>
- Adding interactivity using State
- Use
const[state, updateState] = React.useState(initialState)
to create a state variable and update it1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33<script type="text/jsx">
const app = document.getElementById('div1');
const HomePage = () => {
const [likes, setLikes] = React.useState(0);
const handleClick1 = () => {
setLikes(likes + 1);
}
const handleClick2 = () => {
setLikes(0);
}
const props = {
title: "Hello world!",
info: "This is a test page."
}
return (
)
}
const Header = (props) => {
return (
);
}
ReactDOM.render(<HomePage />, app);
</script>
- Use
From React to Next.js
- Get Next.js in your project:
npm install react react-dom next
- The original html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41<html>
<body>
<div id="app"></div>
<script src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/jsx">
const app = document.getElementById("app")
function Header({ title }) {
return <h1>{title ? title : "Default title"}</h1>
}
function HomePage() {
const names = ["Ada Lovelace", "Grace Hopper", "Margaret Hamilton"]
const [likes, setLikes] = React.useState(0)
function handleClick() {
setLikes(likes + 1)
}
return (
{names.map((name) => (
))}
)
}
ReactDOM.render(<HomePage />, app)
</script>
</body>
</html> - The Next.js file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45import { useState } from "react";
const Header = (props) => {
return (
<div>
<h1>{props.title}</h1>
<p>{props.paragraph}</p>
</div>
);
}
const HomePage = () => {
const[likes, setLikes] = useState(0);
const list = [1, 2, 3, 4];
const props = {
title:"Hello World!",
paragraph:"Welcome to this test page"
};
const clickHandler1 = () => {
setLikes(likes + 1);
}
const clickHandler2 = () => {
setLikes(0);
}
return (
<div>
<Header {...props}/>
<ol>
{list.map((item) => {
return <li key={item}>{item}</li>
})}
</ol>
<button onClick={clickHandler1}>Increase Likes</button>
<button onClick={clickHandler2}>Reset Likes</button>
<div>Likes: {likes}</div>
</div>
);
}
export default HomePage; - Add the above code into a
index.js
file in thepages
folder - Add the following code to
package.json
1
2
3"scripts": {
"dev": "next dev",
}, - Next.js uses fast refresh, so when you make a change to the code and save, the page will be automatically updated
- The original html
How Next.js Works
Development and Production Environments
- In development environment, Next.js supports TypeScript, ESLint integration, Fast Refresh, etc.
- In the production stage, Next.js optimizes for the end-users
- The Next.js compiler
- Next.js handles code transformation and underlying infrastructure to make it easier for an application to go to production
- Next.js has a compiler written in Rust, and SWC, a platform that can be used for compilation, minification, bundling, etc.
Compiling
- Code in JSX, TypeScript, modern version of JavaScript needs to be compiled into JavaScript before browsers can understand them
- Compilation happens during the development states when you edit your code, and as part of the build step to prepare your application for production
Minifying
- Developers write code that is optimized for human readability
- Minification is the process of removing unnecessary code formatting and comments without changing the code's functionality
Bundling
- Developers break up their application into modules, components, and functions that can be used to build larger pieces of their application
- Bundling is the process of resolving the web of dependencies and merging the files into optimized bundles for the browser, with the goal of reducing the number of requests for files when a user visits a web page
Code splitting
- Developers usually split their application into multiple pages that can be accessed from different URLs, each of these pages becomes a unique entry point into the application
- The goal of code splitting is to improve the application's initial load time by only loading the code required to run that page
- Each file inside the
pages/
directory will be code split into its own JavaScript bundle during the build step - Any code shared between pages will also split into another bundle to avoid re-downloading the same code
Build Time and Runtime
- Build time is the name given to a series of steps that prepare your application code for production
- Code is transformed into production-optimized files ready to be deployed to servers and consumed by users during build time, including HTML files, JavaScript code for rendering pages on the server, JavaScript code for making pages interactive on the client, CSS files
- Runtime refers to the period of time when your application runs in response to a user's request, after your application has been build and deployed
Client and server: omitted
Rendering
- Rendering is the process to convert the code you write in React into the HTML representation of your UI
- It can take place on the server or on the client, ahead of time at build time, or on every request at runtime
- Three types of rendering methods are available with Next.js: Server-side rendering, static site generation, and client-side rendering
- Pre-rendering: server-side rendering and static site generation, because fetching external data and transformation of React components into HTML happens before the result is sent to the client, Next.js pre-renders every page by default
- Client-side rendering: browsers receive an empty HTML shell from the server with the JavaScript instructions to construct the UI
- Server-side rendering: the HTML page is generated on a server for each request. The generated HTML, JSON data, and JavaScript instructions to make the page interactive are then sent to the client
- Static site generation: the HTML is generated on the server, content is generated once, at build time, when the application is deployed, and the HTML is stored in a CDN and re-used for each request
CDNs and the Edge
- Your application code can be distributed to origin servers, CDNS(content delivery networks), and the Edge
- Origin servers: the main computer that stores and runs the original version of your application code
- CDNS: store static content in multiple locations around the world and are placed between the client and the origin server (closer cached result to the client)
- The Edge: a generalized concept for the fringe of the network, closest to the user, Edge can cache static contents, and also run code
Create a Next.js App
- Install Node.js
- Run
npx create-next-app app-name --use-npm
to create a Next.js app- The command is
create-next-app
app-name
is the name of your app--use-npm
tells the CLI to bootstrap the app using npm- Use
--ts
to create a TypeScript app
- The command is
Navigate Between Pages
- In Next.js, a page is a React Component exported from a file in the
pages
directory - Pages are associated with a route based on their file name:
pages/index.js
is associated with the/
routepages/posts/first-post.js
is associated with the/posts/first-post
route
- Use
Link
component to navigate between pages in Next.js- Very similar to the
a
tag in HTML - Allows users to do client-side navigation inside an Next.js app and accepts props that give better control over the navigation behavior
- If you want to navigate to a page that is outside of the Next.js
app, use the
a
tag - If you want to add properties to a link, wrap an
a
tag inside aLink
component, and add the properties to thea
tag1
2import Link from "next/link";
<Link href="URL">Display Text</Link> - It is also possible to use dynamic routes, the file name should
include
[variable]
to represent the dynamic route, and useuserRouter().query
to get that variable1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25// this is in the pages/posts/[pid].js
import Link from "next/link";
import { useRouter } from 'next/router'
const Header = (props) => {
return (
<div>
<h1>Post {props.pid}</h1>
</div>
);
}
const Post = () => {
const props = useRouter().query;
return (
<div>
<Header {...props} />
<div>
<Link href="/">Back to Home page.</Link>
</div>
</div>
);
}
export default Post; - Link is client-side navigation, the browser only re-render the part
that is changed, if you use
a
tag, the browser will reload the whole page
- Very similar to the
Assets, Metadata, and CSS
- Assets
- Next.js serve static assets under the
public
directory - The
public
directory is also useful forrobots.txt
, Google site verification, and any other static assets - URL pattern: for
public/profile.jpg
, the URL will be/profile.jpg
in the app
- Next.js serve static assets under the
- The Image Component
- You can use the
image
tag to import images next/image
is an extension of the HTMLimg
tag, it supports for image optimization by default (resizing, optimizing, and serving images in modern formats)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import Image from "next/image";
const ProfileFigure = () => {
return (
<Image
src="/profile.jpg"
alt="Picture of the author"
width={200}
height={200}
/>
);
}
const Profile = () => {
return (
<div>
<h1>Profile page</h1>
<ProfileFigure />
</div>
);
}
export default Profile;
- You can use the
- Metadata
- Add head to a page
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import Head from "next/head";
const Profile = () => {
return (
<div>
<Head>
<title>Profile</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<h1>Profile page</h1>
</div>
);
}
export default Profile;
- Add head to a page
- Third-party scripts
- Method one: use HTML
script
tag in theHead
component - Method two: use the
Script
component innext/script
, thestrategy
attribute controls when the third-party script should load, theonLoad
attribute is used to run any JavaScript code immediately after the script has finished loading1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import Script from "next/script";
const Profile = () => {
return (
<div>
<Head>
<title>Profile</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<h1>Profile page</h1>
<Script
src="https://www.google-analytics.com/analytics.js"
strategy="lazyOnload"
onLoad={() =>
console.log(`script loaded correctly, window.FB has been populated`)
}
/>
</div>
);
}
- Method one: use HTML
- CSS