Next.Js 메타데이터 및 OpenGraph 이미지 경로 이슈 해결 (문제 해결)

Devinix·2025년 12월 22일

[문제 해결]

목록 보기
34/44
post-thumbnail

개요

Next.js App Router에서 generateMetadata를 사용해
SEO 설정과 OpenGraph 이미지를 설정하던 중 예상치 못한 문제가 발생했다.

함수명, 변수명, 컴포넌트명은 모두 예시용 가명으로 작성되어 있다.

문제 상황

AWS Amplify로 배포한 Next.Js 앱에서 프로필 페이지를 포함한 여러 페이지에서 OpenGraph 이미지가 표시되지 않았다. 페이지 소스를 확인해보니 다음과 같은 메타 태그가 생성되어 있었다.

<meta property="og:image" content="http://localhost:3000/assets/profile_og.png">

이미 배포된 서비스임에도 불구하고 OpenGraph 이미지 URL이 localhost:3000을 가리키고 있었다.

원인

[Next.js의 메타데이터 처리 방식]

OpenGraph, Twitter 메타 태그에 사용되는 이미지 URL은 절대 URL이어야 한다.

Next.js는 generateMetadata에서 이미지 URL이 상대 경로로 들어오면
이를 자동으로 절대 URL로 변환하려고 시도한다.

문제는 이 변환 과정에서 어떤 호스트를 기준으로 삼느냐다.

  1. generateMetadata가 빌드 타임에 실행
  2. 요청 컨텍스트가 없어 Host 헤더를 알 수 없음
  3. NEXT_PUBLIC_SITE_URL이 설정되지 않았거나
    빌드 시점에 주입되지 않음

이 경우 Next.Js는 마지막 fallback 값인 localhost:3000을 사용한다.

결과적으로, 배포 환경임에도 OpenGraph 이미지가 localhost 기준으로 생성된 것이다.

[문제의 코드]

export async function generateMetadata({ params }: { params: { userId: string } }) {
  const userData = await fetchUserData(params.userId);

  const defaultImagePath = '/assets/default_profile.png';
  const imageUrl = userData.profileImage || defaultImagePath; // 상대 경로

  return {
    openGraph: {
      images: [
        {
          url: imageUrl, // 상대 경로 → localhost로 변환됨
          alt: userData.name,
        },
      ],
    },
  };
}

imageUrl이 상대 경로인 상태로 반환되면서 Next.js가 이를 자동 변환했고, 그 결과가 localhost:3000이었다.

해결 과정

환경변수 확인

가장 먼저 AWS Amplify 콘솔에서 환경변수 설정 상태를 확인했다.

[경로]
Amplify Console → App 선택 → Environment variables
여기서 사이트의 도메인이 각 브랜치에 정확히 설정되어 있는지 확인했다.

절대 URL로 명시적 변환

문제의 핵심은 Next.js의 자동 변환 로직에 의존했다는 점이었다.

따라서 상대 경로를 그대로 넘기지 않고, 메타데이터 단계에서 절대 URL을 명시적으로 생성하도록 수정했다.

export async function generateMetadata({ params }: { params: { userId: string } }) {
  const userData = await fetchUserData(params.userId);

  // 사이트 URL을 환경변수에서 가져오기
  const siteUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://example.com';
  const defaultImagePath = '/assets/default_profile.png';

  // 기본 이미지를 절대 URL로 변환
  const defaultImageUrl = `${siteUrl}${defaultImagePath}`;

  // 프로필 이미지가 있으면 사용, 없으면 기본 이미지
  const profileImageUrl = userData.profileImage
    ? formatImageUrl(userData.profileImage) // 이미 절대 URL로 변환하는 함수
    : undefined;

  const imageUrl = profileImageUrl || defaultImageUrl;

  return {
    openGraph: {
      images: [
        {
          url: imageUrl, // 절대 URL 보장
          alt: userData.name,
        },
      ],
    },
  };
}

이후 배포 브랜치별로 NEXT_PUBLIC_SITE_URL을 명확히 분리했다.

[MAIN]
NEXT_PUBLIC_SITE_URL=https://example.com

[DEV]
NEXT_PUBLIC_SITE_URL=https://dev.example.com

빌드 타임에 url을 주입되도록 설정한 것이 핵심이다.

수정 후 생성된 메타 태그는 다음과 같이 나왔다.

<meta property="og:image" content="https://example.com/assets/profile_og.png">

배포 환경에서도 OpenGraph 미리보기가 정상적으로 표시되었다.

결론

이 문제의 본질은 상대 경로 + 빌드 타임 메타데이터 + 환경변수 미설정의 조합이었다.

핵심 교훈은 명확하다.

  1. OpenGraph 이미지는 항상 절대 URL
  2. generateMetadata에서 Next.js의 자동 변환 로직에 의존하지 말 것
  3. 배포 환경에서는 빌드 타임 환경변수 주입 여부를 반드시 확인할 것
profile
React, Next.Js, React-Native

0개의 댓글