Express 앱의 탭 아이콘이 비어 보인다면 파일이 존재하더라도 서버에서 제공되지 않았거나 페이지 head에 link되지 않았을 수 있습니다. 이 Express JS favicon 가이드는 static middleware와 표준 HTML link를 사용합니다.

필수 조건

정사각형 브랜드 마크를 준비합니다. Mzu favicondl을 사용하면 SVG와 ICO fallback 파일을 만들고, 선택적으로 Apple touch PNG를 추가할 수 있습니다.

다음 항목이 필요합니다.

Express JS favicon 설정

  1. public 디렉터리 생성

    프로젝트 루트의 public에 브라우저에 제공할 애셋을 다음과 같이 배치합니다.

    my-app/
    ├─ public/
    │  ├─ favicon.svg
    │  ├─ favicon.ico
    │  ├─ apple-touch-icon.png
    │  └─ index.html
    └─ app.js

    Linux 서버는 대문자와 소문자를 구분하므로 파일명을 정확히 유지해야 합니다.

  2. public 디렉터리 제공

    애플리케이션 라우트와 catch-all 404 핸들러보다 먼저 static middleware를 다음과 같이 등록합니다.

    const express = require('express');
    const path = require('path');
    
    const app = express();
    
    app.use(express.static(path.join(__dirname, 'public')));
    
    app.listen(3000, () => {
      console.log('Listening on http://localhost:3000');
    });

    이제 Express는 public/favicon.svg를 /favicon.svg에 매핑하며 public/index.html 파일을 /에서 제공할 수 있습니다. static middleware보다 앞에 배치된 라우트는 아이콘 요청을 먼저 처리할 수 있습니다.

  3. HTML head에 아이콘 연결

    모든 라우트에 아이콘이 적용되도록 공유 레이아웃에 명시적인 link를 다음과 같이 추가합니다.

    <head>
      <link rel='icon' href='/favicon.svg' type='image/svg+xml'>
      <link rel='icon' href='/favicon.ico' sizes='16x16 32x32 48x48'>
      <link rel='apple-touch-icon' href='/apple-touch-icon.png'>
    </head>

    HTML Standard는 rel='icon'을 외부 리소스 link로 정의합니다. 따라서 이 태그들은 브라우저에 명시적인 아이콘 URL을 제공합니다.

  4. 파일과 렌더링된 HTML 확인

    서버를 다시 시작합니다. 다음 명령으로 두 파일을 요청합니다.

    curl -I http://localhost:3000/favicon.svg
    curl -I http://localhost:3000/favicon.ico

    두 요청 모두 HTTP 200 응답이 반환되어야 합니다. 페이지 소스에 동일한 경로가 포함되어 있는지 확인합니다. 파일 요청이 정상적으로 처리되는데도 탭 아이콘이 여전히 잘못 표시된다면 favicon 문제 해결 체크리스트를 사용합니다.

  5. 아이콘 변경 사항 안전하게 게시하기

    아이콘이 변경되면 HTML의 URL을 href='/favicon.svg?v=2'로 업데이트하고, 배포할 때마다 버전을 증가시킵니다. 파일명 해시를 사용하는 방식도 가능합니다. 이 방식은 이전 URL을 재사용하지 않습니다. cache-busting 가이드에서 trade-off을 설명합니다.

Express에서 자주 발생하는 문제

결론

asset 경로, static middleware, 공유 HTML 링크를 일치시키세요. 그러면 전용 icon controller 없이도 모든 Express route에서 동일한 favicon을 사용할 수 있습니다.