Build a static blog with Next.js 14: add social cards and robots.txt

August 01, 2024

Tested 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


Did you find this post useful? What about Buy Me A Coffee

A photo of Elia Contini
Written by
Elia Contini
Sardinian UX engineer and a Front-end web architect based in Switzerland. Marathoner, traveller, wannabe nature photographer.