Provide metadata with NextJS

Pro Members Only

This lesson is available if you have an active subscription.

Alternatively, some member might be able to gift it to you.

If you already have a subscription, you can sign in.

Professional NextJS Lessons

1.Course Intro
free
⏱️ 2:05
2.Get Setup
free
⏱️ 2:05
3.Project Template
free
⏱️ 5:45
4.Introducing FullStack React
free
⏱️ 4:57
5.App Router Reference
free
⏱️ 7:08
6.NextJS Server vs. "use client" Rendering
⏱️ 5:01
7.Nesting Server and Client Components
⏱️ 8:51
8.Client Only Components
⏱️ 3:48
9.Global CSS in NextJS
⏱️ 6:30
10.CSS Modules and SASS
⏱️ 4:15
11.Tailwind CSS
⏱️ 5:17
12.NextJS Custom Fonts
⏱️ 4:08
13.Static vs Dynamic Rendering
⏱️ 4:55
14.NextJS Link Component
⏱️ 3:20
15.NextJS Link Prefetching
⏱️ 5:49
16.Navigation Scroll with Link
⏱️ 2:02
17.Replace Navigation History
⏱️ 1:35
18.NextJS Image Component
⏱️ 7:01
19.Dynamic Image URLs
⏱️ 5:34
20.Safe Colocation with Private Folders
⏱️ 2:12
21.NextJS Route Groups
⏱️ 3:07
22.Dynamic Routes
⏱️ 5:37
23.NextJS API Routes
⏱️ 6:03
24.NextRequest and NextResponse
⏱️ 2:41
25.Cookies in API Handlers
⏱️ 4:25
26.React Suspense Simplified
⏱️ 2:23
27.Power of Suspense Boundaries
⏱️ 3:52
28.use Promises
⏱️ 3:24
29.Stream Promise Results from Server to Client
⏱️ 3:03
30.use Requires a Cached Promise
free
⏱️ 2:30
31.Suspense Error Boundaries
⏱️ 4:42
32.React Server Functions
⏱️ 4:50
33.Server Actions for Powerful Forms
⏱️ 5:35
34.useActionState to Simplify Form Actions
⏱️ 6:38
35.React Serializable Types
⏱️ 2:42
36.Create Dynamic Images with NextJS ImageResponse
⏱️ 5:54
37.Deploy NextJS Application to Production
⏱️ 3:51
38.NextJS Environment Variables Masterclass
⏱️ 3:50
39.Deploying and Managing Environment Variables
⏱️ 4:38
40.Using Databases for Dynamic Server Side State
free
⏱️ 7:34
41.Mastering NextJS Layout Files
⏱️ 4:54
42.Client State Management with NextJS
⏱️ 3:48
43.Client State Management In Action
⏱️ 8:04
44.Using Client State Management Libraries
⏱️ 5:25
45.Detecting Server vs Client Runtime and useEffect
⏱️ 4:33
46.Demystifying ISR vs SSR vs SSG
⏱️ 3:07
47.Static Site Generation or SSG with NextJS
⏱️ 3:16
48.Incremental Static Regeneration (ISR) Simplified
⏱️ 2:51
49.API Routes Caching with NextJS
⏱️ 3:05
50.Reference Guide to Caching for Modern NextJS
⏱️ 2:47
51.Setup a BASE_URL for client and server
free
⏱️ 2:54
52.Creating a sitemap.xml
⏱️ 3:29
53.Provide metadata with NextJS
⏱️ 6:54
54.Created High Quality Social Media Previews
⏱️ 7:38

Provide metadata with NextJS

Subscription Required

You must have an active subscription to access this content.
If you already have a subscription, you can sign in.

Why is metadata important?

Providing high quality metadata can:

  • increase your search ranking as pages can provide easy hints to search engines about their purpose
  • provide a better use experience as they navigate your website, create bookmarks etc.

Two Key Ways

There are two key ways to provide metadata using code in NextJS:

  • export a metadata object
  • export a generateMetadata function

Simple metadata object

At its simplest you can export a metadata object from your page file.

This is demonstrated in the below example where the different pages export a metadata object.

app/page.tsx
app/about/page.tsx
app/contact/page.tsx
import styles from "./page.module.css";
import { Metadata } from "next";

export const metadata: Metadata = {
title: "Home",
description: "Welcome to our home page",
};

export default function Page() {
return (
<div className={styles.root}>
<h1 className={styles.title}>Welcome to our home 🏡</h1>
</div>
);
}

Metadata in layout vs page

You can provide a common metadata for a section of your site by exporting it from a layout file instead of a page file. You can even override portions of the metadata of your layout from your page.

This is demonstrated in the below example where we provide a common title and a description for the dashboard section, and override the title in the individual pages.

app/dashboard/layout.tsx
app/dashboard/security/page.tsx
app/dashboard/subscription/page.tsx
import { type Metadata } from "next";

export const metadata: Metadata = {
title: "Dashboard",
description: "Manage your user settings and preferences",
};

export default function Layout({ children }: React.PropsWithChildren) {
return children;
}

Dynamic generateMetadata function

