Build a static blog with Next.js 14: add social cards and robots.txt
August 01, 2024Tested with
-
Ubuntu Linux 24.04 LTS
-
Node.js v20.15.0 LTS
-
Next.js v14.2.4
The complete code of this post is available on GitHub.
In this post we will add social cards (Facebook, X, LinkedIn, etc.) and other SEO metadata (page title and description) to our Next.js 14 static blog.
To test social cards I used Social Share Preview Browser Extension.
Add data to src/lib/constants.mjs
We need to add some data shared among all pages of our blog in order to generate social cards and SEO metadata.
// File: src/lib/constants.mjs
// ...
export const SITE_URL = "https://www.example.com";
Creating shared metadata objects
All pages will have some common metadata so it is a good idea to create the file src/lib/shared-metadata.js
with this code
// File: src/lib/shared-metadata.js
// custom
import { SITE_DESCRIPTION, SITE_TITLE, SITE_URL } from "@/constants";
export const defaultOpenGraph = {
title: {
default: SITE_TITLE,
template: `%s | ${SITE_TITLE}`,
},
description: SITE_DESCRIPTION,
url: SITE_URL,
siteName: SITE_TITLE,
images: [
{
url: "https://placehold.co/2048x1024?text=Open+Graph",
width: 2048,
height: 1024,
},
],
type: "website",
};
export const defaultTwitter = {
card: "summary_large_image",
title: {
default: SITE_TITLE,
template: `%s | ${SITE_TITLE}`,
},
description: SITE_DESCRIPTION,
siteId: "1467726470533754880",
creator: "@myXAccount",
creatorId: "1467726470533754880",
images: ["https://placehold.co/2048x1024?text=X"],
};
export const defaultMetadata = {
description: SITE_DESCRIPTION,
title: {
default: SITE_TITLE,
template: `%s | ${SITE_TITLE}`,
},
openGraph: { ...defaultOpenGraph },
twitter: { ...defaultTwitter },
};
Importing this code in each page will set all proper metadata for social cards.
Add default metadata to src/app/layout.js
The dafault metadata can be added to src/app/layout.js
. These are inherited by all pages that use the layout and
each page can overwrite only the properties needed.
// File: src/app/layout.js
// ...
import { SITE_PUBLISHER, SITE_TITLE } from "@/lib/constants";
import { defaultMetadata } from "@/lib/shared-metadata";
// ...
export const metadata = { ...defaultMetadata };
// ...
Now the home page has all metadata properly set.
Add page specific metadata
Time to edit other pages.
Blog page
The src/app/blog/page.mdx
contains the code that shows the list of posts. For this page we have to overwrite title
, description
and images
properties.
// File: src/app/blog/page.mdx
// ...
import {
defaultMetadata,
defaultOpenGraph,
defaultTwitter,
} from "@/lib/shared-metadata";
// ...
const description = "The blog about everything";
const title = "Blog";
export const metadata = {
...defaultMetadata,
description: description,
title: title,
openGraph: {
...defaultOpenGraph,
description: description,
images: [
{
url: "https://placehold.co/2048x1024?text=Blog+Open+Graph",
width: 2048,
height: 1024,
},
],
title: title,
},
twitter: {
...defaultTwitter,
description: description,
images: ["https://placehold.co/2048x1024?text=Blog+X"],
title: title,
},
};
// ...
Blog post pages
For blog post pages we have to do the same thing we did for the Blog page, but we have to wrap code in a self executing function because of MDX.
Let's edit src/app/blog/my-1st-post/page.mdx
and replace the current metadata with
{/* File: src/app/blog/my-first-post/page.mdx */}
// ...
import {
defaultMetadata,
defaultOpenGraph,
defaultTwitter,
} from "@/lib/shared-metadata";
// ...
export const metadata = (() => {
const description = "Description of Welcome to my MDX page!";
const title = "Welcome to my MDX page!";
return {
...defaultMetadata,
authors: [
{
name: "Elia Contini",
},
],
datePublish: "2024-07-10T10:00:00Z",
description: description,
keywords: ["nextjs", "app router", "mdx"],
title: title,
openGraph: {
...defaultOpenGraph,
description: description,
images: [
{
url: "https://placehold.co/2048x1024?text=Post+1+Open+Graph",
width: 2048,
height: 1024,
},
],
title: title,
},
twitter: {
...defaultTwitter,
description: description,
images: ["https://placehold.co/2048x1024?text=Post+1+X"],
title: title,
},
};
})();
// ...
And even for src/app/blog/my-2nd-post/page.mdx
we should do the same.
Add robots.txt
The content of src/app/robots.txt
is
User-Agent: *
Allow: /
References
-
Title and Template object
-
Open Graph metadata
-
X (Twitter) metadata
-
robots.txt file