Skip to content

Commit 8d00c5c

Browse files
authored
✨ - Add dynamic metadata generator (#9)
1 parent 28864bd commit 8d00c5c

File tree

9 files changed

+81
-45
lines changed

9 files changed

+81
-45
lines changed

contentlayer.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export const Blog = defineDocumentType(() => ({
99
fields: {
1010
title: { type: 'string', required: true },
1111
date: { type: 'date', required: true },
12-
description: { type: 'string', required: false },
12+
description: { type: 'string', required: true },
1313
thumbnailUrl: { type: 'string', required: true },
1414
author: { type: 'string', required: true },
1515
},

posts/blog/resources_developers.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
title: Mis 5 Sitios Favoritos para Aprender Programación
33
date: 2023-12-11
4+
description: Mis 5 Sitios Favoritos para Aprender Programación
45
thumbnailUrl: /blog/developer.png
56
author: claudio_coder
67
---

public/profile.jpg

243 KB
Loading

src/app/[slug]/page.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,33 @@ import { notFound } from 'next/navigation'
33
import { format, parseISO } from 'date-fns'
44
import Footer from '@/components/Footer'
55
import { Mdx } from '@/components/Mdx'
6+
import metadata from '@/utils/metadata'
67

78
type Props = {
89
params: {
910
slug: string
1011
}
1112
}
1213

13-
async function getDocFromParams({ params }: Props) {
14+
const getDocFromParams = ({ params }: Props) => {
1415
const doc = allBlogs.find((doc) => doc.slug === params.slug)
1516

1617
return doc ?? null
1718
}
1819

20+
export const generateMetadata = async ({ params }: Props) => {
21+
const doc = await getDocFromParams({ params })
22+
if (!doc) {
23+
return {}
24+
}
25+
return metadata({
26+
title: doc.title,
27+
description: doc.description,
28+
path: `/${doc.slug}`,
29+
image: `/${doc.thumbnailUrl}`,
30+
})
31+
}
32+
1933
const BlogPage = async ({ params }: Props) => {
2034
const post = await getDocFromParams({ params })
2135

src/app/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export default function RootLayout({
1313
children: React.ReactNode
1414
}) {
1515
return (
16-
<html lang="en">
16+
<html lang="es">
1717
<body className={_roboto.className}>
1818
<div className="p-5 sm:pl-5 h-screen">
1919
<div className="flex flex-col sm:flex-row column w-full">

src/app/page.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ export default function Home() {
2323
<meta name="viewport" content="width=device-width, initial-scale=1" />
2424
<link rel="icon" href="/favicon.ico" />
2525
</Head>
26-
<div>
27-
<h1 className="mb-4 sm:mb-8 text-3xl font-black">Blog</h1>
26+
<div className="sm:m-8">
27+
<h1 className="mb-6 sm:mb-8 text-3xl font-black">Blog</h1>
2828
<div className="flex flex-wrap gap-5">
2929
{posts.map((post, idx) => (
3030
<PostCard key={idx} {...post} />

src/components/ProfileContainer.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const ProfileContainer = () => {
88
return (
99
<>
1010
<div>
11-
<div className="mb-5">
11+
<div className="mb-5 flex flex-col items-center">
1212
<Image
1313
className="shadow-[0_5px_15px_rgba(0,0,0,0.35)] rounded-full"
1414
src={profileImage}
@@ -18,9 +18,11 @@ const ProfileContainer = () => {
1818
height={200}
1919
/>
2020
</div>
21-
<h1 className={`${_roboto.className} text-xl font-bold mb-1 text-center`}>Hi, my name is Claudio!</h1>
21+
<h1 className={`${_roboto.className} text-xl font-bold mb-1 text-center`}>Hola, mi nombre es Claudio!</h1>
2222
<h2 className={`${_khula.className} text-base mb-5 text-center`}>Software Developer</h2>
23-
<SocialNetwork></SocialNetwork>
23+
<div>
24+
<SocialNetwork></SocialNetwork>
25+
</div>
2426
</div>
2527
</>
2628
)
Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,24 @@
1-
import {
2-
faGithub,
3-
faLinkedin,
4-
faSquareTwitter,
5-
faTwitch,
6-
} from '@fortawesome/free-brands-svg-icons'
1+
import { faGithub, faLinkedin, faSquareTwitter, faTwitch } from '@fortawesome/free-brands-svg-icons'
72
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
83
import Link from 'next/link'
94

105
const SocialNetwork = () => {
11-
return (
12-
<div className="flex items-center justify-around w-full max-w-[200px]">
13-
<Link href="https://twitter.com/claudio_coder" target="_blank" legacyBehavior>
14-
<FontAwesomeIcon
15-
className="text-3xl text-blue-500 cursor-pointer"
16-
icon={faSquareTwitter}
17-
/>
18-
</Link>
19-
<Link href="https://github.com/claudiocoder" target="_blank" legacyBehavior>
20-
<FontAwesomeIcon
21-
className="text-3xl text-gray-800 cursor-pointer"
22-
icon={faGithub}
23-
/>
24-
</Link>
25-
<Link
26-
href="https://www.linkedin.com/in/cmorenomx"
27-
target="_blank"
28-
legacyBehavior>
29-
<FontAwesomeIcon
30-
className="text-3xl text-blue-800 cursor-pointer"
31-
icon={faLinkedin}
32-
/>
33-
</Link>
34-
<Link href="https://www.twitch.tv/claudio_coder" target="_blank" legacyBehavior>
35-
<FontAwesomeIcon
36-
className="text-3xl text-purple-800 cursor-pointer"
37-
icon={faTwitch}
38-
/>
39-
</Link>
40-
</div>
41-
);
6+
return (
7+
<div className="flex items-center justify-around w-full">
8+
<Link href="https://twitter.com/claudio_coder" target="_blank" legacyBehavior>
9+
<FontAwesomeIcon className="text-3xl text-blue-500 cursor-pointer" icon={faSquareTwitter} />
10+
</Link>
11+
<Link href="https://github.com/claudiocoder" target="_blank" legacyBehavior>
12+
<FontAwesomeIcon className="text-3xl text-gray-800 cursor-pointer" icon={faGithub} />
13+
</Link>
14+
<Link href="https://www.linkedin.com/in/cmorenomx" target="_blank" legacyBehavior>
15+
<FontAwesomeIcon className="text-3xl text-blue-800 cursor-pointer" icon={faLinkedin} />
16+
</Link>
17+
<Link href="https://www.twitch.tv/claudio_coder" target="_blank" legacyBehavior>
18+
<FontAwesomeIcon className="text-3xl text-purple-800 cursor-pointer" icon={faTwitch} />
19+
</Link>
20+
</div>
21+
)
4222
}
4323

4424
export default SocialNetwork

src/utils/metadata.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { Metadata } from 'next'
2+
3+
interface MetadataProps {
4+
title: string
5+
description: string
6+
path: string
7+
image?: string
8+
}
9+
10+
const webUrl = 'https://claudiocoder.me'
11+
12+
const defaultImage = `/profile.jpg`
13+
14+
export default function metadata(props: MetadataProps): Metadata {
15+
const { title, description: desc, path } = props
16+
17+
const description = desc + ' | @claudio_coder'
18+
19+
const images = webUrl + defaultImage
20+
21+
return {
22+
title,
23+
description,
24+
openGraph: {
25+
title,
26+
description,
27+
url: webUrl + path,
28+
siteName: 'claudiocoder.me',
29+
images,
30+
locale: 'es',
31+
},
32+
twitter: {
33+
card: 'summary_large_image',
34+
title,
35+
description,
36+
images,
37+
},
38+
}
39+
}

0 commit comments

Comments
 (0)