feat: add MDX support and blog functionality
- Updated next.config.ts to include MDX support with new page extensions. - Added dependencies for MDX in package.json. - Refactored Home component to include BlogList. - Adjusted layout and styling in Projects and Timeline components. - Implemented dynamic blog post routing with generateStaticParams and BlogPost component. - Created BlogLayout for consistent blog page structure. - Added initial blog post in MDX format. - Developed BlogList component to display a list of blog posts. - Introduced blog utility functions to read and parse MDX files.
This commit is contained in:
parent
deca6506a9
commit
35f2c41d7b
11 changed files with 431 additions and 5 deletions
30
src/app/blog/[slug/]/page.tsx
Normal file
30
src/app/blog/[slug/]/page.tsx
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import { notFound } from "next/navigation";
|
||||
import { readdirSync } from "fs";
|
||||
import { join } from "path";
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const blogDir = join(process.cwd(), "src/app/blog/posts");
|
||||
const files = readdirSync(blogDir).filter((file) => file.endsWith(".mdx"));
|
||||
|
||||
return files.map((file) => ({
|
||||
slug: file.replace(".mdx", ""),
|
||||
}));
|
||||
}
|
||||
|
||||
export default async function BlogPost({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ slug: string }>;
|
||||
}) {
|
||||
const { slug } = await params;
|
||||
|
||||
try {
|
||||
const Post = (
|
||||
await import(`@/app/blog/posts/${slug}.mdx`)
|
||||
).default;
|
||||
|
||||
return <Post />;
|
||||
} catch {
|
||||
notFound();
|
||||
}
|
||||
}
|
||||
20
src/app/blog/layout.tsx
Normal file
20
src/app/blog/layout.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import type { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Blog",
|
||||
description: "My thoughts and experiences",
|
||||
};
|
||||
|
||||
export default function BlogLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<article className="min-h-screen max-w-3xl mx-auto px-6 py-12">
|
||||
<div className="prose prose-invert max-w-none">
|
||||
{children}
|
||||
</div>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
8
src/app/blog/posts/2024-11-20-first-post.mdx
Normal file
8
src/app/blog/posts/2024-11-20-first-post.mdx
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
title: "삣삐"
|
||||
description: "삣삐"
|
||||
date: "2025-11-20"
|
||||
tags: ["삣삐"]
|
||||
---
|
||||
|
||||
# 삣삐
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
import BlogList from "@/components/BlogList";
|
||||
import NeoFetch from "@/components/NeoFetch";
|
||||
import Projects from "@/components/Projects";
|
||||
import TimelineComponent from "@/components/timeline";
|
||||
import Top from "@/components/Top";
|
||||
|
||||
export default function Home() {
|
||||
export default async function BlogIndex() {
|
||||
return (
|
||||
<main className="min-h-screen">
|
||||
<Top />
|
||||
|
|
@ -17,10 +18,14 @@ export default function Home() {
|
|||
<p>최근에는 정보보안 분야 중 <strong>웹 해킹</strong>에 관심이 많습니다.</p>
|
||||
<br />
|
||||
<p>대표적인 프로젝트들은 아래와 같습니다.</p>
|
||||
<br />
|
||||
<Projects />
|
||||
</div>
|
||||
|
||||
<TimelineComponent />
|
||||
<div className="px-12 mt-8 w-full lg:w-2/3 xl:w-1/2">
|
||||
<BlogList />
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue