Skip to content

Commit 2ced04a

Browse files
committed
fix: prerender fewer pages
1 parent 829e426 commit 2ced04a

3 files changed

Lines changed: 177 additions & 159 deletions

File tree

apps/next-blog/next.config.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ const nextConfig = {
2121
typescript: {
2222
ignoreBuildErrors: true,
2323
},
24+
25+
staticPageGenerationTimeout: 120,
2426
output: "standalone",
2527
// reactStrictMode: true,
2628
// i18n: {
Lines changed: 62 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,76 @@
1-
import { SITE } from '../../config.mjs'
1+
import { draftMode } from "next/headers";
2+
import { notFound } from "next/navigation";
3+
import { SITE } from "../../config.mjs";
4+
import { getAllPosts, getPostBy, getSinglePost } from "../../utils/blog";
5+
import { createMetadata } from "../../utils/createMetadata";
6+
import { getAcademicOtherSeo } from "../../utils/getAcademicOtherSEO";
7+
import { cleanSlug } from "../../utils/permalinks";
8+
import { SinglePost } from "../components/blog/SinglePost";
29

3-
import { SinglePost } from '../components/blog/SinglePost'
4-
5-
import { cleanSlug } from '../../utils/permalinks'
6-
import { getPostBy, getAllPosts, getSinglePost } from '../../utils/blog'
7-
import { createMetadata } from '../../utils/createMetadata'
8-
import { notFound } from 'next/navigation'
9-
10-
import { getAcademicOtherSeo } from '../../utils/getAcademicOtherSEO'
11-
import { draftMode } from 'next/headers'
12-
13-
export async function generateMetadata({ params }: { params: { post: string } }) {
14-
const post = await getPostBy({ field: 'slug', value: params.post })
15-
if (!post) {
16-
return createMetadata({})
17-
}
18-
return createMetadata(
19-
{
20-
title: `${post.title}${SITE.name}`,
21-
description: post.seo?.metaDescription ?? post.excerpt,
22-
canonical: post.slug ?? '',
23-
image: post.image?.formats?.thumbnail?.url ?? post.image.url,
24-
ogTitle: post.title,
25-
},
26-
{ other: getAcademicOtherSeo(post) },
27-
)
10+
export async function generateMetadata({
11+
params,
12+
}: {
13+
params: { post: string };
14+
}) {
15+
const post = await getPostBy({ field: "slug", value: params.post });
16+
if (!post) {
17+
return createMetadata({});
18+
}
19+
return createMetadata(
20+
{
21+
title: `${post.title}${SITE.name}`,
22+
description: post.seo?.metaDescription ?? post.excerpt,
23+
canonical: post.slug ?? "",
24+
image: post.image?.formats?.thumbnail?.url ?? post.image.url,
25+
ogTitle: post.title,
26+
},
27+
{ other: getAcademicOtherSeo(post) },
28+
);
2829
}
2930

3031
export async function generateStaticParams() {
31-
// const posts = await fetchPosts()
32-
const posts = (await getAllPosts()) ?? []
32+
// const posts = await fetchPosts()
33+
const posts = (await getAllPosts()) ?? [];
34+
const orderedByLatest = posts.sort(
35+
(a, b) =>
36+
new Date(b.publishDate ?? b.publishedAt ?? "").getTime() -
37+
new Date(a.publishDate ?? a.publishedAt ?? "").getTime(),
38+
);
3339

34-
const pars = posts.map((post, idx) => ({
35-
post: cleanSlug(post.slug ?? '/'),
36-
}))
40+
// only prerender the latest 20 posts
41+
const pars = posts.slice(0, 20).map((post, idx) => ({
42+
post: cleanSlug(post.slug ?? "/"),
43+
}));
3744

38-
return pars
45+
return pars;
3946
}
4047

4148
export default async function Post({ params }: { params: { post: string } }) {
42-
const { isEnabled } = draftMode()
49+
const { isEnabled } = draftMode();
4350

44-
const { post: slug } = params
45-
const posts = (await getAllPosts(isEnabled)) ?? []
46-
// const post = posts.find((post) => cleanSlug(post.slug ?? '/') === slug)
47-
const post = await getSinglePost(slug, isEnabled)
48-
const idx = posts.findIndex((post) => cleanSlug(post.slug ?? '/') === slug)
49-
const prev = posts[idx - 1]
50-
const next = posts[idx + 1]
51+
const { post: slug } = params;
52+
const posts = (await getAllPosts(isEnabled)) ?? [];
53+
// const post = posts.find((post) => cleanSlug(post.slug ?? '/') === slug)
54+
const post = await getSinglePost(slug, isEnabled);
55+
const idx = posts.findIndex((post) => cleanSlug(post.slug ?? "/") === slug);
56+
const prev = posts[idx - 1];
57+
const next = posts[idx + 1];
5158

52-
// const date = post?.publishDate ?? post?.publishedAt
53-
// const nextNext = getNextPublishPost(date ? new Date(date) : new Date())
54-
// console.log(next.slug, nextNext?.slug)
55-
const latest = posts.filter((latest) => latest.id !== post?.id).slice(0, 4)
59+
// const date = post?.publishDate ?? post?.publishedAt
60+
// const nextNext = getNextPublishPost(date ? new Date(date) : new Date())
61+
// console.log(next.slug, nextNext?.slug)
62+
const latest = posts.filter((latest) => latest.id !== post?.id).slice(0, 4);
5663

57-
if (!post) {
58-
notFound()
59-
}
64+
if (!post) {
65+
notFound();
66+
}
6067

61-
return (
62-
<SinglePost latest={latest} prev={prev} next={next} post={{ ...post, image: post.image }} />
63-
)
68+
return (
69+
<SinglePost
70+
latest={latest}
71+
prev={prev}
72+
next={next}
73+
post={{ ...post, image: post.image }}
74+
/>
75+
);
6476
}
Lines changed: 113 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -1,121 +1,125 @@
1-
import { BlogPost } from '@/types'
2-
import { getAllPosts } from '../../../utils/blog'
3-
import { Pagination } from '../../components/blog/Pagination'
4-
import { PostCard } from '../../components/blog/PostCard'
5-
import { notFound } from 'next/navigation'
6-
import { getUniqueCategoriesAndTags } from '../../../utils/getUniqueCategoriesAndTags'
1+
import { notFound } from "next/navigation";
2+
import type { BlogPost } from "@/types";
3+
import { getAllPosts } from "../../../utils/blog";
4+
import { getUniqueCategoriesAndTags } from "../../../utils/getUniqueCategoriesAndTags";
5+
import { Pagination } from "../../components/blog/Pagination";
6+
import { PostCard } from "../../components/blog/PostCard";
77

8-
export async function generateStaticParams() {
9-
const posts = (await getAllPosts()) ?? []
8+
// export const
109

11-
const postsPerPage = 10
10+
// export async function generateStaticParams() {
11+
// const posts = (await getAllPosts()) ?? []
1212

13-
const totalPages = Math.ceil(posts.length / postsPerPage)
13+
// const postsPerPage = 10
1414

15-
const blogPages = Array.from({ length: totalPages }, (_, i) => ({
16-
page: (i + 1).toString(),
17-
}))
18-
const { categories, tags } = getUniqueCategoriesAndTags(posts)
15+
// const totalPages = Math.ceil(posts.length / postsPerPage)
1916

20-
const categoryPages = categories.map((category) => ({
21-
page: category.slug,
22-
}))
17+
// const blogPages = Array.from({ length: totalPages }, (_, i) => ({
18+
// page: (i + 1).toString(),
19+
// }))
20+
// const { categories, tags } = getUniqueCategoriesAndTags(posts)
2321

24-
const tagPages = tags.map((tag) => ({
25-
page: tag.slug,
26-
}))
27-
const allPages = [...blogPages, ...categoryPages, ...tagPages]
22+
// const categoryPages = categories.map((category) => ({
23+
// page: category.slug,
24+
// }))
2825

29-
return allPages
30-
}
26+
// const tagPages = tags.map((tag) => ({
27+
// page: tag.slug,
28+
// }))
29+
// const allPages = [...blogPages, ...categoryPages, ...tagPages]
30+
31+
// return allPages
32+
// }
3133

3234
export default async function BlogPage({
33-
params: { page },
35+
params: { page },
3436
}: {
35-
params: { page: string; final: string }
37+
params: { page: string; final: string };
3638
}) {
37-
const posts: BlogPost[] = (await getAllPosts()) ?? []
38-
let actualPosts: BlogPost[] = []
39-
40-
const { categories, tags } = getUniqueCategoriesAndTags(posts)
41-
42-
let intPage = 0
43-
let nextUrl = ''
44-
let prevUrl = ''
45-
46-
let isBasicBlog = false
47-
48-
try {
49-
intPage = parseInt(page)
50-
} catch (e) {}
51-
52-
const pageType =
53-
intPage && !isNaN(intPage)
54-
? 'blog'
55-
: tags.some((tag) => tag.slug === page)
56-
? 'tag'
57-
: categories.some((cat) => cat.slug === page)
58-
? 'category'
59-
: ''
60-
61-
if (!pageType) {
62-
return notFound()
63-
}
64-
65-
let title = 'Blog'
66-
67-
if (pageType === 'blog') {
68-
if (intPage < 1 || intPage > posts.length / 10 + 1) {
69-
return notFound()
70-
}
71-
isBasicBlog = true
72-
73-
actualPosts = posts.slice((intPage - 1) * 10, intPage * 10)
74-
const hasNext = intPage < posts.length / 10 + 1
75-
const hasPrev = intPage > 1
76-
77-
nextUrl = hasNext ? `/blog/${intPage + 1}` : ''
78-
prevUrl = hasPrev ? `/blog/${intPage - 1}` : ''
79-
}
80-
81-
if (pageType === 'category') {
82-
actualPosts = posts.filter((post) => {
83-
if (post.category?.slug === page) {
84-
title = post.category?.title
85-
return true
86-
}
87-
return false
88-
})
89-
}
90-
91-
if (pageType === 'tag') {
92-
actualPosts = posts.filter((post) =>
93-
post.blog_tags?.some((tag) => {
94-
if (tag.slug === page) {
95-
title = tag.title
96-
return true
97-
}
98-
return false
99-
}),
100-
)
101-
}
102-
103-
const Title =
104-
pageType === 'blog' ? (
105-
<h1 className="inline text-center font-sans text-8xl font-black">Blog</h1>
106-
) : pageType === 'tag' ? (
107-
<h1 className="button px-4 py-1 text-xl">{title}</h1>
108-
) : (
109-
<h1 className="border-2 border-black bg-orange-500 px-4 py-1 text-2xl font-bold">{title}</h1>
110-
)
111-
112-
return (
113-
<>
114-
<div className="flex h-40 items-center">{Title}</div>
115-
{actualPosts?.map((post) => (
116-
<PostCard post={post} wide key={post.id} />
117-
))}
118-
{isBasicBlog && <Pagination prevUrl={prevUrl} nextUrl={nextUrl} />}
119-
</>
120-
)
39+
const posts: BlogPost[] = (await getAllPosts()) ?? [];
40+
let actualPosts: BlogPost[] = [];
41+
42+
const { categories, tags } = getUniqueCategoriesAndTags(posts);
43+
44+
let intPage = 0;
45+
let nextUrl = "";
46+
let prevUrl = "";
47+
48+
let isBasicBlog = false;
49+
50+
try {
51+
intPage = parseInt(page);
52+
} catch (e) {}
53+
54+
const pageType =
55+
intPage && !isNaN(intPage)
56+
? "blog"
57+
: tags.some((tag) => tag.slug === page)
58+
? "tag"
59+
: categories.some((cat) => cat.slug === page)
60+
? "category"
61+
: "";
62+
63+
if (!pageType) {
64+
return notFound();
65+
}
66+
67+
let title = "Blog";
68+
69+
if (pageType === "blog") {
70+
if (intPage < 1 || intPage > posts.length / 10 + 1) {
71+
return notFound();
72+
}
73+
isBasicBlog = true;
74+
75+
actualPosts = posts.slice((intPage - 1) * 10, intPage * 10);
76+
const hasNext = intPage < posts.length / 10 + 1;
77+
const hasPrev = intPage > 1;
78+
79+
nextUrl = hasNext ? `/blog/${intPage + 1}` : "";
80+
prevUrl = hasPrev ? `/blog/${intPage - 1}` : "";
81+
}
82+
83+
if (pageType === "category") {
84+
actualPosts = posts.filter((post) => {
85+
if (post.category?.slug === page) {
86+
title = post.category?.title;
87+
return true;
88+
}
89+
return false;
90+
});
91+
}
92+
93+
if (pageType === "tag") {
94+
actualPosts = posts.filter((post) =>
95+
post.blog_tags?.some((tag) => {
96+
if (tag.slug === page) {
97+
title = tag.title;
98+
return true;
99+
}
100+
return false;
101+
}),
102+
);
103+
}
104+
105+
const Title =
106+
pageType === "blog" ? (
107+
<h1 className="inline text-center font-sans text-8xl font-black">Blog</h1>
108+
) : pageType === "tag" ? (
109+
<h1 className="button px-4 py-1 text-xl">{title}</h1>
110+
) : (
111+
<h1 className="border-2 border-black bg-orange-500 px-4 py-1 text-2xl font-bold">
112+
{title}
113+
</h1>
114+
);
115+
116+
return (
117+
<>
118+
<div className="flex h-40 items-center">{Title}</div>
119+
{actualPosts?.map((post) => (
120+
<PostCard post={post} wide key={post.id} />
121+
))}
122+
{isBasicBlog && <Pagination prevUrl={prevUrl} nextUrl={nextUrl} />}
123+
</>
124+
);
121125
}

0 commit comments

Comments
 (0)