-
Notifications
You must be signed in to change notification settings - Fork 18
/
layout.tsx
92 lines (80 loc) · 2.18 KB
/
layout.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import getPosts from '@lib/get-posts'
import Navigation from '@components/content-footer/navigation'
import PostFooter from '@components/content-footer/post-footer'
import styles from './layout.module.css'
import { Metadata } from 'next'
export async function generateStaticParams() {
const posts = await getPosts()
return posts.map((post) => ({ slug: post.slug }))
}
export const generateMetadata = async (
props: {
params: Promise<{
slug: string
}>
}
): Promise<Metadata> => {
const params = await props.params;
const post = (await getPosts()).find((p) => p?.slug === params.slug)
return {
title: post?.title,
description: post?.description,
alternates: {
canonical: `https://maxleiter.com/blog/${params.slug}`,
},
}
}
async function getData({ slug }: { slug: string }) {
const posts = await getPosts()
const postIndex = posts.findIndex((p) => p?.slug === slug)
if (postIndex === -1) {
throw new Error(`${slug} not found in posts. Did you forget to rename the file?`)
}
const post = posts[postIndex]
const { ...rest } = post
return {
previous: posts[postIndex + 1] || null,
next: posts[postIndex - 1] || null,
...rest,
}
}
export default async function PostLayout(
props: {
children: JSX.Element
params: Promise<{
slug: string
}>
}
) {
const params = await props.params;
const {
children
} = props;
const { previous, next, title, date, lastModified } = await getData(params)
const lastModifiedDate = lastModified
? new Date(lastModified).toLocaleDateString('en-US', {
month: 'long',
day: 'numeric',
year: 'numeric',
})
: null
return (
<>
<div className={styles.wrapper}>
<span className={styles.date}>{date}</span>
{lastModified ? (
<span className={styles.lastModified}>
Last modified {lastModifiedDate}
</span>
) : null}
{/* {updatedViews && <FadeIn>{updatedViews} views</FadeIn>} */}
</div>
<article>
<h1 className={styles.title}>{title}</h1>
{children}
</article>
<PostFooter />
<Navigation previous={previous} next={next} />
</>
)
}