SSG
1.
/data/products.json 파일 추가
[
  {
    "id": "1234",
    "name": "청바지5555",
    "price": "5000"
  },
  {
    "id": "1235",
    "name": "티셔츠",
    "price": "5000"
  },
  {
    "id": "1236",
    "name": "부츠",
    "price": "5000"
  }
]
JavaScript
복사
products.json
2.
/src/service/products.ts 파일 추가
import path from "path"; // Node API
import { promises as fs } from "fs"; // Node API 
export type Product = {
  id: string;
  name: string;
  price: number;
};
export async function getProducts(): Promise<Product[]> {
  const filePath = path.join(process.cwd(), "data", "products.json"); // Node 파일관련함수
  const data = await fs.readFile(filePath, "utf-8"); 
  return JSON.parse(data);
}
export async function getProduct(id: string): Promise<Product | undefined> {
  const products = await getProducts();
  return products.find((item) => item.id === id);
}
JavaScript
복사
3.
/app/products/page.tsx 에서 getProducts() 함수 호출
import { getProducts } from "@/service/products";
import Link from "next/link";
export default async function ProductsPage() {
  // 서버 파일(데이터베이스) 에 있는 제품의 리스트를 읽어와서, 그걸 보여줌.
  const products = await getProducts();
  return (
    <>
      <h1>제품 소개 페이지</h1>
      <ul>
        {products.map((p, i) => (
          <li key={i}>
            <Link href={`/products/${p.id}`}>{p.name}</Link>
          </li>
        ))}
      </ul>
    </>
  );
}
JavaScript
복사
4.
/app/products/[slug]/page.tsx 에서 getProduct(id)와 getProducts()를 호출한다.
import { getProduct, getProducts } from "@/service/products";
import { Metadata } from "next";
import { notFound } from "next/navigation";
type Props = {
  params: {
    slug: string;
  };
};
function generateMetadata({ params }: Props) {
  return {
    title: `제품의 이름: ${params.slug}`,
    description: "멋진 제품을 확인하세요..",
    icons: {
      icon: "/favicon.ico",
    },
  };
}
export default async function ProductItems({ params: { slug } }: Props) {
  const product = await getProduct(slug);
  if (!product) {
    notFound();
  }
  // 서버 파일에 있는 데이터중 해당 제품의 정보를 찾아서 그걸 보여줌.
  return <div>{product.name} 제품 설명 페이지</div>;
}
async function generateStaticParams() {
  const products = await getProducts();
  return products.map((product) => ({
    slug: product.id,
  }));
}
JavaScript
복사
ISR
revalidate 를 추가한다.
import { getProducts } from "@/service/products";
import Link from "next/link";
export const revalidate = 3;
export default async function ProductsPage() {
  const products = await getProducts();
  return (
    <>
      <h1>제품 소개 페이지</h1>
      <ul>
        {products.map((p, i) => (
          <li key={i}>
            <Link href={`/products/${p.id}`}>{p.name}</Link>
          </li>
        ))}
      </ul>
    </>
  );
}
JavaScript
복사
/app/products/page.tsx
import { getProduct, getProducts } from "@/service/products";
import { Metadata } from "next";
import { notFound } from "next/navigation";
export const revalidate = 3; // 3초 - 서버기준
type Props = {
  params: {
    slug: string;
  };
};
function generateMetadata({ params }: Props) {
  return {
    title: `제품의 이름: ${params.slug}`,
    description: "멋진 제품을 확인하세요..",
    icons: {
      icon: "/favicon.ico",
    },
  };
}
export default async function ProductItems({ params: { slug } }: Props) {
  const product = await getProduct(slug);
  if (!product) {
    notFound();
  }
  // 서버 파일에 있는 데이터중 해당 제품의 정보를 찾아서 그걸 보여줌.
  return <div>{product.name} 제품 설명 페이지</div>;
}
async function generateStaticParams() {
  const products = await getProducts();
  return products.map((product) => ({
    slug: product.id,
  }));
}
JavaScript
복사
/app/products/[slug]/page.tsx


