Velog
블로그 목록

포트폴리오 사이트를 만들어보자

0
next.js

Hello World

첫 글입니다.

항상 벨로그에서만 블로그 글을 적다가 제가 만든 웹에 올릴 글을 적는게 신기하기도, 뿌듯하기도 합니다.

이번 글은 제가 만든 포트폴리오를 소개하면서 만들게된 계기, 사용한 기술 등을 글로 풀어보도록 하겠습니다.

포트폴리오 소개

디자인

이번 작품에서 가장 오랜 시간이 걸렸습니다.

도저히 제 손으로는 제 포트폴리오를 예쁘게 보이게 할 수 없었습니다…ㅋㅋㅋ

그래서 다른 프론트엔드 개발자 분들의 포트폴리오 사이트를 참고하기로 했습니다.

정보 수집 사이트: https://boottent.com/community/article/20230612161832
디자인 참고 사이트:
https://www.leeboa.com/

포트폴리오 사이트들을 이것저것 뒤져보다가 디자인이 정말 취향 저격인 사이트를 발견해서 곧장 카피에 들어갔습니다.

(디자인 제작자이신 이보아님 정말 대단하신 것 같습니다…)

애니메이션

포트폴리오 사이트에 애니메이션이 빠질 수는 없죠

애니메이션 구현은 Framer-Motion과 React-Intersection-Observer을 주로 사용했습니다.

전체적인 컨셉은 스크롤하면 애니메이션이 진행되는 전형적인 포트폴리오 사이트의 느낌을 냈습니다.

최대한 다양하게 하려고 가로축 세로축을 정말 많이 섞어봤는데 마지막에 보니까 너무 정신이 없는 느낌이라 가로축 사용 빈도를 줄이고 세로축을 많이 사용하는 쪽으로 바꿨더니 깔끔하니 보기 좋더라고요.

Framer-Motion은 이전에 써본적은 있었지만, 제가 코드를 직접 친적은 많이 없었습니다. (클로드 최고)

하지만, 이번에는 구체적인 디자인 컨셉이 있기 때문에 클로드가 제가 원하는 바를 제대로 캐치하질 못해서 제가 코드를 대부분 직접 작성했습니다.

이번 계기로 Framer-Motion에 대해서 “이제 이거 쓸 줄 안다” 정도의 레벨이 된 것 같아서 기분이 좋네요 ㅋㅋ.

반응형 레이아웃

컴퓨터에서만 예쁘게 보이면 짜치니까 이왕 할거 반응형 작업도 제대로 해보자 싶어서 PC에서 보이는 UI와 최대한 동일한 모습을 모바일에 담을 수 있도록 노력했습니다.

개인적으로 웹 개발이 어렵다고 느껴지는 부분이 참 사용할 수 있는 환경이 너무 많고 다르다보니, 내 웹이 각기 다른 환경에서 예쁘게 보이도록 html, css 구조를 잘 짜는 부분입니다. 이번 개발에서도 분명히 느꼈지만 이런 어려움에 패배하지 않기로 마음먹고 천천히 글자 하나부터 섹션, 페이지 단위로 레이아웃을 심사숙고해서 기획했습니다.

덕분에 matchMedia()와 같은 메서드도 알게되고 여러모로 유익한 시간이었습니다.

콘텐츠

포트폴리오에 들어가는 정보들은 거의 대부분 관리하기 편하도록 CMS 방식으로 구성하였습니다.
(CMS 구현에 대해서는 조금 있다가 설명하겠습니다.)

CMS 기반 웹앱/홈페이지를 개발해본건 가장 최근 외주 작업에서 요구사항으로 받았던 경험이 있습니다.

CMS 기반 홈페이지를 제작하는 일이었는데, 그 당시에는 CMS 관련 기능을 만들어본 경험이 없었어서 레이아웃과 디자인, 애니메이션을 신경써야 하는 동시에 홈페이지에 보여지는 정보들을 하나하나 DB 컬럼으로 치환해서 생각하느라 머리가 아팠던 해프닝이 있었는데, 이번엔 그때의 기억과 예쁜 디자인이 있었기에 조금 더 수월하게 구현할 수 있었던 것 같습니다.

