이번 글에서는 **SSR(Server-Side Rendering)**을 기반으로
MDX(Markdown + JSX)를 활용한 Next.js 블로그 를 구축하는 방법을 자세히 알아봅니다.
Content Collections 라이브러리를 사용해 효율적인 데이터 관리와 SSR의 장점을 결합한 블로그를 만들어봅시다.
SSR (서버 사이드 렌더링)은 사용자가 페이지를 요청할 때 서버에서 HTML을 생성하여 브라우저로 전송하는 방식입니다.
이 방식은 특히 아래와 같은 이유로 유용합니다:
SSR은 완전한 HTML을 검색 엔진에 제공하므로 SEO 최적화에 유리합니다.
SSR은 사용자가 페이지를 요청할 때 데이터를 서버에서 바로 렌더링하기 때문에 항상 최신 상태를 유지할 수 있습니다.
MDX와 JSON 메타데이터를 SSR로 처리하면 블로그 콘텐츠를 효율적으로 관리할 수 있습니다.
npx create-next-app my-mdx-blog
cd my-mdx-blog
npm install @content-collections/core @content-collections/mdx @fumadocs/content-collections
프로젝트 최상위 위치에 content-collections.ts
파일을 생성하고,
블로그 데이터를 처리하는 컬렉션을 정의합니다:
import { defineCollection, defineConfig } from '@content-collections/core' ;
import {
createMetaSchema,
createDocSchema,
transformMDX
} from '@fumadocs/content-collections/configuration' ;
const blog = defineCollection ({
name: 'blog' ,
directory: 'content/blog' ,
include: '**/*.mdx' ,
schema : ( z ) => {
const docSchema = createDocSchema (z);
return {
... docSchema,
author: z. string (),
date: z. string (). date (). or (z. date ()). optional (),
tags: z. array (z. string ()). optional ()
};
},
transform: transformMDX
});
const blogMetas = defineCollection ({
name: 'blogMeta' ,
directory: 'content/blog' ,
include: '**/meta.json' ,
parser: 'json' ,
schema: createMetaSchema
});
export default defineConfig ({
collections: [blog, blogMetas]
});
blog 컬렉션 : MDX 파일과 메타데이터를 관리합니다.
SSR을 통해 데이터 로드 : 이 설정은 SSR에서 사용하기 위해 데이터를 정리합니다.
app/source.ts
content-collections
에서 데이터를 불러오는 로직을 작성합니다:
import { loader } from 'fumadocs-core/source';
import { createMDXSource } from '@fumadocs/content-collections';
import { allBlogs, allBlogMetas } from '../../content-collections.ts';
export const blog = loader({
baseUrl: '/blog',
source: createMDXSource(allBlogs, allBlogMetas)
});
app/blog/page.tsx
import Link from 'next/link' ;
import { blog } from '@/app/source' ;
export default function BlogPage () {
const posts = [ ... blog. getPages ()]. sort (
( a , b ) =>
new Date (b.data.date ?? b.file.name). getTime () -
new Date (a.data.date ?? a.file.name). getTime ()
);
return (
< main className = "my-14" >
< h1 className = "mb-8 text-5xl font-bold" >블로그</ h1 >
< ul >
{posts. map (( post , index ) => (
< li key = {index}>
< Link href = {post.url}>
< a >
< h2 >{post.data.title}</ h2 >
< p >{post.data.description}</ p >
</ a >
</ Link >
</ li >
))}
</ ul >
</ main >
);
}
app/blog/[slug]/page.tsx
import { blog } from '@/app/source' ;
export default function BlogPostPage ({ params } : { params : { slug : string } }) {
const post = blog. getPage ([params.slug]);
if ( ! post) {
return < div >포스트를 찾을 수 없습니다.</ div >;
}
const { title , description , content } = post.data;
return (
< article >
< h1 className = "text-4xl font-bold" >{title}</ h1 >
< p className = "text-gray-500" >{description}</ p >
< div >{content}</ div >
</ article >
);
}
서버에서 데이터 로드 : content-collections
를 통해 MDX 파일과 메타데이터를 로드합니다.
데이터 전달 : source.ts
에서 데이터를 로드하고, 페이지 컴포넌트로 전달합니다.
페이지 렌더링 : 페이지 컴포넌트에서 데이터를 활용하여 렌더링합니다.
SEO 최적화 : 검색 엔진 최적화를 위한 완전한 HTML 제공.
최신 데이터 : 사용자가 요청할 때마다 최신 데이터를 제공.
유연한 데이터 관리 : MDX와 JSON 메타데이터를 통한 효율적인 데이터 관리.
확장성 : 동적 라우팅과 데이터 로딩을 통한 블로그 확장.
MDX와 Content Collections를 활용하면 강력한 SSR 기반 블로그를 구축할 수 있습니다.
이 방법은 최신 데이터를 제공하면서도 SEO 최적화에 유리하며, 확장성과 관리 편의성을 모두 갖춘 솔루션입니다.