hoonie-blog v1.1.0 등장!
2025년 3월 14일
목차
들어가면서: v1.1.0 패치노트
hoonie-blog가 세상에 공개된지 한 달이 지났습니다. 기존 블로그의 여러 문제점들을 개선하기 위해 v1.1.0 버전에서는 다음과 같은 핵심 변경을 진행했습니다:
- SSR에서 SSG로 전환: 정적 콘텐츠에 최적화된 빌드 방식으로 변경
- MDX 파일 구조 개선:
/app/blog/(posts)/
→/content/posts/
로 경로 단순화 - SEO 최적화: 표준 URL(canonical URL) 설정 및 메타데이터 개선
- 동적 라우팅 구현:
generateStaticParams
,generateMetadata
활용
이러한 변경을 통해 페이지 로딩 속도 향상, 블로그 관리 편의성 증대, 그리고 검색엔진 최적화라는 세 가지 목표를 달성하려고 노력했습니다. 그럼 지금부터 각 변경점과 그 배경에 대해 하나씩 살펴볼까요?
SSR에서 SSG로 전환하기
블로그에 SSG가 필요했던 이유
기존 v1.0.0 블로그는 SSR(Server-Side Rendering) 방식으로 동작하고 있었습니다. 이는 매 요청마다 서버에서 페이지를 렌더링하는 방식인데, 정적 콘텐츠만 제공하는 블로그에는 불필요한 서버 부하를 가져올 수 있다고 판단했습니다.
항목 | SSR | SSG |
---|---|---|
렌더링 시점 | 요청 시 서버에서 렌더링 | 빌드 시점에 정적 HTML 생성 |
성능 | 요청마다 렌더링 -> 상대적으로 느림 | 미리 생성된 HTML 제공 -> 빠름 |
SEO | 서버에서 생성된 HTML 제공 | 미리 생성된 HTML 제공 -> SEO 우수 |
서버 부하 | 트래픽 증가 시 서버 부하 증가 | 정적 파일 제공으로 부하 적음 |
SSG(Static Site Generation)로 전환함으로써 빌드 시점에 모든 페이지를 미리 생성하고, 사용자에게는 이미 완성된 HTML을 제공할 수 있게 되었습니다. 이는 로딩 속도 향상뿐만 아니라 서버 비용 절감에도 도움이 됩니다.
Dynamic Imports를 활용한 구현
기존의 정적 라우팅에서 벗어나, Next.js에서 SSG를 구현하기 위해 Dynamic Imports와 함께 generateStaticParams
, generateMetadata
함수를 활용했습니다. 이를 통해 빌드 시점에 모든 블로그 포스트를 미리 생성하고, 각 포스트별 메타데이터도 정적으로 생성할 수 있게 되었습니다.
export async function generateStaticParams() {
const posts = await getAllPosts();
return posts.map((post) => ({
slug: post.slug,
}));
}
export default async function PostPage({ params }: PostPageProps) {
const paramsData = await params;
const slug = paramsData.slug;
const result = await getPostBySlug(slug);
if (!result) {
notFound();
}
const PostContent = result.postModule.default;
return <PostContent />;
}
이후 간소화된 빌드 로그에서 게시글에 해당하는 페이지가 정적으로 빌드되어 있다는 것을 확인할 수 있었습니다.
[00:40:23.417] Route (app)
[00:40:23.417] ┌ ƒ /
[00:40:23.417] ├ ƒ /_not-found
[00:40:23.418] ├ ○ /apple-icon.png
[00:40:23.419] ├ ƒ /blog
[00:40:23.419] ├ ● /blog/[slug]
[00:40:23.419] ├ ├ /blog/retro-onebite-ts-challenge
[00:40:23.419] ├ ├ /blog/retro-next-blog
[00:40:23.419] ├ ├ /blog/retro-moty
[00:40:23.419] ├ └ [+2 more paths]
...etc
[00:40:23.421]
[00:40:23.421] ○ (Static)
[00:40:23.421] ● (SSG)
[00:40:23.421] ƒ (Dynamic)
MDX 파일 구조 개선: 작성 경험의 향상
기존 구조의 문제점
v1.0.0에서는 블로그 포스트를 작성할 때 다음과 같은 복잡한 과정을 거쳐야 했습니다:
/app/blog/(posts)/
폴더에서 게시글을 위한 폴더 생성- 폴더 내부에서
page.mdx
파일 생성 page.mdx
에서 글을 작성- 이미지가 필요하다면,
/public
폴더에 별도 디렉토리 생성 후 이미지 추가
src/
├─ app/
│ ├─ blog/
│ │ ├─ (posts)/
│ │ │ ├─ [post-name]/
│ │ │ │ └─ page.mdx
└─ ...etc
위 구조와 같이 매번 [post-name]
에 해당하는 폴더와 함께 page.mdx
파일을 추가적으로 생성해야 했고, 이러한 구조는 불필요한 중첩을 만들어 글 작성 흐름을 방해했습니다.
개선된 파일 구조
v1.1.0에서는 MDX 파일을 /content/posts/
디렉토리로 이동시켜 구조를 단순화했습니다. 이제 블로그 글 작성이 훨씬 간편해졌습니다:
/content/posts/
폴더에 직접my-post.mdx
파일 생성- MDX 파일 내에서 메타데이터와 함께 글 작성
src/
├─ app/
│ ├─ blog/
│ │ ├─ [slug]/
│ │ │ └─ page.tsx
├─ content/
│ ├─ posts/
│ │ ├─ post1.mdx
│ │ └─ post2.mdx
└─ ...etc
게시글 컴포넌트의 자유도도 높아졌습니다. 이전에는 MDX 파일을 직접 페이지로 사용했기 때문에, 특정 페이지에만 필요한 일회성 컴포넌트도 mdx-components.tsx
에 전역으로 정의해야 했습니다. 또한 게시글 페이지 내부에서 본문 이외에 추가적인 스타일링이 필요한 레이아웃이 있다면, 모든 page.mdx
파일에서 이를 임포트해 사용해야 했습니다. 이제는 페이지 컴포넌트에서 MDX 콘텐츠를 동적으로 불러와 렌더링하기 때문에, 페이지별 커스터마이징이 더 유연해졌습니다.
SEO 최적화: 구글 검색에 노출되기
도메인 변경에 따른 문제
블로그를 처음 배포했을 때는 hoonie-blog.vercel.app
도메인을 사용했고, 이후 hoonieblog.xyz
라는 커스텀 도메인으로 변경했습니다. 그러나 구글 서치 콘솔에서 색인 생성에 실패하는 문제가 발생했습니다.