내용에 대해서는 사실 기존에 있던 pdf 포트폴리오와 많이 다르지 않지만, pdf 포트폴리오는 너무 길면 안되기에 아쉽지만 생략해야 했던 정보들을 웹 포트폴리오에 넣을 수 있었습니다. (제 가치관, 캐치프레이즈 등등 다양한 걸 넣어서 있어빌리티를 챙겼습니다 ㅋㅋㅋ)

블로그

제 포트폴리오 사이트에 현재 여러분이 보고 계시는 블로그 기능을 추가했습니다.

포트폴리오를 만드는 김에 같이 만들어보고 싶은 생각에 넣은 이유도 있지만, 요즘 제가 중요하게 여기는 “왜 그렇게 구현했는지”를 프로젝트 소개에 적는 것보다 훨씬 더 자세하고 깊게 적을 수 있을 것 같아서 제 포트폴리오의 컨셉, 취지에 부합한다고 생각하여 추가하게 되었습니다.

기존에 제가 작성했던 블로그는 벨로그 밖에 없었는데 벨로그에는 뭔가 개발 관련한 글만 적어야할 것 같은 압박감이 느껴져서 좀 더 많은 카테고리의 글을 작성할 수 있게 되었습니다. (이래봬도 개발 말고 좋아하는게 많습니다 🙂)

뒤에 있지만 마크다운 요소(ex: H1, H2 등등)들의 디자인을 어떻게 할까 고민하다가, 제 pdf 포트폴리오에 있는 디자인 시스템을 그대로 빼껴왔더니 놀라울 정도로 찰떡어서 놀란 기억이 있네요 ㅋㅋ.

조만간 블로그 구독과 같은 기능도 추가할 예정이니 많은 관심 부탁드립니다!!

프로젝트

프로젝트 페이지에서는 제가 개발을 공부하고 개발자로서의 취업을 준비하며 경험했던 프로젝트들을 담으려고 합니다.

아직 귀찮아서 pdf에 있는 프로젝트도 다 못옮겼지만 이제 방학이라 시간 빌게이츠가 되었으니 열심히 기록하면서 과거를 되짚어 보고 또 공부해야겠네요.

프로젝트 아티클의 디자인은 정말 제 pdf 포트폴리오와 최대한 똑같이 만드려고 노력했습니다.

일반적인 블로그랑 비슷한 디자인으로 하려다가 그럼 너무 딱딱하고 차별성이 없어서 했던 결정입니다.

대제목, 소제목, 본문, 들여쓰기등 여러가지 요소들을 pdf 포트폴리오에서 착안했고, 프로젝트 메타데이터 부분 또한 유사하게 만드려 노력했습니다.

Image
Image

(왼: 웹사이트 포트폴리오 / 오: pdf 포트폴리오 / 지금보니 한 블록 내에서 줄나누기 한게 적용이 안돼있네요… 수정해야겠습니다 ㅋㅋ)

프로젝트에서는 블로그만큼 길진 않지만 무엇을 만들었는지, 어떻게 만들었는지, 어떤 문제를 겪고 어떻게 해결했는지를 서술합니다.

포트폴리오 홈에도 적혀있지만, 프로젝트에는 서비스를 만들며 고민한 결과들이 모여있다면, 블로그에는 그 과정에서 잠시 멈춰 고민한 과정을 모아둔다는 취지에 따라 앞으로 그 경계를 확실히하고 아티클의 퀄리티를 올리는데 집중을 해야겠습니다.

기술 소개

노션 API

앞에서 설명했던 CMS의 구현 방식이 바로 노션 API를 활용하는 것이었습니다.

언급했던 외주 프로젝트에서는 직접 CMS 어드민 페이지를 구축했지만, 돈을 받지도 않는 개인프로젝트에서 프로젝트, 블로그, 기술스택, 학력, 수상이력, 자격증등 많은 도메인에 대한 어드민 페이지를 만든다는 것은 제게 너무나 가혹한 일이었기 때문에, 어떻게하면 CMS를 간편하게 만들 수 있을지 짱구를 굴렸습니다.

