티스토리 뷰
JAMstack 기반 포트폴리오 사이트 핵심 기능 개발
1. 프로젝트 핵심 기능 개요
JAMstack 아키텍처를 활용한 포트폴리오 사이트에서는 빠른 성능, 유지보수 편리성, 동적 콘텐츠 지원이 중요하다.
이번 단계에서는 프로젝트 페이지, 블로그 기능, 연락처 페이지 등을 구현하고,
서버리스 API 및 CMS(Content Management System)를 연동하여 동적 데이터 관리를 적용한다.
2. 홈(Home) 페이지 구현
① 홈 페이지 레이아웃 구성
홈 페이지는 방문자에게 빠르게 개발자의 핵심 정보를 제공하는 역할을 한다.
- 자기소개 (이름, 직업, 간단한 소개)
- 기술 스택 (사용하는 기술, 숙련도 표시)
- 주요 프로젝트 하이라이트 (데모 및 GitHub 링크)
- CTA(Call To Action) 버튼 (프로젝트 보기, 블로그 방문, 연락하기)
🔹 홈 페이지 기본 구조 (pages/index.js)
export default function Home() {
return (
<div className="container mx-auto text-center">
<h1 className="text-4xl font-bold">안녕하세요, 개발자 John Doe입니다!</h1>
<p className="text-lg mt-4">JAMstack을 활용한 웹 개발을 전문으로 합니다.</p>
<button className="mt-6 px-4 py-2 bg-blue-500 text-white rounded-lg">
프로젝트 보기
</button>
</div>
);
}
🔹 Tailwind CSS를 활용하여 스타일링 적용
@tailwind base;
@tailwind components;
@tailwind utilities;
3. 프로젝트(Projects) 페이지 구현
① Strapi CMS와 프로젝트 데이터 연동
정적 페이지에서 동적인 프로젝트 데이터를 표시하려면 CMS(Content Management System)를 활용하는 것이 좋다.
Strapi 또는 Contentful API를 사용하여 프로젝트 데이터를 관리하고 불러온다.
🔹 프로젝트 데이터 API 호출 (lib/api.js)
export async function getProjects() {
const res = await fetch("http://localhost:1337/api/projects");
const data = await res.json();
return data;
}
🔹 프로젝트 목록 페이지 (pages/projects.js)
import { getProjects } from "../lib/api";
export default function Projects({ projects }) {
return (
<div className="container mx-auto">
<h1 className="text-3xl font-bold mb-6">포트폴리오 프로젝트</h1>
<ul>
{projects.map((project) => (
<li key={project.id} className="mb-4">
<h2 className="text-xl font-semibold">{project.title}</h2>
<p>{project.description}</p>
<a href={project.link} className="text-blue-500">프로젝트 보기</a>
</li>
))}
</ul>
</div>
);
}
export async function getStaticProps() {
const projects = await getProjects();
return { props: { projects } };
}
4. 블로그(Blog) 페이지 구현
① Markdown 기반 블로그 시스템 구축
JAMstack에서는 정적 사이트 생성을 통해 블로그를 효율적으로 운영할 수 있다.
MDX(Markdown + JSX) 파일을 활용하여 블로그 글을 작성하고, Next.js에서 동적으로 렌더링한다.
🔹 블로그 게시글을 위한 posts 폴더 구조
posts/
├── hello-world.mdx
├── jamstack-guide.mdx
├── serverless-tutorial.mdx
🔹 MDX 포스트 예시 (posts/hello-world.mdx)
---
title: "JAMstack 기반 포트폴리오 개발하기"
date: "2025-03-15"
author: "John Doe"
tags: ["JAMstack", "Next.js", "Serverless"]
---
# JAMstack이란 무엇인가?
JAMstack은 **JavaScript, API, Markup**의 조합으로 구성된 최신 웹 개발 방식입니다...
🔹 Next.js에서 MDX를 지원하도록 설정 (next.config.js)
const withMDX = require('@next/mdx')({
extension: /\.mdx?$/
});
module.exports = withMDX({
pageExtensions: ['js', 'jsx', 'md', 'mdx']
});
🔹 블로그 목록 페이지 (pages/blog.js)
import fs from "fs";
import path from "path";
import matter from "gray-matter";
import Link from "next/link";
export default function Blog({ posts }) {
return (
<div className="container mx-auto">
<h1 className="text-3xl font-bold mb-6">기술 블로그</h1>
<ul>
{posts.map((post) => (
<li key={post.slug} className="mb-4">
<Link href={`/blog/${post.slug}`}>
<h2 className="text-xl font-semibold text-blue-500">{post.title}</h2>
</Link>
<p>{post.date}</p>
</li>
))}
</ul>
</div>
);
}
export async function getStaticProps() {
const postsDirectory = path.join(process.cwd(), "posts");
const filenames = fs.readdirSync(postsDirectory);
const posts = filenames.map((filename) => {
const filePath = path.join(postsDirectory, filename);
const fileContent = fs.readFileSync(filePath, "utf8");
const { data } = matter(fileContent);
return {
slug: filename.replace(".mdx", ""),
...data
};
});
return { props: { posts } };
}
5. 연락처(Contact) 페이지 구현
① 서버리스 API(OpenFaaS)로 이메일 전송 기능 추가
🔹 서버리스 함수 작성 (email-api/handler.js)
const nodemailer = require("nodemailer");
module.exports = async (event, context) => {
const { email, message } = JSON.parse(event.body);
let transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS
}
});
await transporter.sendMail({
from: email,
to: "admin@example.com",
subject: "새로운 문의",
text: message
});
return {
statusCode: 200,
body: JSON.stringify({ success: true })
};
};
🔹 OpenFaaS에 API 배포
faas-cli new send-email --lang node12
cd send-email
faas-cli up -f send-email.yml
🔹 연락처 폼 페이지 (pages/contact.js)
import { useState } from "react";
export default function Contact() {
const [form, setForm] = useState({ email: "", message: "" });
async function handleSubmit(e) {
e.preventDefault();
await fetch("/function/send-email", {
method: "POST",
body: JSON.stringify(form),
headers: { "Content-Type": "application/json" }
});
alert("문의가 전송되었습니다!");
}
return (
<form onSubmit={handleSubmit}>
<input type="email" placeholder="이메일" onChange={(e) => setForm({ ...form, email: e.target.value })} />
<textarea placeholder="메시지" onChange={(e) => setForm({ ...form, message: e.target.value })} />
<button type="submit">전송</button>
</form>
);
}
6. 결론
✅ 홈, 프로젝트, 블로그, 연락처 페이지 구현 완료
✅ Strapi CMS, MDX, OpenFaaS API 연동하여 동적 콘텐츠 처리
✅ 서버리스 API 활용하여 이메일 문의 기능 추가
'project > 포트폴리오만들기' 카테고리의 다른 글
JAMstack 기반 포트폴리오 사이트의 배포 및 운영 (Mac Mini + Docker 기반 서버리스 프레임워크) (0) | 2025.03.15 |
---|---|
JAMstack 기반 포트폴리오 사이트 최적화 및 추가 기능 구현 (0) | 2025.03.15 |
JAMstack 기반 포트폴리오 사이트 개발을 위한 기술 스택 선택 (0) | 2025.03.14 |
JAMstack 기반 포트폴리오 사이트 개발 컨셉 (0) | 2025.03.14 |
[React] Github page로 포트폴리오 웹페이지 만들기 #16 About 페이지를 완성해 보자! (0) | 2022.07.07 |
- Total
- Today
- Yesterday
- 백엔드개발
- 관리자
- github
- Next.js
- 프론트엔드
- Python
- nodejs
- kotlin
- 프론트엔드면접
- Prisma
- App Router
- REACT
- SEO최적화
- 개발블로그
- llm
- Webpack
- LangChain
- PostgreSQL
- SEO 최적화
- nextJS
- Ktor
- gatsbyjs
- NestJS
- rag
- 웹개발
- AI챗봇
- CI/CD
- fastapi
- seo 최적화 10개
- Docker
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |