포트폴리오 사이트 만들기 - Next
소개
안녕하세요! 웹스토리보이입니다. 이제 정말 마지막단계입니다. 지금까지 잘 따라오셨습니다. 마지막까지 최선을 다해 성공합시다. 화이팅 👍
포트폴리오 사이트 만들기
VITE SITE
- 1. 셋팅하기
- 1_1. vite 설치하기
- 1_2. vite 폴더 정리하기
- 1_3. gsap/lenis 설치하기
- 1_4. git 연동하기
- 2. 레이아웃
- 2.1 레이아웃 구조 만들기
- 2.2 메인 레이아웃 구조 만들기
- 2.3 CSS 셋팅하기
- 2.4 JavaScript 셋팅하기
- 3. 헤더 영역
- 3.1 헤더 구조 잡기
- 3.2 헤더 디자인 설정
- 3.3 반응형 작업하기
- 3.4 메뉴 자바스크립트 설정
- 4. 인트로 영역
- 4.1 인트로 구조 잡기
- 4.2 인트로 디자인 설정
- 4.3 반응형 작업하기
- 5. 스킬 영역
- 5.1 스킬 구조 잡기
- 5.2 스킬 디자인 설정
- 5.3 반응형 작업하기
- 6. 사이트 영역
- 6.1 사이트 구조 잡기
- 6.2 사이트 디자인 설정
- 6.3 반응형 작업하기
- 7. 포트폴리오 영역
- 7.1 사이트 구조 잡기
- 7.2 사이트 디자인 설정
- 7.3 반응형 작업하기
- 7.4 스크립트 작업하기
- 8. 연락처 영역
- 8.1 연락처 구조 잡기
- 8.2 연락처 디자인 설정
- 8.3 반응형 작업하기
- 9. 푸터 영역
- 9.1 푸터 구조 잡기
- 9.2 푸터 디자인 설정
- 9.3 반응형 작업하기
- 10. 마무리
- 10.1 스무스 효과주기
- 10.2 링크 연결하기
- 10.3 netlify에 배포하기
REACT SITE
- 1. 셋팅하기
- 1_1. React 설치하기
- 1_2. React 폴더 정리하기
- 1_3. 라이브러리 설치하기
- 1_4. git 연동하기
- 2. 라우팅 및 컴퍼넌트
- 2_1. 라우팅 설정하기
- 2_2. 컴퍼넌트 설정하기
- 2_3. SCSS 설정하기
- 3. 헤더 영역
- 3_1. 헤더 구조잡기
- 3_2. 헤더 디자인 설정
- 3_3. 헤더 데이터 작업
- 3_4. 헤더 토글 메뉴 작업하기
- 4. 인트로 영역
- 4_1. 인트로 구조잡기
- 4_2. 인트로 디자인 설정
- 4_3. 인트로 데이터 작업
- 5. 스킬 영역
- 5_1. 스킬 구조잡기
- 5_2. 스킬 디자인 설정
- 5_3. 스킬 데이터 작업
- 6. 사이트 영역
- 6_1. 사이트 구조잡기
- 6_2. 사이트 디자인 설정
- 6_3. 사이트 데이터 작업
- 7. 포트폴리오 영역
- 7_1. 포트폴리오 구조잡기
- 7_2. 포트폴리오 디자인 설정
- 7_3. 포트폴리오 데이터 작업
- 8. 연락처 영역
- 8_1. 연락처 구조잡기
- 8_2. 연락처 디자인 설정
- 8_3. 연락처 데이터 작업
- 9. 푸터 영역
- 9_1. 푸터 구조잡기
- 9_2. 푸터 디자인 설정
- 9_3. 푸터 데이터 작업
- 10. 마무리
- 10_1. 데이터 통합하기
- 10_2. 스무스 효과 넣어주기
- 10_3. 가로모드 구현하기
- 10_4. netlify에 배포하기
VUE SITE
- 1. 셋팅하기
- 1_1. Vue 설치하기
- 1_2. Vue 폴더 정리하기
- 1_3. 라이브러리 설치하기
- 1_4. git 연동하기
- 2. 라우팅 및 컴퍼넌트
- 2_1. 라우팅 설정하기
- 2_2. 컴퍼넌트 설정하기
- 2_3. SCSS 설정하기
- 3. 헤더 영역
- 3_1. 헤더 구조잡기
- 3_2. 헤더 디자인 설정
- 3_3. 헤더 데이터 작업
- 3_4. 헤더 토글 메뉴 작업하기
- 4. 인트로 영역
- 4_1. 인트로 구조잡기
- 4_2. 인트로 디자인 설정
- 4_3. 인트로 데이터 작업
- 5. 스킬 영역
- 5_1. 스킬 구조잡기
- 5_2. 스킬 디자인 설정
- 5_3. 스킬 데이터 작업
- 6. 사이트 영역
- 6_1. 사이트 구조잡기
- 6_2. 사이트 디자인 설정
- 6_3. 사이트 데이터 작업
- 7. 포트폴리오 영역
- 7_1. 포트폴리오 구조잡기
- 7_2. 포트폴리오 디자인 설정
- 7_3. 포트폴리오 데이터 작업
- 8. 연락처 영역
- 8_1. 연락처 구조잡기
- 8_2. 연락처 디자인 설정
- 8_3. 연락처 데이터 작업
- 9. 푸터 영역
- 9_1. 푸터 구조잡기
- 9_2. 푸터 디자인 설정
- 9_3. 푸터 데이터 작업
- 10. 마무리
- 10_1. 스무스 효과 넣어주기
- 10_2. 가로모드 구현하기
- 10_3. 링크 클릭 구현하기
- 10_4. netlify에 배포하기
NEXT SITE
- 1. 셋팅하기
- 1_1. Next 설치하기
- 1_2. Next 폴더 정리하기
- 1_3. 라이브러리 설치하기
- 1_4. git 연동하기
- 2. 라우팅 및 컴퍼넌트
- 2_1. 라우팅 설정하기
- 2_2. 컴퍼넌트 설정하기
- 2_3. SCSS 설정하기
- 2_4. Script 설정하기
- 3. 헤더 영역
- 3_1. 헤더 구조잡기
- 3_2. 헤더 디자인 설정
- 3_3. 헤더 데이터 작업
- 3_4. 헤더 토글 메뉴 작업하기
- 4. 인트로 영역
- 4_1. 인트로 구조잡기
- 4_2. 인트로 디자인 설정
- 4_3. 인트로 데이터 작업
- 5. 스킬 영역
- 5_1. 스킬 구조잡기
- 5_2. 스킬 디자인 설정
- 5_3. 스킬 데이터 작업
- 6. 사이트 영역
- 6_1. 사이트 구조잡기
- 6_2. 사이트 디자인 설정
- 6_3. 사이트 데이터 작업
- 7. 포트폴리오 영역
- 7_1. 포트폴리오 구조잡기
- 7_2. 포트폴리오 디자인 설정
- 7_3. 포트폴리오 데이터 작업
- 8. 연락처 영역
- 8_1. 연락처 구조잡기
- 8_2. 연락처 디자인 설정
- 8_3. 연락처 데이터 작업
- 9. 푸터 영역
- 9_1. 푸터 구조잡기
- 9_2. 푸터 디자인 설정
- 9_3. 푸터 데이터 작업
- 10. 마무리
- 10_1. 스무스 효과 넣어주기
- 10_2. 링크 클릭 구현하기
- 10_3. 가로모드 구현하기
- 10_4. netlify에 배포하기
10. 마무리
10.1 스무스 효과 넣어주기
스크립트 셋팅은 처음에 다 해줬기 때문에 lenis.js
에 파일만 넣어주면 됩니다.
import Lenis from "@studio-freight/lenis";
const lenis = () => {
const lenis = new Lenis({
duration: 1,
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
});
function raf(time) {
lenis.raf(time);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
lenis.on("scroll", (e) => {
console.log(e);
});
};
export default lenis;
10.2 링크 클릭 구현하기
이 부분도 link.js
에 다음과 같이 작업합니다.
const link = () => {
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
anchor.addEventListener("click", function (e) {
e.preventDefault();
const targetId = this.getAttribute("href");
const targetElement = document.querySelector(targetId);
if (targetElement) {
targetElement.scrollIntoView({ behavior: "smooth" });
}
});
});
};
export default link;
- const link = () => { ... }: link라는 이름의 화살표 함수(arrow function)를 정의합니다. 이 함수는 스크롤 내비게이션 기능을 구현하는 로직을 담고 있습니다.
- document.querySelectorAll('a[href^="#"]').forEach((anchor) => { ... }): 문서(Document) 내에서 href 속성이 #으로 시작하는 모든 <a>(앵커) 요소들을 선택합니다. 이후 forEach 메서드를 사용하여 선택된 모든 앵커 요소들에 대해 콜백 함수를 실행합니다.
- anchor.addEventListener("click", function (e) { ... }): 각 앵커 요소에 클릭 이벤트 리스너를 추가합니다. 이렇게 하면 앵커를 클릭할 때마다 콜백 함수가 실행됩니다.
- e.preventDefault();: 이벤트의 기본 동작을 취소합니다. 앵커를 클릭하면 기본적으로 해당 앵커의 링크로 이동하는 동작을 취소하여 페이지가 새로고침되지 않도록 합니다.
- const targetId = this.getAttribute("href");: 클릭된 앵커의 href 속성 값을 가져옵니다. 이 값은 클릭한 앵커의 목적지 요소를 찾는데 사용됩니다.
- const targetElement = document.querySelector(targetId);: targetId로 지정된 요소를 문서에서 찾습니다. targetId는 #을 포함한 앵커의 링크값이므로, 해당 앵커의 링크로 이동할 위치의 요소를 검색합니다.
- if (targetElement) { ... }: targetElement가 존재하면, 즉 링크로 이동할 위치의 요소가 존재하면 다음 블록을 실행합니다.
- targetElement.scrollIntoView({ behavior: "smooth" });: targetElement로 지정된 요소로 스크롤을 부드럽게 이동합니다. 이 때 behavior: "smooth" 옵션을 사용하여 스크롤이 부드럽게 이동하도록 합니다.
10.3 가로모드 구현하기
포트폴리오를 보여주는 가로모드를 구현하겠습니다.
이 부분은 port.jsx
에서 작업을 하겠습니다.
import React, { useEffect, useRef } from "react";
import Image from "next/image";
import { portText } from "../constants";
import { gsap } from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
const Port = () => {
const horizontalRef = useRef(null);
const sectionsRef = useRef([]);
useEffect(() => {
gsap.registerPlugin(ScrollTrigger);
const horizontal = horizontalRef.current;
const sections = sectionsRef.current;
let scrollTween = gsap.to(sections, {
xPercent: -120 * (sections.length - 1),
ease: "none",
scrollTrigger: {
trigger: horizontal,
start: "top 56px",
end: () => "+=" + horizontal.offsetWidth,
pin: true,
scrub: 1,
invalidateOnRefresh: true,
anticipatePin: 1,
},
});
return () => {
scrollTween.kill();
};
}, []);
return (
<section id="port" ref={horizontalRef}>
<div className="port__inner">
<h2 className="port__title">
portfolio <em>포폴 작업물</em>
</h2>
<div className="port__wrap">
{portText.map((port, key) => (
<article
className={`port__item p${key + 1}`}
key={key}
ref={(el) => (sectionsRef.current[key] = el)}
>
<span className="num">{port.num}.</span>
<a href={port.code} target="_blank" className="img" rel="noreferrer">
<Image src={port.img} alt={port.title} width={420} height={262} />
</a>
<h3 className="title">{port.title}</h3>
<p className="desc">{port.desc}</p>
<a href={port.view} target="_blank" className="site" rel="noreferrer">사이트 보기</a>
</article>
))}
</div>
</div>
</section>
)
}
export default Port
- useEffect는 컴포넌트가 렌더링된 후에 특정 동작을 실행하는 훅입니다. 여기서는 GSAP의 ScrollTrigger 플러그인을 등록하고, 가로 스크롤 애니메이션을 적용하는 로직을 설정합니다. 의존성 배열 []을 전달하여 마운트된 후 한 번만 실행되도록 합니다.
- useRef는 React에서 DOM 노드 또는 다른 값의 변경 여부를 감지할 때 사용하는 훅입니다. 여기서 horizontalRef는 가로 스크롤 컨테이너를 가리키는 DOM 노드를 참조하고, sectionsRef는 각 포트폴리오 항목 요소들을 참조하는 배열을 생성합니다.
10.4 netlify에 배포하기
깃헙에 모든 소스를 올리겠습니다.
git add .
git commit -m "🥺 마무리 완료"
git push -u origin main
이제 빌드를 한번해보겠습니다. 지금까지 작업했던 소스는 브라우저가 읽을 수 없습니다. 브라우저가 읽을 수 있도록 컴파일을 해주고 빌드 작업을 해주어야 브라우저에서 볼 수 있습니다. 빌드 과정을 통해 소스는 가벼워지고 효율성이 증가됩니다.
$ npm run build
빌드화 과정을 거치면 .next 폴더에 파일이 생깁니다.
webstoryboy@Webstoryboyui-MacBookPro next-site % npm run build
> next-site@0.1.0 build
> next build
Warning: For production Image Optimization with Next.js, the optional 'sharp' package is strongly recommended. Run 'yarn add sharp', and Next.js will use it automatically for Image Optimization.
Read more: https://nextjs.org/docs/messages/sharp-missing-in-production
- info Creating an optimized production build
- info Compiled successfully
- info Linting and checking validity of types
- info Collecting page data
- info Generating static pages (3/3)
- info Finalizing page optimization
Route (app) Size First Load JS
─ ○ / 58.6 kB 137 kB
+ First Load JS shared by all 78.1 kB
├ chunks/596-502b6f304d168aed.js 25.7 kB
├ chunks/fd9d1056-c9f151c58d427982.js 50.5 kB
├ chunks/main-app-e5c7c3938b6b9060.js 216 B
└ chunks/webpack-0bb8a6bc12122529.js 1.68 kB
Route (pages) Size First Load JS
─ ○ /404 182 B 75.6 kB
+ First Load JS shared by all 75.4 kB
├ chunks/framework-8883d1e9be70c3da.js 45 kB
├ chunks/main-d62d37922d9e063a.js 28.5 kB
├ chunks/pages/_app-52924524f99094ab.js 195 B
└ chunks/webpack-0bb8a6bc12122529.js 1.68 kB
○ (Static) automatically rendered as static HTML (uses no initial props)
마지막으로 다시 한번 업로드 해보겠습니다.
이렇게 올려도 깃헙에는 큰 변화가 없을 것입니다.
.gitignore
파일에 build 폴더가 포함되어 있기 때문에 파일은 올라가지 않습니다.
git add .
git commit -m "😇 1차 완성본"
git push -u origin main
이제 netlify 사이트로 이동하겠습니다.
로그인을 하고 add new site
버튼을 누르고 import an existing project
를 선택하겠습니다.
deploy width GitHub 버튼을 클릭하고 port2023-next
를 검색 후 선택합니다.
자동으로 next 파일을 인식합니다.
따로 수정할 필요는 없습니다.
바로 Deploy port2023-next
버튼을 클릭하면 됩니다.
자동으로 빌드가 되고 배포가 됩니다.
완료가 되었습니다. Domain setting을 누르면 도메인을 변경할 수 있습니다.
마지막으로 깃헙에 정리하면 되겠습니다. 메모장에도 같이 정리하겠습니다.
3. 마무리
드뎌 모든게 마무리 되었습니다. 하나의 사이트를 네가지 버젼으로 만들었습니다. 기초적인 흐름을 이해하기 위한 튜토리얼입니다. 이제 조금 감이 잡히면 이제는 한단계 더 깊이 들어가봅시다. 다음 강의에는 조금 더 파고드는 강의를 만들겠습니다. 그 동안 정말 수고하셨습니다. 👍👍✊
예제 목록
- 1. 포트폴리오 사이트 만들기 : Vite-Site : 셋팅하기
- 2. 포트폴리오 사이트 만들기 : Vite-Site : 레이아웃 설정
- 3. 포트폴리오 사이트 만들기 : Vite-Site : 헤더 영역
- 4. 포트폴리오 사이트 만들기 : Vite-Site : 인트로 영역
- 5. 포트폴리오 사이트 만들기 : Vite-Site : 스킬 영역
- 6. 포트폴리오 사이트 만들기 : Vite-Site : 사이트 영역
- 7. 포트폴리오 사이트 만들기 : Vite-Site : 포트폴리오 영역
- 8. 포트폴리오 사이트 만들기 : Vite-Site : 연락처 영역
- 9. 포트폴리오 사이트 만들기 : Vite-Site : 푸터 영역
- 10. 포트폴리오 사이트 만들기 : Vite-Site : 마무리
- 11. 포트폴리오 사이트 만들기 : React-Site : 셋팅하기
- 12. 포트폴리오 사이트 만들기 : React-Site : 컨퍼넌트 설정
- 13. 포트폴리오 사이트 만들기 : React-Site : 헤더 영역
- 14. 포트폴리오 사이트 만들기 : React-Site : 인트로 영역
- 15. 포트폴리오 사이트 만들기 : React-Site : 스킬 영역
- 16. 포트폴리오 사이트 만들기 : React-Site : 사이트 영역
- 17. 포트폴리오 사이트 만들기 : React-Site : 포트폴리오 영역
- 18. 포트폴리오 사이트 만들기 : React-Site : 연락처 영역
- 19. 포트폴리오 사이트 만들기 : React-Site : 푸터 영역
- 20. 포트폴리오 사이트 만들기 : React-Site : 마무리
- 21. 포트폴리오 사이트 만들기 : Vue-Site : 셋팅하기
- 22. 포트폴리오 사이트 만들기 : Vue-Site : 컨퍼넌트 설정
- 23. 포트폴리오 사이트 만들기 : Vue-Site : 헤더 영역
- 24. 포트폴리오 사이트 만들기 : Vue-Site : 인트로 영역
- 25. 포트폴리오 사이트 만들기 : Vue-Site : 스킬 영역
- 26. 포트폴리오 사이트 만들기 : Vue-Site : 사이트 영역
- 27. 포트폴리오 사이트 만들기 : Vue-Site : 포트폴리오 영역
- 28. 포트폴리오 사이트 만들기 : Vue-Site : 연락처 영역
- 29. 포트폴리오 사이트 만들기 : Vue-Site : 푸터 영역
- 30. 포트폴리오 사이트 만들기 : Vue-Site : 마무리
- 31. 포트폴리오 사이트 만들기 : Next-Site : 셋팅하기
- 32. 포트폴리오 사이트 만들기 : Next-Site : 컨퍼넌트 설정
- 33. 포트폴리오 사이트 만들기 : Next-Site : 헤더 영역
- 34. 포트폴리오 사이트 만들기 : Next-Site : 인트로 영역
- 35. 포트폴리오 사이트 만들기 : Next-Site : 스킬 영역
- 36. 포트폴리오 사이트 만들기 : Next-Site : 사이트 영역
- 37. 포트폴리오 사이트 만들기 : Next-Site : 포트폴리오 영역
- 38. 포트폴리오 사이트 만들기 : Next-Site : 연락처 영역
- 39. 포트폴리오 사이트 만들기 : Next-Site : 푸터 영역
- 40. 포트폴리오 사이트 만들기 : Next-Site : 마무리
댓글