후보군에 Github 레포지토리에 직접 마크다운 파일을 적어서 커밋하는 방식도 있었는데, vscode에서 마크다운으로 글을 적는 일은 상당히 힘들고 귀찮습니다. 그래서 UI와 세계 최정상의 글쓰기 UX를 가진 노션을 사용할 방법에 대한 고민을 하루 온종일 했습니다.

노션에 데이터베이스(데이터소스)를 만들고 이를 API와 연결하는 방식이 있어 이 방식을 채택했습니다.

앞서 설명한 프로젝트를 예로 들면, PROJECT INFO 부분부터는 노션 데이터베이스의 페이지 내용이지만, 상단의 METADATA는 RDBMS에 있는 컬럼과 비슷한 프로퍼티를 사용해 설정할 수 있도록 하였습니다.

페이지 내에 모든 정보를 적는게 아니라 정보의 종류가 나눠져있으니 한층 더 글을 쓰기 편해졌습니다.

노션 API의 또다른 강점은 SDK가 매우 강력하다는 점인데요, 타사의 OpenAPI의 방식처럼 API 엔드포인트를 직접 호출하는게 아닌,

typescript
async getProjects(size?: number) {
  const res = await notion.dataSources.query({
    data_source_id: this.id,
    filter: {
      property: "status",
      status: {
        equals: "Published",
      },
    },
    sorts: [
      {
        property: "created_at",
        direction: "descending",
      },
    ],
    page_size: size,
  });

  return res.results as ResultResponse<Project>[];
},

위와 같이 간편하고 정확한 인터페이스를 통해 DX가 매우 편하게 구성되어 있습니다.

한마디로 그냥 감동받았습니다. 타입 지정도 다 되어있어서 상당히 쓰기 좋습니다.

노션 API 문서에는 엔드포인트 호출 방식과 SDK 사용 방식 둘다 나와있는데, 둘중 하나만 있는 API는 아직 못본 것 같아서 왠만하면 SDK를 사용하시면 될 것 같습니다.

다만 노션이 진짜 데이터베이스가 아니기 때문에 페이지 내에 존재하는 정보들을 정형화하여 json으로 만들어내는 데에 많은 자원이 필요하고 이에따라 API의 평균 응답시간이 매우 느린 단점이 있습니다.

그렇기 때문에 이어서 설명할 ISR 전략을 적극적으로 사용하였습니다.

ISR

ISR은 빌드 타임에 정적 페이지를 생성하고 일정 주기마다 만들어진 정적 페이지를 재검증하여 최신 상태를 유지해주는 기능을 가지고 있습니다.

내용을 미리 캐싱해두고 사용자가 요청할때 빠르게 페이지를 서빙할 수 있도록 ISR을 모든 페이지 적용하였습니다.

블로그 아티클, 프로젝트 아티클의 목록과 각각의 상세페이지는 정보가 거의 변하지 않고, 실시간으로 데이터 변경을 표시해 주어야할 필요가 없기 때문에, ISR을 사용하기 매우 적절한 사례라고 볼 수 있습니다.

ISR을 공부하기 위한 더미 프로젝트에서는 사용해보았지만, 실제 배포할 프로젝트에 적용해본 경험은 처음이라 설렜고 많은 공부가 되었습니다.

하지만 저는 ISR을 조금 특이하게 사용하였습니다.

사실 블로그 글, 목록의 경우 ISR의 일반적인 재검증 인터벌인 24시간 동안 변하지 않는 경우다 대다수이므로 조금 더 확실하게 최적화를 하고 싶었습니다.

이때 발견한 것이 노션 API의 “웹훅”입니다.

웹훅을 사용하여 노션 데이터소스의 변화를 감지하고 감지한 변화를 본 서비스의 api 엔드포인트로 전송해줍니다.

이를 통해 웹사이트가 업데이트 되어야할 시점을 특정할 수 있었고, ISR을 거의 SSG처럼 사용해서 서버 자원을 아낄 수 있었습니다.

써보고 싶었지만 못써본 기술

이번 프로젝트에 Next.js의 Parallel Routes와 Intercepting routes를 적용해보고 싶었지만 기술적 한계를 느껴 포기하게 되었습니다.

Parallel Routes는

