Astro 프로젝트를 새로 만들고 Vercel이나 Netlify에 배포한 후, 브라우저 탭에 여전히 기본 그라데이션 로켓 아이콘이 자랑스럽게 떠 있는 것을 본 적이 있다면... 걱정하지 마세요. 당신만 겪는 일이 아닙니다. Next.js나 순수 HTML에서 넘어온 개발자들이 이 문제를 겪는 것을 수없이 보았습니다. astro 프레임워크 favicon 설정이 어려운 것은 아니지만, Astro 특유의 에셋 파이프라인 때문에 .ico 파일을 아무 데나 던져놓고 작동하기를 바랄 수는 없습니다.
Astro는 기존 번들러와 다르게 정적 에셋을 처리합니다. 아이콘을 잘못된 폴더에 넣으면 Vite가 이를 무시하거나, 파일명을 해시 처리하거나, 프로덕션 환경에서 404 에러를 발생시킵니다. 지금 바로 이 문제를 해결해 봅시다.
가장 큰 고민거리: public/ vs src/assets/
Astro에서 개발자들이 가장 흔히 하는 실수는 favicon을 src/assets/ 디렉토리 안에 넣는 것입니다. Astro의 에셋 파이프라인은 콘텐츠 이미지를 최적화하는 데는 훌륭하지만, 캐시 제어를 위해 파일명을 공격적으로 해시 처리합니다(예: icon.svg를 icon.a8b3c9.svg로 변경).
브라우저, RSS 리더, 웹 크롤러는 favicon이 예측 가능하고 정적인 URL(이상적으로는 도메인의 최상위 루트)에 있기를 기대합니다. 이를 달성하려면 favicon 파일을 반드시 public/ 디렉토리에 배치해야 합니다.
Astro는 public/ 폴더 안의 모든 항목을 파일명 변경 없이 빌드 출력(일반적으로 dist/ 폴더)으로 직접 복사합니다. 이를 통해 public/favicon.svg가 yoursite.com/favicon.svg로 완벽하게 매핑됩니다.
1단계: 모던 아이콘 스택 준비하기
지금은 2026년입니다. 10년 전에 사라진 기기들을 위해 30가지의 다양한 레거시 아이콘 크기를 생성하는 일은 이제 그만두세요. 완벽한 설정을 위해서는 딱 세 개의 파일만 있으면 됩니다.
- favicon.svg: 모던 웹 표준입니다. 무한히 확장 가능하며 CSS 미디어 쿼리를 통해 다크 모드를 지원합니다.
- favicon.ico: 구형 브라우저를 위한 32x32 크기의 아이콘을 포함하는 레거시 폴백입니다.
- apple-touch-icon.png: iOS 홈 화면 및 북마크 전용 180x180 PNG 파일입니다.
고해상도의 로고 PNG 파일만 가지고 있다면, Mzu favicondl에 넣고 돌려서 이 세 가지 파일 스택을 즉시 생성하세요. (왜 이 특정 스택이 최고인지 더 자세히 알고 싶다면 favicon 모범 사례 가이드를 확인하세요).
2단계: Public 디렉토리에 파일 배치하기
방금 생성한 세 개의 파일을 Astro 프로젝트의 public/ 폴더 루트에 직접 넣습니다. 프로젝트 구조는 다음과 같아야 합니다:
├── public/
│ ├── favicon.svg
│ ├── favicon.ico
│ └── apple-touch-icon.png
├── src/
│ ├── components/
│ ├── layouts/
│ └── pages/
└── astro.config.mjs절대 public/images/ 폴더 안에 중첩하지 마세요. 루트에 유지해야 합니다. 그래야 HTML을 읽지 않고 맹목적으로 /favicon.ico를 요청하는 도구들도 필요한 파일을 찾을 수 있습니다.
3단계: BaseHead 컴포넌트 업데이트하기
대부분의 최신 Astro 템플릿은 <head> 섹션에 공유 컴포넌트를 사용하며, 일반적으로 BaseHead.astro로 명명되거나 Layout.astro 내부에서 처리됩니다. 해당 파일을 엽니다.
올바른 HTML link 태그를 추가해야 합니다. href 속성 앞의 슬래시에 주의하세요. 이것이 핵심입니다.
<!-- src/components/BaseHead.astro 내부 -->
<meta charset='utf-8' />
<meta name='viewport' content='width=device-width,initial-scale=1' />
<!-- Favicon 스택 -->
<link rel='icon' href='/favicon.ico' sizes='32x32' />
<link rel='icon' href='/favicon.svg' type='image/svg+xml' />
<link rel='apple-touch-icon' href='/apple-touch-icon.png' />
<!-- 선택 사항: Web App Manifest -->
<link rel='manifest' href='/site.webmanifest' />GitHub가 브라우저 아이콘을 어떻게 처리하는지 살펴보세요. 그들은 모던 브라우저를 위해 선명한 SVG를 제공하고 시스템 테마에 따라 동적으로 색상을 전환하지만, 라우팅은 루트 수준에서 매우 단순하게 유지합니다. Astro의 public/ 디렉토리와 절대 경로를 사용하면 이러한 GitHub 수준의 완성도를 쉽게 재현할 수 있습니다.
Astro의 흔한 함정들
누락된 선행 슬래시
href='/favicon.svg' 대신 href='favicon.svg'라고 작성하면 중첩된 라우트에서 아이콘이 깨집니다. 예를 들어 사용자가 yoursite.com/blog/my-post/를 방문하면 브라우저는 yoursite.com/blog/my-post/favicon.svg에서 아이콘을 찾으려다 실패합니다. 항상 슬래시로 시작하는 절대 경로를 사용하세요. 여전히 문제가 발생한다면 favicon 누락 문제 해결 가이드를 검토해 보세요.
Base Path 설정 문제
Astro 사이트를 하위 디렉토리(예: GitHub Pages)에 배포하고 astro.config.mjs에서 base 옵션을 설정한 경우, 표준 절대 경로는 작동하지 않습니다. Astro에 내장된 base 헬퍼를 사용해야 합니다.
프런트매터에서 import.meta.env.BASE_URL을 가져와 링크에 적용합니다:
---
const baseUrl = import.meta.env.BASE_URL;
---
<link rel='icon' href=`${baseUrl}favicon.svg` type='image/svg+xml' />이렇게 하면 로컬호스트에서 실행 중이든 중첩된 프로덕션 URL에 배포되었든 관계없이 favicon 경로가 동적으로 조정됩니다.
라우팅 규칙만 이해하면 Astro 프레임워크 favicon을 올바르게 설정하는 데 2분이면 충분합니다. public/ 폴더를 고수하고, 절대 경로를 사용하며, 나머지는 브라우저가 알아서 처리하도록 두세요.