Notes on Next.js new release to go back on.
The new file system is built on top of React Server components.
There is a new directory called app
, it works alongiside the existing directory called pages
.
Components within app
are React Server Components
.
app
pages
index.tsx
exampleFolder
index.tsx
component.tsx
When you create an app
directory, you will need a page.tsx
file.
There are also some special files noted below.
page.tsx: file for route of UI and make path accessible
layout.tsx: shared across multiple pages, accepts another layout/page of its child + can be nested
loading.tsx: optional file for specific part of an app - automatically wraps a page/child
layout in `React Suspense Boundary`; shows the loading component immediately on first loading or between navigating sibling routes
error.tsx: optional file used to isloate errors in specific parts of the app to
show specific errors - similar to `loading.tsx`, also wrapped in `React Suspense Boundary`
template.tsx: optional file, like layout but for navigation
head.tsx: optional file for `<head>` tag for the given route
pages
uses client-side routing
app
uses server-centric routing; server components and data fetching on server
The following is taken from a blog post on the Next.js site.
With Server Components, we're laying the foundations to build complex interfaces
while reducing the amount of JavaScript sent to the client, enabling faster initial page loads.
When a route is loaded, the Next.js and React runtime will be loaded, which is cacheable
and predictable in size. This runtime does not increase in size as your application grows. Further,
the runtime is asynchronously loaded, enabling your HTML
from the server to be progressively enhanced on the client.
Essentially this is support for React’s recent Promises RFC.
// app/page.js
async function getData() {
const res = await fetch('https://api.example.com/...');
// The return value is *not* serialized
// You can return Date, Map, Set, etc.
return res.json();
}
// This is an async Server Component
export default async function Page() {
const data = await getData();
return <main>{/* ... */}</main>;
}
This is what updated fetch
looks like. SSG, SSR and ISR (Incremental Static Regeneration) all available through one API.
// This request should be cached until manually invalidated.
// Similar to `getStaticProps`.
// `force-cache` is the default and can be omitted.
fetch(URL, { cache: 'force-cache' });
// This request should be refetched on every request.
// Similar to `getServerSideProps`.
fetch(URL, { cache: 'no-store' });
// This request should be cached with a lifetime of 10 seconds.
// Similar to `getStaticProps` with the `revalidate` option.
fetch(URL, { next: { revalidate: 10 } });
To add images you need to include two things in your component, the next/image
import and the image
you wanted to import.
import Image from 'next/image'
import pictureName from './file-path/imageName.jpeg'
export default MyComponent() {
<section>
<Image src={pictureName} alt="alt text" />
</section>
}
The example above is for local images
and .jpg, .png and .webp
are currently supported. Next.js will automatically determine the width
and height
of the imported image file.
If you want to use a remote image
, you will need to specify the width
and height
.
The following is taken from the documentation for my own reference.
The default loader for Next.js applications uses the built-in Image Optimization API,
which optimizes images from anywhere on the web, and then serves them directly from
the Next.js web server. If you would like to serve your images directly from a CDN or
image server, you can write your own
loader function with a few lines of JavaScript.
You can define a loader per-image with the loader prop, or at the application level with
the loaderFile configuration.
The priority
property to the image will be the largest contentful paint (LCP)
element for each page.
The LCP element is usually the largest image/text visible within the viewport of the page.
<Image
src="example.jpeg"
alt="example"
width={100}
height={100}
priority
/>
You can change the sizes of images in three ways:
height
and width
property on <Image/>
This is a brand new font system, which optimises fonts including custom fonts. Also enables you to use Google fonts in an efficient way.
npm install @next/font
import { Inter } from '@next/font/google';
const inter = Inter();
<html className={inter.className}>
Custom fonts:
import localFont from '@next/font/local';
const myFont = localFont({ src: './my-font.woff2' });
<p className={myFont.className}>text</p>
next/link
will no longer require adding an <a>
tag.
import Link from 'next/link'
// old
<Link href="/link-example">
<a>Link</a>
</Link>
<Link href="/link-example">
Link
</Link>