포스트 상세 페이지 (더미 데이터)

cxaosdev·2025년 7월 30일
post-thumbnail

더미 데이터

src/lib/posts.ts

백엔드 연동 전에 우선 사용할 더미 데이터!

export const posts = [
  {
    slug: "start-blog",
    title: "블로그 시작! 계획과 구조",
    content: `...`,
  },
  {
    slug: "why-next",
    title: "왜 Next일까?",
    content: `...`,
  },
];

export function getPostBySlug(slug: string) {
  return posts.find((post) => post.slug === slug);
}

두개의 데이터를 넣어줬고 slug로 객체를 찾아 반환하는 getPostBySlug도 만들어줬다.

App Route

GET API 핸들러

app/api/posts/[slug]/route.ts

import { NextResponse } from "next/server";
import { getPostBySlug } from "@/lib/posts";

export async function GET(
  req: Request,
  { params }: { params: { slug: string } }
) {
  const post = getPostBySlug(params.slug);

  if (!post) {
    return NextResponse.json(null, { status: 404 });

  return NextResponse.json(post);
}

나중에 DB 연결 하면 수정 예정

NextResponse:
Response 객체를 확장한 Next 전용 응답 유틸리티! Next에서 쿠키 설정, 리다이렉트, rewrite 등 확장이 가능하다고 한다.

포스트 상세 페이지

src/app/posts/[slug]/page.tsx

URL에서 slug 값을 받아서 해당 slug에 해당하는 게시글을 요청해서에서 가져오고, Markdown를 파싱하고 HTML 형태로 브라우저에 렌더링하기!

import { marked } from "marked";
import { notFound } from "next/navigation";

export default async function PostPage({
  params,
}: {
  params: { slug: string };
}) {
  const res = await fetch(`http://localhost:3000/api/posts/${params.slug}`, {
    cache: "no-store",
  });

  if (!res.ok) return notFound();

  const post = await res.json();
  const html = marked(post.content);

  return (
    <article className="prose prose-invert prose-lg md:prose-xl lg:prose-xl mx-auto px-6 py-10">
      <h1 className="text-center">{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: html }} />
    </article>
  );
}

요청해서 받아온 걸 파싱해서 postcontentmarked 라이브러리로 HTML 문자열로 바꿔주고 dangerouslySetInnerHTML로 렌더링

cache: "no-store":
기본적으로 Next.js는 페이지를 캐싱하는데 이게 처음으로 페이지를 들어가면 다음 요청 때 까지 저장둬서 속도는 빨라짐. 근데 내가 만드는건 블로그니까. 수정이되고 하면 항상 최신의 글을 보여줘야 하니까 no-store가 맞다. 이렇게 하면 매번 API를 새로 호출해서 최신 데이터를 가져온다.
그리고 이부분은 지금만 이렇게 해두고 나중에 ISR로 일정 주기마다 HTML을 재생성하게 해주면 이부분을 지워도 될 것 같다.

prose:
Tailwind Typography 플러그인을 사용해서 예쁘게 HTML 스타일도 적용시킴

성공

http://localhost:3000/posts/why-next로 접속하면 해당되는 포스트가 보인다.

이제 이 포스트 상세 페이지를 메인 페이지에서 연결시키면 될 것 같다. 다음!

profile
FE developer

0개의 댓글