문제의 원인은 도메인을 변경했음에도 구글이 여전히 이전 도메인을 표준 URL로 인식하고 있었기 때문이었습니다. 구글 서치 콘솔에서 URL을 검사했을 때, 다음과 같은 결과를 확인할 수 있었습니다.
- 구글이 선택한 표준 URL:
https://hoonie-blog.vercel.app
- 사용자 선언 표준 URL: 없음
해당 문제의 원인은 구글의 검색 엔진이 이미 이전 도메인의 색인을 생성했고, 제가 추가적인 표준 URL을 선언하지 않았기 때문에 변경된 도메인을 기반으로 하는 블로그 페이지가 사용자가 선택한 표준이 없는 중복 페이지로 인식되고 있기 때문이라고 생각했습니다.
표준 URL 설정으로 해결
이 문제를 해결하기 위해 모든 페이지에 표준 URL(canonical URL)을 추가했습니다. v1.0.0 버전에서는 .mdx 파일을 기반으로 하는 정적 라우팅을 사용하고 있었기 때문에, 표준 URL을 적용하려면 다음과 같이 모든 .mdx 파일에 표준 URL을 직접 작성해야 했습니다.
export const metadata = {
title: 'hoonie-blog v1.1.0 등장!',
description: 'SSR에서 SSG로 개선하는 여정을 떠나봅시다',
date: '2025-03-14',
canonical: 'https://hoonieblog.xyz/blog/retro-hoonie-blog-v1.1.0',
};
<PostTitle {...metadata} />;
그리고 각 MDX 파일마다 이 canonical 속성을 올바르게 설정해야 하며, 경로 변경 시 모든 파일을 수정해야 하는 번거로움이 있었을 것입니다. 그러나 v1.1.0 버전부터는 동적 라우팅을 사용하기 때문에, generateMetadata
를 활용해 게시글 제목에 맞는 표준 URL을 빌드 시 자동으로 생성할 수 있습니다.
export async function generateMetadata({
params,
}: PostPageProps): Promise<Metadata> {
const slug = params.slug;
const result = await getPostBySlug(slug);
// ...
return {
// ...
alternates: {
canonical: `/blog/${slug}`,
},
// ...
};
}
이제 폴더 구조가 변경되더라도 해당 부분만 수정하면 되기 때문에 유지보수성이 향상되었습니다.

이후 서치 콘솔에서 URL 검사를 다시 진행한 결과, 사용자 선언 URL이 변경된 커스텀 도메인으로 명시되어 있는 것을 확인할 수 있었습니다. 추가로 301 리디렉션을 설정하여 이전 도메인으로 접속하는 사용자를 새 도메인으로 자동 이동시켰습니다.

나오면서: 앞으로의 로드맵
hoonie-blog v1.1.0은 성능, 편의성, SEO 측면에서 개선을 이루었지만, 아직 더 발전시킬 부분이 많습니다. 앞으로의 로드맵은 다음과 같습니다:
v1.0.0 - 최초 블로그 출시
↓
v1.1.0 - Dynamic Imports를 사용한 SSG 방식 리팩토링 (현재)
↓
v1.1.1 - 마이너 리팩토링 및 버그 수정
↓
v1.2.0 - 블로그 목록 페이지네이션 기능 추가
↓
v1.3.0 - 태그/카테고리 기능 추가
↓
v2.0.0 - 뉴스레터 구독 및 이메일 피드백 기능 추가
↓
v3.0.0 - 국제화(i18n) 지원
v1.1.1에서는 리팩토링 및 버그 수정을 진행하면서, 404 Not Found 페이지를 비롯한 작은 개선을 진행할 예정입니다. 그럼 다음 업데이트도 기대해 주세요!