If you want to dynamically create the metadata by querying an external data source, you can export a generate metadata function from your layout or page module and use it to implement your custom business logic.

This is demonstrated in the below example where we load content from an external CMS (content management system).

app/cms/[slug]/page.tsx
import { fetchPageContent } from "@/api/cms";
import { SimpleContent } from "@/lib/SimpleContent";
import { type Metadata } from "next";

export async function generateMetadata({
params,
}: {
params: Promise<{ slug: string }>;
}): Promise<Metadata> {
const { slug } = await params;
const content = await fetchPageContent(slug);
return {
title: content.title,
description: content.description,
};
}

export default async function Page({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
const content = await fetchPageContent(slug);
return <SimpleContent {...content} />;
}

Accessing parent metadata with generateMetadata

With the generate metadata function you are even passed in the metadata that was returned by some parent layout, so you can build on top of that parent result customizing it further for your page.

This is demonstrated below where we customize the metadata in the dashboard pages building on top of the title returned by the dashboard layout.

app/dashboard/layout.tsx
app/dashboard/security/page.tsx
app/dashboard/subscription/page.tsx
export const metadata = {
title: "Dashboard",
description: "Manage your user settings and preferences",
};

export default function Layout({ children }: React.PropsWithChildren) {
return children;
}
javascript
typescript
react
playwright

Enjoy free content straight from your inbox 💌

No spam, unsubscribe at any time.

Transcript

00:00

Next has a built-in metadata, API that can be used for an improved user experience and increased search engine ranking. There are two options that you can use in order to provide metadata using code, either by using the metadata object or by using the generate metadata function. We will build a solid understanding of both of these approaches in this lesson. Let's first demonstrate why it's important for you to provide good metadata for different routes. We start off with a simple three-page application. We have the homepage, then we have the about page, and then we have the contact page.

00:31

Note that none of these pages currently export any custom metadata. This means that as the user navigates through our application, all the pages would share the same title. The title website that is showing in the tab is configured in our route layout. This title shows up in a number of user experience ways. For example, it also shows up in the browser history. This makes it difficult for the user to see where they have been on our website, and additionally, this title also shows up to search engines, which would think that they are all the same page. At its simplest, you can export a metadata object from your page file.

01:03

Within our homepage, we bring in the metadata type from XAS, and then we export a metadata object, which is of metadata type, and we provide a title and a description. Then we repeat the same process for the other two pages for the about page. We bring in the type and then we export the metadata object using the content that we already have. And finally, we repeat it for the contact page. We bring in the type and we export that metadata object. With these changes in place, let's visit our website again. As we navigate through the different pages, you can see that the title for the tab changes to reflect the page that we are currently on.

01:36

Additionally, the title also shows up in the browser history, so the user can easily see the different pages that they visited on our website. A simple thing like the title can greatly improve the user experience. Note that the things that we provide in the metadata are added to the HTMO head by next js. For example, over here we can see the title as well as the description. You can provide a common metadata for a section of your site by exporting it from a layout file instead of a page file. To demonstrate this, we've added a new section to our website called dashboard that has two pages inside of it slash security and slash subscription.

02:09

As you can see, these pages do not currently export any metadata. So as the user visits these dashboard sections, they are presented with a default title, which is configured in our root layout, which is currently just plain website. We can override this by providing a common layout for the two dashboard sections. Within this dashboard layout file, we bring in the metadata type and then export the metadata object with a simple title called dashboard and a description that is common for the different dashboard sections. Note that a layout file within next J must export a default component that provides a common layout for the child pages.

02:42

But since we are only using this file to provide the common metadata, we export a layout which is a simple pass through. It takes the children and returns them without any rendering modifications. With these changes in place, if you visit the different dashboard sections of our website, you can see the new title showing up in the browser tab. When the metadata is provided in a layout file, you can override portions of it from the page files. For example, within the dashboard security page, we override the title with custom content for the page, but leave the description intact and we repeat the same process for the subscription page within our dashboard.

03:14

With these two changes in place, let's visit our website again, and as you visit the security page, you can see the custom title showing up, and the same is true for the subscription page. Note that there is a cascade of metadata that happens with out files, and since we only provided a title, the description is still shared between the two dashboard sections. If you want to dynamically create the metadata by creating an external data source, you can export a generate metadata function from your layout or page module to implement your custom business logic. Let's move our simple content pages to an external CMS. We bring in a fetch page content utility

03:47

that will load the content from our external CMS and a simple content component which will display that content. Our route is not dynamic that accepts a slug as a parameter, which gets passed as the promise to our page function within the function body. We await that promise to get the slug. We then use the slug to query the CMS for the content that is relevant for this page, and then render that content with our simple content component. So the content for the about and the content page are now coming from the CMS, and as you can see, they currently share the same title. Let's fix this to use the title that is returned from our CMS.

04:20

We start off by bringing in the metadata type from next as we export a generate metadata function from our page module, and just like the page gets passed in the route, pers that generate metadata function also has access to the same paras promise. From your generate metadata function, you need to return a metadata object, which we return as a promise because this is an async function within the function body. We evade the paras to get the slug and then use it to fetch the page content from the CMS. Once we have the content, we return the metadata, and for this we are providing the title and the description. Note that next year's automatically cases any fetch requests

04:55

made with the same URL and options between the rendering of generate metadata and the page function. So actually, even though we are making two function calls over here, only one network call would be made to the CMS. With this change in place, the CMS pages get their own title and descriptions. For example, the about page has the title about and the contact page has the title contact with the generate metadata function, you are even passed in the metadata that was returned by some parent layout, so you can build on top of that parent result customizing it further for your page. To demonstrate this, we use our dashboard example

05:27

where the different pages currently use a simple metadata object. Note that the sub pages of the dashboard currently have a hardcoded title from the parent layout. Let's fix these pages to automatically get access to the title provided by the dashboard layout. To start off, within the security page, we remove the metadata object and instead we will use the generate metadata function. We know that the generate metadata function gets passed in the route patterns as the first argument, and since we do not have any dynamic routing overhead, we mark this as unused With underscore and give it the type unknown so we don't end up using it by mistake.

06:01

This function is actually passed in a second argument as well, which will be the metadata currently being resolved by some parent layout. And eventually we need to return a metadata object within the function body. We get access to the resolved parent metadata by simply using a weight with parent resolving note that next year stores the resolved metadata a bit differently than the metadata object. So if you want to read the title from Resolved metadata, we need to access its absolute property. Now that we have the title from the parent layout, we simply return a new title using the title for the current content along with the pipe and the title from the parent.

06:34

Note that this might seem like a lot of code, but you can move this function into a utility module that builds a general purpose bedroom for titles used on various sections of your website. And as far as behavior is concerned, it behaves the same as before with the title for the page, followed by the pipe and the title for the dashboard.

Professional NextJS

Professional NextJS

1.Course Intro
free
⏱️ 2:05
2.Get Setup
free
⏱️ 2:05
3.Project Template
free
⏱️ 5:45
4.Introducing FullStack React
free
⏱️ 4:57
5.App Router Reference
free
⏱️ 7:08
6.NextJS Server vs. "use client" Rendering
⏱️ 5:01
7.Nesting Server and Client Components
⏱️ 8:51
8.Client Only Components
⏱️ 3:48
9.Global CSS in NextJS
⏱️ 6:30
10.CSS Modules and SASS
⏱️ 4:15
11.Tailwind CSS
⏱️ 5:17
12.NextJS Custom Fonts
⏱️ 4:08
13.Static vs Dynamic Rendering
⏱️ 4:55
14.NextJS Link Component
⏱️ 3:20
15.NextJS Link Prefetching
⏱️ 5:49
16.Navigation Scroll with Link
⏱️ 2:02
17.Replace Navigation History
⏱️ 1:35
18.NextJS Image Component
⏱️ 7:01
19.Dynamic Image URLs
⏱️ 5:34
20.Safe Colocation with Private Folders
⏱️ 2:12
21.NextJS Route Groups
⏱️ 3:07
22.Dynamic Routes
⏱️ 5:37
23.NextJS API Routes
⏱️ 6:03
24.NextRequest and NextResponse
⏱️ 2:41
25.Cookies in API Handlers
⏱️ 4:25
26.React Suspense Simplified
⏱️ 2:23
27.Power of Suspense Boundaries
⏱️ 3:52
28.use Promises
⏱️ 3:24
29.Stream Promise Results from Server to Client
⏱️ 3:03
30.use Requires a Cached Promise
free
⏱️ 2:30
31.Suspense Error Boundaries
⏱️ 4:42
32.React Server Functions
⏱️ 4:50
33.Server Actions for Powerful Forms
⏱️ 5:35
34.useActionState to Simplify Form Actions
⏱️ 6:38
35.React Serializable Types
⏱️ 2:42
36.Create Dynamic Images with NextJS ImageResponse
⏱️ 5:54
37.Deploy NextJS Application to Production
⏱️ 3:51
38.NextJS Environment Variables Masterclass
⏱️ 3:50
39.Deploying and Managing Environment Variables
⏱️ 4:38
40.Using Databases for Dynamic Server Side State
free
⏱️ 7:34
41.Mastering NextJS Layout Files
⏱️ 4:54
42.Client State Management with NextJS
⏱️ 3:48
43.Client State Management In Action
⏱️ 8:04
44.Using Client State Management Libraries
⏱️ 5:25
45.Detecting Server vs Client Runtime and useEffect
⏱️ 4:33
46.Demystifying ISR vs SSR vs SSG
⏱️ 3:07
47.Static Site Generation or SSG with NextJS
⏱️ 3:16
48.Incremental Static Regeneration (ISR) Simplified
⏱️ 2:51
49.API Routes Caching with NextJS
⏱️ 3:05
50.Reference Guide to Caching for Modern NextJS
⏱️ 2:47
51.Setup a BASE_URL for client and server
free
⏱️ 2:54
52.Creating a sitemap.xml
⏱️ 3:29
53.Provide metadata with NextJS
⏱️ 6:54
54.Created High Quality Social Media Previews
⏱️ 7:38