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