Next.js로 개발 블로그를 만들 때 꼭 해야하지만 가장 귀찮았던 게 이미지를 처리하는 일이었어요.
예전에는 Gatsby를 사용했었는데 그때는 Gatsby에서 알아서 해주니깐 너무 좋았었어요.
Gatsby보다는 Next.js로 전환하기로 결정했지만 Next.js에서는 이미지 처리가 은근 까다로워서 애를 먹었어요.
먼저 알아두셔야 할 건 저는 Next.js로 SSG(Static Site Generator)를 사용하고 있어요. 이 말은 모든 HTML은 빌드 단계에 생성되어 GitHub Pages에 호스팅돼요. 이건 NGINX 정적인 파일만 올리는 것처럼 사용하고 있다는 뜻과 비슷해요. 운영 환경에서 서버 렌더링을 통해 HTML을 돌려주는 부분은 없다고 보시면돼요.
그리고 저는 이 프로젝트 내부에서 Obisidan을 통해 글을 써요.
프로젝트 안에 blog 폴더에 .obsidian
설정 폴더가 있어요. Obsidian 프로그램에서는 프로젝트 루트/blog
폴더에서 글을 작성하고 있어요.
글이 작성되는 위치는 blog/posts
이고 이미지가 저장되는 위치는 blog/assets
에요.
HTML에서 이미지를 표시하는 데는 2가지 방법이 있어요.
- 이미지 파일 경로를 알려주는 것
- 이미지 파일을 base64로 변환해서 굉장히 긴 문자열로 바꿔서 표시
원격 이미지인 경우에는 보통 서버 렌더링을 받을 때 이미지를 base64로 변환하던가 그냥 CDN 경로로 받아오면 돼요.
저는 원격 이미지 경로로는 Unsplash와 Yes24를 사용하고 있어요.
저한테 큰 문제는 로컬 이미지였어요. Obsidian에서 이미지를 첨부했을 때, 이미지는 잘 표시되지만 웹 환경(개발, 배포 모두)에서는 이미지가 깨진채로 표시되었어요.
이미지 문제를 해결하기 위해 제가 참고한 블로그 글은 2가지 였습니다.
- Use relative paths in markdown and MDX images with Next.js -> 이미지 경로 변환
- Contentlayer with next/image -> 이미지를 base64로 변환
처음 이미지 문제를 해결하기 위해 시도했던 건 로컬 이미지 파일들을 마크다운을 HTML로 변환하는 과정에서 이미지인 경우를 찾아서 src에 경로 대신 base64로 변환한 문자열로 전부 바꿔주었어요.
이렇게 하면 손쉽게 문제가 해결되지만 블로그 글에 이미지가 많아질수록 웹사이트가 느려지게 되었어요.
이미지가 나오니 사이트가 느려져서 이미지를 다시 경로에서 찾아오도록 변경해야 했는데요. remarkPlugins
에 직접 만든 함수(remarkSourceRedirect
)를 추가해서 Obsidian 경로를 개발 & 운영 환경에서 이미지 경로가 표시될 수 있도록 이미지 src 값을 수정해주는 작업을 추가했어요.
그리고 Next.js에서는 public 폴더에서만 이미지를 인식하기 때문에 프로젝트 루트/blog/assets
-> 프로젝트 루트/public/blog/assets
으로 옮기는 과정을 predev
와 prebuild
스크립트로 추가했어요.
SSG인 경우에는 아래처럼 next.config.js
에서 꼭 이미지 최적화 옵션을 사용하지 않도록 해주셔야 해요.
const isDev = process.env.NODE_ENV === 'development'
const nextConfig = {
output: isDev ? 'standalone' : 'export',
reactStrictMode: true,
swcMinify: true,
images: {
unoptimized: true, // 여기요!
remotePatterns: [
{
protocol: 'https',
hostname: 'image.yes24.com',
pathname: '/**',
},
{
protocol: 'https',
hostname: 'images.unsplash.com',
}
],
}
}
module.exports = withContentlayer(nextConfig)
더 개선된 처리 방식은 Next.js 빌드 사이즈를 105MB에서 16MB로 줄이기를 참고해주세요!
Make the best use of what is in your power and take the rest as it happens.
— Epictetus