Language:EN
Pages: 32
Words: 7225
Rating : ⭐⭐⭐⭐⭐
Price: $10.99
Page 1 Preview
if a page has dynamic routes and uses getstaticpro

If a page has dynamic routes and uses getstaticprops, it needs to define a list of paths to be statically generated. when you export a function called getstaticpaths (normally used for static site generation) from a page that uses dynamic routes, next.js will statically pre-render all the paths specified by getstaticpaths.

Introduction

Next.js 13 Upgrade Guide

yarn add next@latest react@latest react-dom@latest eslint-config-next@latest

If you're using ESLint, you need to upgrade your ESLint version:

A step-by-step guide to help you incrementally migrate from the `pages` to the `app` directory.

Upgrading New Features

Special file conventions are used to create UI for each route segment. The most common special files are page.js and layout.js.

Use page.js to define UI unique to a route.

Data Fetching Fundamentals

Data fetching functions

Like getServerSideProps, getStaticProps, and getStaticPaths have been replaced with a new API inside app.

  • Step 1: Creating the app directory

Ensure you've updated to Next.js version 13, then opt into the new app directory in next.config.js:

appDir: true,

},

Create a new app/layout.tsx file inside the app directory. This is a root layout that will apply to all routes inside app.

app/layout.tsx

}: {

children: React.ReactNode;

</html>

);

js, jsx, or tsx extensions can be used for layout files.

You can use the head.js special file to manage <head> HTML elements, for example, the <title> element.

<title>My Next.js App</title>

</>

If you are using any React Context providers, they will need to be moved to a Client Component.

Migrating the getLayout() pattern to Layouts (Optional)

Before:

pages/index.tsx

<Head>

<title>My page title</title>

After:

app/head.tsx

<meta name="viewport" content="width=device-width, initial-scale=1" />

</>

Step 4: Migrating Pages

Pages in the app directory are Server Components by default. This is different from the pages directory where pages are Client Components.

about.js about/page.js /about

blog/[slug].js blog/[slug]/page.js /blog/post-1

Step 1: Create a new Client Component

Create a new separate file inside the app directory (i.e. app/HomePage.tsx or similar) that exports a Client Component. To define Client Components, add the 'use client' directive to the top of the file (before any imports).

// has access to state and effects just like Page components

// in the `pages` directory.

<div key={post.id}>{post.title}</div>

))}

Create a new app/page.tsx file inside the app directory. This is a Server Component by default. Import the HomePage.tsx Client Component into the page. If you were fetching data in pages/index.js, move the data fetching logic directly into the Server Component using the new data fetching APIs. See the data fetching upgrade guide for more details.

app / page.tsx

    const posts = await res.json();

    return posts;

    // Forward fetched data to your Client Component

    return <HomePage recentPosts={recentPosts} />;

New Router hook

A new router has been added to support the new behaviour in the app directory.

The new useRouter does not return the query object. Use the separate useSearchParams hook instead.

These new hooks are only supported in Client Components. They cannot be used in Server Components.

export default function Page() {

  const router = useRouter();

In addition, the new useRouter hook has the following changes:

isPreview has been removed. Use the previewData function instead.

isReady has been removed because it is no longer necessary. During static rendering, any component that uses the useSearchParams() hook will skip the prerendering step and instead be rendered on the client at runtime.

View the useRouter() API reference.

    // This request should be cached until manually invalidated.

    // Similar to `getStaticProps`.

    const dynamicData = await fetch(`https://...`, { cache: 'no-store' });

    // This request should be cached with a lifetime of 10 seconds.

    return <div>...</div>;

}

export async function getServerSideProps() {

    const res = await fetch(`https://...`);

    return projects.map((project) => <div>{project.name}</div>);

}

// This function can be named anything

async function getProjects() {

export default async function Dashboard() {

const projects = await getProjects();

For example, you can retrieve the req object from getServerSideProps and use it to retrieve the request's cookies and headers.

pages/index.js

return { props: { ... }}

}

headers(): Based on the Web Headers API, and can be used inside Server Components to retrieve request headers.

cookies(): Based on the Web Cookies API, and can be used inside Server Components to retrieve cookies.

  const authHeader = headers().get('authorization');

  return ...;

  const theme = cookies().get('theme');

  const data = await getData();

pages/index.js

// `pages` directory

}

export default function Index({ projects }) {

// `app` directory

// This function can be named anything

}

export default async function Index() {

In the pages directory, the getStaticPaths function is used to define the dynamic paths that should be pre-rendered at build time.

pages/posts/[id].js

    };

}

}

export default function Post({ post }) {

app/posts/[id]/page.js

// `app` directory

const res = await fetch(`https://.../posts/${params.id}`);

const post = await res.json();

return <PostLayout post={post}>

}

// `pages` directory

export async function getStaticPaths() {

}

export async function getStaticProps({ params }) {

}