Parallel Routes를 사용하면 동일한 레이아웃 내에서 하나 이상의 페이지를 동시에 또는 조건부로 렌더링할 수 있습니다. 이는 소셜 사이트의 대시보드 및 피드와 같은 매우 동적인 앱 섹션에 유용합니다. - nextjs.org

라고 합니다.

한마디로 페이지에 따라 레이아웃에서 동적으로 바뀌어야 할 섹션을 만들때, layout.tsx에 그 위치를 지정해두고 app router에서 페이지를 렌더링하는 것 처럼 사용할 수 있다는 뜻 입니다.

Intercepting routes은

Intercepting routes를 사용하면 현재 레이아웃 내에서 애플리케이션의 다른 부분의 라우트를 로드할 수 있습니다. 이 라우팅 패러다임은 사용자가 다른 컨텍스트로 전환하지 않고도 라우트의 콘텐츠를 표시하려는 경우에 유용합니다. - nextjs.org

라고 합니다.

특정 페이지내에서 “/about” 페이지로의 이동이 감지되면 app router상의 “/about” 경로가 아닌 다른 페이지/레이아웃을 렌더링할 수 있다는 뜻 입니다.

이 기능들을 섞어 메인화면에서 최근 블로그와 프로젝트 카드를 눌렀을 때, 페이지로 이동되는게 아닌 모달을 이용한 퀵뷰 기능을 만드려고 했지만, 하위페이지에도 영향을 미치는 두 기능의 특성에 의해 메인페이지의 경로가 “/” 이어서 목록 페이지인 “/blog”와 “/projects”에서 카드를 눌렀을 때 페이지가 아닌 모달로 열리는 대참사가 벌어져서 포기했습니다.

참 아쉽네요. 제가 준비했던 킥이었는데….

두 기능은 다른 프로젝트에서 기회가 된다면 꼭 써봐야겠습니다 ㅎㅎ.

웹사이트 포트폴리오를 만들게 된 계기

PDF는 수정하기 너무 귀찮아요

원래 저는 포트폴리오를 pdf로만 관리하고 있었는데요, 프로젝트 변경과 같은 큰 변경이면 시간을 내서라도 하지만, 자잘자잘한 수정인데도 레이아웃이 변경되거나 하는 귀찮은 작업이 생길 때가 빈번해서 변경을 해야함에도 불구하고 미루게 되다가 결국 잊어서 수정하지 못하는 그런 상황들이 매우 많았습니다.

그래서 이를 해결하고자 데이터만 빠르게 기록하면 자동으로 이쁜 UI에 녹아들도록 CMS 기반 웹 포트폴리오를 만들게 되었습니다.

또, 명색이 웹개발자인데 예쁜 웹 포트폴리오 하나 정도는 있어야 자신감이 생기죠 ㅋㅋㅋ

후기

평소같았으면 절대 안했을 듯

사실 겨울방학 이후 졸업식 주간에 일주일간 학교에서 할 일이 없어서 할 수 있었던 프로젝트인 것 같습니다.

학기 중엔 바쁘기도 하고 학교에 있으면 은근 개발할 시간이 많지 않아서 그 시간에 동아리나 다른 프로젝트를 하느라 틈이 안났겠지만, 지금은 아무도 건드리지 않는 프리시즌이기 때문에 맘놓고 시간도 마음껏 태워가면서 예쁜 포트폴리오 사이트를 만들 수 있었던 것 같습니다.

프로젝트에 UX라고 할게 없기 때문에 오로지 UI에만 집중해본 신기한 경험이 되기도 했고, 열심히 만들어보니 애정도 생겨서 이렇게 글도 쓰고 뿌듯하네요.

앞으로의 계획

방학동안 큰 포트폴리오 변경이 없었기 때문에 포트폴리오 내용보다는 블로그 글을 자주 쓸 것 같습니다.

구독 기능도 얼른 만들고, 태그별로 필터링할 수 있는 기능도 만들면서 제 웹 포트폴리오를 열심히 갈고 닦도록 하겠습니다.

읽어주셔서 감사합니다!

새 글 알림 받기

글이 마음에 드셨다면 블로그를 구독하고 새로운 소식을 받아보세요.

On this page