사람들이 블로그를 운영하는 이유는 다양하다. 어떤 이는 블로그를 통한 부수입을 위해, 또 다른 이는 전문성을 알리고 고객을 유치하기 위해, 혹은 단순히 자신의 생각을 표현할 창구가 필요해서 블로그를 운영한다. 그렇다면 블로그를 운영하는 김에 직접 사이트를 만들어 자신만의 트래픽을 확보해 보는 것은 어떨까?
물론 티스토리, 네이버 블로그, 브런치 등 글 작성이 편리하고 이용자 기반이 충분히 확보된 좋은 블로그 서비스 들이 있지만, 나만의 블로그를 통해 더욱 강력한 개인 브랜딩을 구축 할 수 있다.
개발이라고 하면 어렵다고 생각할 수 있지만 Next.js와 Notion API를 활용하면 손쉽게 개인 블로그를 만들 수 있다. 자유로운 레이아웃 구성, SEO 최적화, 브랜딩 강화까지 가능하므로 비즈니스를 운영하는 이들에게도 훌륭한 선택이 될 수 있다. 또한 기존 블로그와 병행 운영하며 고객 확보 전략으로 활용하는 것도 가능하다.
사전지식
개발에 대해 전혀 모른다면 솔직히 말해서 개인 블로그를 운영하는 일이 어려울 수 있다. 그럼에도 불구하고 다음의 사전지식을 차근차근 공부한 뒤 블로그 코드를 따라하면서 만들면 이해할 수 있을 것이다. 혹시 이해가 되지 않더라도, 코드 복사 붙여넣기를 통해 구현이 가능하도록 설명해보고자 한다.
AIi-in-one 메모 앱 노션
노션(Notion) [https://www.notion.com] 은 메모, 문서 작성, 데이터베이스, 프로젝트 관리 등을 하나의 워크스페이스에서 할 수 있는 올인원 협업 툴로 개인이 글을 정리하거나 팀이 협업할 때 유용하다. 블로그 초안 작성부터 일정 관리까지 다양한 용도로 활용되고 있다. 한국에서도 기업과 개인 사용자 모두에게 인기를 얻고 있으며, 2023년 기준 구글 트렌드와 앱 스토어 순위에서도 상위권을 차지할 만큼 활발히 사용되고 있다.
노션 블로그를 만들기 위해 회원가입이 필요하다. 무료계정임에도 모든 과정을 무료로 지원하니 부담스러워하지 않아도 된다.
노션 API를 쓰는 이유
API란? 쉽게 말해, 프로그램끼리 서로 대화할 수 있게 해 주는 약속이다. 예를 들어 내 블로그가 노션에 "글 좀 보여줘" 하고 정해진 규칙대로 요청하면, 노션은 "여기 있어" 하며 글 데이터를 표준 형식(JSON)으로 돌려주는 식이다. 직접 DB를 관리하고 게시판 UI를 직접 만드는 것보다. 편리하고 사용하기도 좋다.
직접 여러 가지 WYSIWYG 도구로 블로그를 만들어 보았지만 게시글 작성 경험이 불편하고 이미지 처리 로직을 별도로 구성해야 했다. 반면 노션 API와 react-notion-x [https://www.npmjs.com/package/react-notion-x] 를 사용하면 노션에서 보던 블록 구조를 거의 그대로 불러올 수 있고, 인증키 하나로 안전하게 데이터에 접근하며, 캐싱/SEO도 Next.js와 쉽게 결합할 수 있다. 그래서 본 글에서는 노션 API를 이용한 블로그 방식을 추천한다.
Next.js + Vercel
Next.js 는 React 라이브러리를 기반으로 하는 개발 프레임워크로 정해진 규칙에 따라 코드를 작성해야 한다. 그러므로 개발 지식이 충분하지 않더라고 Next.js docs [https://nextjs.org/docs] 만 읽으면 형식에 따라 어느정도 웹 서비스를 만들 수 있다. 아예 개발을 모른다면. Next.js 에서 제공하는 [https://nextjs.org/learn?utm_source=next-site&utm_medium=homepage-cta&utm_campaign=home] 기본 교육과정을 한 번 공부해 보는 것을 추천한다.
vercel [https://vercel.com] 이라는 회사에서 Next.js 프레임워크를 관리한다 뿐만 아니라 github의 계정만 있으면 github와 연동하여 손쉽게 작업물을 배포할 수 있다. 심지어 무료 호스팅과 https 인증도 무료로 제공해준다. 덕분에 가비아에서 도메인 서버만 구매하여 개인 블로그 사이트를 배포할 수 있었다.
개발 환경 셋팅
Node.js 설치
노드.js는 자바스크립트를 브라우저가 아닌 서버에서도 실행할 수 있게 해주는 런타임 실행기이다. 쉽게 말해, 브라우저 안에서만 실행되던 자바스크립트를 컴퓨터나 서버에서 독립적으로 돌릴 수 있도록 만들어 준다.
설치 작업을 완료 후 npm run dev 명령어를 통해 정상적으로 실행되는 것을 확인할 수 있다. 정상적으로 동작한다면 개발환경의 셋팅은 완료됐다. 이제 Notion API 의 키를 발급하여 본격적으로 노션의 Database와 연동하여 나의 사이트에 데이터를 가져와보자
integration 을 설정하는 방법은 [https://developers.notion.com/docs/create-a-notion-integration] 이 링크의 가이드를 참고하면된다. View my Integration 에서 노션 API Key를 발급할 수 있다. API key란 서비스를 이용할 수 있도록 발급받는 비밀번호 같은 인증 코드다. 이 키를 통해 내 블로그가 노션 API에 접근할 수 있고, 노션은 이 키를 확인해 허용된 사용자임을 판단한다.
노션 Database 구축
노션에서 블로그용 DB를 만들어주고 Connection 기능을 이용하여 발급된 integration과 DB를 연동해주어야 한다. 연동 후 노션 DB ID를 env 파일에 작성해주어야 한다. 상세한 설정은 DOCS의 가이드를 참고바란다.
나의 DB는 이러한 구성으로 제작하였다.
.ENV 파일에 저장
발급된 API 키와 생성한 database ID 는 .env 파일에 저장해주어야 한다. .env 파일은 쉽게 말해 비밀 설정들을 보관하는 메모장이다 코드에 직접 쓰면 위험한 값을 이 파일에 저장해 두고, 프로그램이 실행될 때 불러와서 사용한다. 이는 로컬에도 설정해주어야 하고, vercel에 별도로 .env 파일을 업로드하는 공간에 .env 설정을 마찬가지로 적용해주어야 한다.
여기까지 따라왔다면 드디어 Noiton API를 통해 직접 블로그를 개발 할 수 있다.
개발 시작
Next.js는 Client Component와 Server Component로 나뉘어 있어 처음 접하면 다소 복잡하게 느껴질 수 있다. 여기서는 최대한 코드 구조를 단순화 하여 설명한다. 실제 운영하는 블로그와는 조금 다른 단순화된 구조를 예시로 사용한다.
Client Component는 브라우저에서 실행되어 사용자 인터랙션(버튼 클릭, 입력 등)을 처리하는 데 쓰이고, Server Component는 서버에서 실행되어 데이터 불러오기나 초기 렌더링을 담당한다. 쉽게 말해 동적인 동작이 있다면 Client component 가 사용된 것이고 동적인 동작이 없다면 기본적으로 Server component 인 것이다.
기본 구조
먼저 기본 구조를 파악해보자
layout.tsx와 page.tsx는 Next.js 앱 구조에서 핵심적인 역할을 한다. layout.tsx는 페이지 전반에 걸쳐 공통으로 적용되는 레이아웃(예: 헤더, 푸터, 네비게이션)을 정의하는 파일이고, page.tsx는 실제 콘텐츠를 보여주는 개별 페이지 파일이다. 예를 들어 블로그라면 layout.tsx에 전체 틀을 잡아두고, page.tsx에는 글 목록이나 글 내용을 표시하는 식으로 나뉜다.
lib/notion.ts
notion.ts 파일은 notion과 연동하는 유틸리티 함수들을 모아둔 파일이다. 유틸리티 함수는 쉽게 말해 자주 쓰이는 기능을 따로 빼서 만든 작은 도구 같은 함수이다. notion.ts 를 통해 notion API와 통신하는 함수를 생성해주고, 필요한 페이지에서 불러와서 사용하도록 하는 역할을 한다. 초반에는 구성이 어렵게 느껴질 수 있지만, 단계별로 차근차근 따라오면 이해할 수 있을 것이다.
아래는 노션API와 연동하여 데이터를 호출하는 함수이다. 이는 아래의 노션 공식 문서를 참고하여 제작하였다.
위 코드는 데이터베이스 ID를 기준으로 데이터를 가져오는 함수이다. id는 데이터베이스의 하위에 페이지 아이디와, 순서를 정렬하는 indexid 로 구분한다. id를 기준으로 페이지 상세내용을 불러오고, index_id를 기준으로 목록을 정렬하는 것을 유의바란다.
app/page.tsx
notion.ts 함수를 통해 블로그를 보기 위한 목록을 app/page.tsx 에 구성한다.
revalidate 옵션을 설정하면 일정 시간마다 새로운 데이터를 자동으로 불러와 최신 상태를 유지할 수 있다. 또한 Metadata 설정을 통해 페이지의 제목, 설명, OG 태그 등을 지정하여 검색 엔진 최적화(SEO)와 SNS 공유 시의 미리보기 성능을 높일 수 있다.
위 코드는 notion.ts에서 작성해 둔 Notion API 연동 함수를 호출해 데이터를 가져온다. 가져온 데이터는 목록 형태로 화면에 표시되며, async/await을 통해 비동기적으로 불러온 뒤 렌더링된다. 또한 Next.js의 Link 컴포넌트를 사용해 각 글의 상세 페이지로 이동할 수 있도록 구성한다.
async/await을 통해 비동기적으로 데이터를 불러온다는 것은, 요청을 보내 놓고 결과가 올 때까지 프로그램 전체가 멈추지 않고 다른 작업을 계속할 수 있다는 의미다. 즉, 서버에 데이터를 요청하는 동안에도 화면은 끊기지 않고 부드럽게 동작하며, 데이터가 준비되면 이어서 그 결과를 처리할 수 있다.
Link에서 전달되는 slug 값은 최적화된 URL 경로 요소를 의미며 이는 DB에 미리 생성해두어야 한다. slug는 간단하게 말해 읽기쉬운 URL정도로 생각하면 된다. 해당 값을 URL에 반영하여 사람이 읽을 수 있는 형태로 구성하면 SEO에 유리하고, 글의 내용을 짐작할 수 있어 가독성이 높아진다. 이 slug 값은 다이나믹 라우트를 통해 상세 페이지로 전달되며, 해당 slug 데이터를 기반으로 id 값을 찾아. 해당 page id 값으로 실제 상세 페이지가 불러와지도록 설계한다.
app/[data]/page.tsx
Dynamic route는 주소를 미리 정해두지 않고, 나중에 들어오는 값에 맞춰 페이지를 보여주는 기능이다. 예를 들어 /post/apple, /post/banana 처럼 글마다 url 값이 달라질 수 있는데 이런 경우 다이나믹 라우트를 사용하면 그 값에 맞는 페이지를 나중에 불러올 수 있다.
getPageIdBySlug 함수를 통해 반환되는 ID 값을 통해 page를 검색하여. 상세 데이터를 가지고 온다.
react-notion-x 라이브러리 설치
가져온 데이터를 notion 에서 보이는 그대로 조회하기 위해 react-notion-x 라이브러리가 필요하다. 아래는 공식 문서에서 제공하는 설치방법과 사용방법을 그대로 가지고 왔다.
app/[data]/page.tsx
getBlogPage 함수와 react-notion-x 라이브러리를 통해 데이터를 불러오는 코드를 통해 블로그의 실제 데이터를 불러오는 코드를 확인할 수 있다.
components/ClientNotionRender.tsx
불가피하게 NotionRenderer가 client component 라서 마찬가지로 데이터 페칭은 서버, 렌더링은 클라이언트로 분리하는 패턴을 위해 별도의 컴포넌트로 분리하였다.
이제 Next.js와 Notion API를 이용한 블로그의 기본 구조를 완성하였다. 작동하는 블로그를 만들었다면 이제는 필요한 기능들을 직접 추가하면서 점차 자신만의 색깔을 입혀보길 바란다. 중요한 것은 완벽하게 만드는 것이 아니라, 작동하는 구조 위에 하나씩 발전시켜 나가는 과정이다.