In the app directory the config.dynamicParams property controls how params outside of generateStaticParams are handled:

// `app` directory

export const dynamicParams = true;

...

}

With dynamicParams set to true (the default), when a route segment is requested that hasn't been generated, it will be server-rendered and cached as static data on success.

Incremental Static Regeneration (getStaticProps with revalidate)

const res = await fetch(`https://.../posts`);

const posts = await res.json();

}

export default function Index({ posts }) {

);

}

const res = await fetch(`https://.../posts`, { next: { revalidate: 60 } });

const data = await res.json();

return posts.map((post) => <div>{post.name}</div>);

};

In the pages directory, global stylesheets are restricted to only pages/_app.js. With the app directory, this restriction has been lifted. Global styles can be added to any layout, page, or component.

CSS Modules

Sass

Tailwind CSS

"./app/**/*.{js,ts,jsx,tsx}", // <-- Add this line

"./pages/**/*.{js,ts,jsx,tsx}",

app/layout.js

import "../styles/globals.css";

</html>

);

On-demand Revalidation

More here: https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration#on-demand-revalidation

Dynamic paths

Defining routes by using predefined paths is not always enough for complex applications. In Next.js you can add brackets to a page ([param]) to create a dynamic route (a.k.a. url slugs, pretty urls, and others).

Static Rendering

Server-side Rendering

When a user requests a page, Next.js will generate the content on the server and return it to the user. This is done on per request. Next.js will enable Server-side rendering when the getServerSideProps API is used in a page.

Use Case:

We can configure each page of our application to fetch data differently. Such as few pages statically render, and few pages server side rendered. Let's take an e-commerce app as an example:

getStaticProps

This controls when a page should build. At next build time that is when we are building website by firing command next build. Don’t be confused with next dev because in dev mode a page is always build.

We can control using getStaticProps following

  1. Should skip building particular page at website build

  2. Should build on time interval, if we set build time like 24 hours, then after first build this page might build again after 24 hours but to trigger this page build a request should come in the form of opening this page in browser or someway to trigger this build.

  3. We can also set to build never again, so in this case only page will be built one time and will never build again. However, if we change the content of this page, we must change the never build to build once more.

getStaticPaths

If a page has Dynamic Routes and uses getStaticProps, it needs to define a list of paths to be statically generated. When you export a function called getStaticPaths (normally used for Static Site Generation) from a page that uses dynamic routes, Next.js will statically pre-render all the paths specified by getStaticPaths.

paths: [{params: { id: '1' } }, { params: { id: '2' } }],

fallback: false, // can also be true or 'blocking'

return {

// Passed to the page component as props

// Render post...

}

When should I use getStaticPaths?

  • The data can be publicly cached (not user-specific)

  • The page must be pre-rendered (for SEO) and be very fast — getStaticProps generates HTML and JSON files, both of which can be cached by a CDN for performance

When does getStaticPaths run

How does getStaticProps run with regards to getStaticPaths

Where can I use getStaticPaths

  • getStaticPaths must be used with getStaticProps

  • You cannot use getStaticPaths with getServerSideProps

Runs on every request in development

Generating paths on-demand

getStaticPaths allows you to control which pages are generated during the build instead of on-demand with fallback. Generating more pages during a build will cause slower builds.

getServerSideProps

const{data, error, isLoading, isValidating, mutate}=useSWR(key, fetcher, options)

isLoading: becomes true when there is an ongoing request and data is not loaded yet.

isValidating:  becomes true whenever there is an ongoing request whether the data is loaded or not.

Example with all return value of useSWR

console.log(data, error, isLoading, isValidating)

return null

undefined Error false false // => end fetching, got an error

undefined Error true true // => start retrying

const { data } = useSWR('/api', fetcher)

console.log(data)

undefined // => hydration / initial render

Data // => end retrying, get the data

Example

const { user, isLoading, isError, mutate} = useUser(id)

if (isLoading) return <Spinner />

isLoading,

isError: error

return <div>hello {data.name}!</div>

Arguments

By default, key will be passed to fetcher as the argument. So, the following 3 expressions are equivalent:

const {data: user} = useSWR(['/api/user', token], ([url, token]) => fetchWithToken(url, token))

const {data: user} = useSWR(['/api/user', token], fetchWithToken)

const {data} = useSWR(shouldFetch ? '/api/data': null, fetcher)

// ...or return a falsy value

Default behaviour: without options object

  • Revalidate when a page has mounted

  • Revalidate when a page gets re-focus

revalidateOnFocus default: true

revalidateOnReconnect default: true

revalidateIfStale default: true

SWR has the revalidateIfStale option and the default value is true. The option indicates whether SWR revalidates data on rendering or not when the cache has stale data. SWR doesn’t revalidate data on rendering when the key has not been changed, so it only affects the behaviour on rendering when mounting or the key has been changed. This also doesn’t affect the behaviours of revalidateOnFocus and relivadateOnReconnet.

revalidateOnMount default: undefined

dedupingInterval default: 2000

useSWRImmutable

You can use useSWRImmutable by importing from swr/immutable.

Retry on an error

Error Handling

// ...

const { data, error } = useSWR('/api/user', fetcher)

Status Code and Error Object

// If the status code is not in the range 200-299,

// we still try to parse and throw it.

error.status = res.status

throw error

const { data, error } = useSWR('/api/user', fetcher)

// error.info === {

Note that data and error can exist at the same time. So, the UI can display the existing data, while knowing the upcoming request has failed.

Example of both data and error

import React from "react";

import useSWR from "swr";

// error!

if (Math.random() < 0.4) throw new Error("An error has occurred!");

const { data, error, mutate, isValidating } = useSWR(

"/api",

<div className="App">

<h2>Current time: {data}</h2>

{error ? <p style={{ color: "red" }}>{error.message}</p> : null}

</div>

Conditional Fetching

const { data } = useSWR(shouldFetch ? '/api/data' : null, fetcher)

// ...or return a falsy value

Dependent fetching

const { data: user } = useSWR('/api/user', fetcher)

const {data: avatar}=useSWR(user?'/api/avatar?id='+user.id : null, fetcher)

const fetcher = (url, token) => uahclient(token).get(url).then(res => res.data);

const { data, mutate, error } = useSWR(() =>[`/cart`, user.token], fetcher);

Another example

function useProjects() {

}

return null;

Revalidation

Mutation & Revalidation

mutate(key, data, options);

key: required, directly or indirectly (bounded mutation)

  • options: accepts the following options and default value is also given below.

  • optimisticData: data to immediately update the client cache, or a function that receives current data and returns the new client cache data, usually used in optimistic UI.

There're 2 ways to use the mutate API to mutate the data,

  1. The global mutate API which can mutate any key

import { useSWRConfig } from "swr"

function App() {

import { mutate } from "swr"

function App() {

const newName = data.name.toUpperCase()

// send a request to backend to update the data, below we are using await so it will block further till backend response.

Return Values of mutation

mutate returns the results the data parameter has been resolved. The function passed to mutate will return an updated data which is used to update the corresponding cache value. If there is an error thrown while executing the function, the error will be thrown so it can be handled appropriately.

const user = await mutate('/api/user', updateUser(newUser))

} catch (error) {

import useSWR from "swr";

const Form = ({ fetcher }) => {

<section>

<h2>Form</h2>

onChange={(e) => setText(e.currentTarget.value)}

/>

<p>{data}</p>

</section>

const [logs, setLogs] = useState([]);

const [mount, setMount] = useState(true);

};

return (

<i>`dedupingInterval = 2000`</i> as its default option, so fetcher calls

in 2seconds will be deduped.

{mount ? <Form fetcher={fetcher} /> : null}

<section>

<ul>

{logs.map((log, i) => (

</div>

);

const Form = ({ fetcher }) => {

const [text, setText] = useState("initial");

<h2>Form</h2>

<div>

/>

</div>

</section>

</>

const [mount, setMount] = useState(true);

const fetcher = async (key) => {

return (

<div>

<ul>

<li>

</li>

<li>

<button onClick={() => setMount((prev) => !prev)}>

{mount ? "Unmount" : "Mount"}

<p>

The following is logs of the fetcher passed in <i>`useSWR`</i>

))}

</ul>

example 3

import React, { useState } from "react";

revalidateOnMount,

revalidateOnFocus: false,

<section>

<h2>Form</h2>

type="checkbox"

checked={revalidateOnMount}

<div>

<input

</div>

</section>{" "}

</>

);

const [revalidateOnMount, setRevalidateOnMount] = useState(true);

const fetcher = async (key) => {

return (

<div>

</p>

<p>

The current version(v1.2.1) never revalidate if{" "}

<i>`revalidateOnMount`</i> disables.

{mount ? (

<Form

) : null}

<section>

<ul>

{logs.map((log, i) => (

</div>

);

const Form = ({ fetcher }) => {

const [text, setText] = useState("initial");

revalidateOnReconnect: false

});

<div>

<label>

onChange={() => setRevalidateIfStale((prev) => !prev)}

/>

type="text"

value={text}

<section>

<h2>Data</h2>

};

export default function App() {

setLogs((prev) => [...prev, key]);

return key;

<p>

<i>`revalidateIfStale`</i> enables us to revalidate data even if there

there is cached data.

</p>

<section>

<h2>Fetcher Logs</h2>

{logs.map((log, i) => (

<li key={i}>{log}</li>

);

}

You are viewing 1/3rd of the document.Purchase the document to get full access instantly

Immediately available after payment
Both online and downloadable
No strings attached
How It Works
Login account
Login Your Account
Place in cart
Add to Cart
send in the money
Make payment
Document download
Download File
img

Uploaded by : Ms Jill Thomas

PageId: DOC73E6202