Skip to content

Comments

[FEAT] og 태그 및 아이콘 설정#147

Merged
sunhwaaRj merged 2 commits intodevelopfrom
feature/#146-og
Jan 27, 2026
Merged

[FEAT] og 태그 및 아이콘 설정#147
sunhwaaRj merged 2 commits intodevelopfrom
feature/#146-og

Conversation

@sunhwaaRj
Copy link
Contributor

@sunhwaaRj sunhwaaRj commented Jan 27, 2026

✅ PR 유형

어떤 변경 사항이 있었나요?

  • 새로운 기능 추가
  • 버그 수정
  • 코드에 영향을 주지 않는 변경사항(오타 수정, 탭 사이즈 변경, 변수명 변경)
  • 코드 리팩토링
  • 주석 추가 및 수정
  • 문서 수정
  • 빌드 부분 혹은 패키지 매니저 수정
  • 파일 혹은 폴더명 수정
  • 파일 혹은 폴더 삭제

📌 관련 이슈번호


✅ Key Changes

  • og 태그 설정
  • 쓰레드 아이콘 설정

📸 스크린샷 or 실행영상


🎸 기타 사항 or 추가 코멘트

Summary by CodeRabbit

릴리스 노트

  • New Features
    • 팀사이로그 상세 페이지에 동적 메타데이터 생성 기능 추가로 소셜 미디어 공유 시 표시 정보 개선
    • 푸터의 소셜 미디어 링크에 Threads 추가 (모바일 및 데스크톱 모두 지원)

✏️ Tip: You can customize this high-level summary in your review settings.

@sunhwaaRj sunhwaaRj self-assigned this Jan 27, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 27, 2026

Walkthrough

/head/[uuid] 페이지에 동적 OG 메타데이터 생성 함수를 추가하여 요청자 이름을 기반으로 페이지 제목과 메타데이터를 동적으로 설정합니다. 또한 Footer 컴포넌트에 Threads 소셜 링크를 모바일과 데스크톱 양쪽에 추가합니다.

Changes

세부사항 / 파일 변경 내용
동적 메타데이터 생성
src/app/(main)/teampsylog/head/[uuid]/page.tsx
generateMetadata() 함수 추가: axios를 통해 API로 요청자 이름 조회 후 title, openGraph, description 등 동적 메타데이터 생성 (오류 시 기본값 '사용자' 적용)
소셜 링크 확장
src/components/common/Footer.tsx
모바일 및 데스크톱 푸터에 Threads 소셜 링크 추가; 모바일에서 Instagram과 Threads를 flex 컨테이너로 그룹화

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • [FEATURE] OG태그 구현 #79: 다른 라우트 페이지에서 axios를 통해 요청자 이름을 조회하고 동적 OG 태그를 생성하는 generateMetadata({ params })함수를 추가하는 동일한 패턴의 구현

Suggested labels

FEATURE

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 og 태그 설정과 아이콘 설정이라는 주요 변경사항을 명확하게 요약하고 있습니다.
Description check ✅ Passed PR 설명이 템플릿의 모든 필수 섹션(PR 유형, 관련 이슈번호, 주요 변경사항)을 포함하고 있습니다.
Linked Issues check ✅ Passed PR은 이슈 #146의 모든 요구사항을 충족합니다: /head/ 경로의 og 태그 설정 구현 및 스레드 아이콘 추가 완료.
Out of Scope Changes check ✅ Passed 모든 변경사항이 이슈 #146의 범위 내에 있습니다: og 태그 설정과 스레드 아이콘 추가만 포함되어 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@src/app/`(main)/teampsylog/head/[uuid]/page.tsx:
- Around line 17-24: The code is using a client-exposed env var and no request
timeout; update the axios call in page.tsx (where generateMetadata/server-side
logic runs) to use the server-only environment variable process.env.API_BASE_URL
instead of process.env.NEXT_PUBLIC_API_BASE_URL, and add a timeout to the
request (e.g., via the axios config timeout option or by creating an axios
instance with a default timeout) so the GET to /teamficial-log/requester with
params { requesterUuid: uuid } fails fast on slow responses.
- Around line 37-43: The OG image URL in the metadata images array is currently
a relative path ('/og/Teamficial_metatag_Image.jpg') which social crawlers don't
resolve; update the images entry in the metadata object in page.tsx to use an
absolute URL (e.g., https://your-domain.com/og/Teamficial_metatag_Image.jpg) or
alternatively set metadataBase in your root layout (export const metadata with
metadataBase: new URL('https://your-domain.com')) so the existing relative path
resolves correctly; modify either the images URL in page.tsx or add metadataBase
in layout.tsx accordingly.

In `@src/components/common/Footer.tsx`:
- Around line 32-59: In the Footer component update the two Image elements for
the social links (the Instagram and Thread images) to be treated as decorative
by screen readers: set their alt attribute to an empty string (alt="") and also
add aria-hidden="true" or role="presentation" to the Image elements so the
screen reader ignores them and avoids duplicate announcements with the anchor's
aria-label.
🧹 Nitpick comments (2)
src/app/(main)/teampsylog/head/[uuid]/page.tsx (2)

5-5: Next.js 서버 컴포넌트에서는 fetch 사용을 권장합니다.

generateMetadata는 서버에서 실행되므로, Next.js의 내장 fetch를 사용하면 자동 캐싱 및 재검증 기능을 활용할 수 있습니다. 프로젝트 전반에서 axios를 일관되게 사용 중이라면 유지해도 무방합니다.


31-46: Twitter 카드 메타데이터 추가를 고려해 보세요.

OG 태그는 잘 설정되었습니다. Twitter에서의 노출을 개선하려면 twitter 메타데이터도 추가할 수 있습니다.

✨ Twitter 메타데이터 추가 예시
     openGraph: {
       title: `${userName}님의 팀피셜록을 작성해볼까요?`,
       description: `소프트스킬 팀빌딩 서비스, 팀피셜`,
       images: [
         {
           url: '/og/Teamficial_metatag_Image.jpg',
           width: 1200,
           height: 630,
         },
       ],
     },
+    twitter: {
+      card: 'summary_large_image',
+      title: `${userName}님의 팀피셜록을 작성해볼까요?`,
+      description: `소프트스킬 팀빌딩 서비스, 팀피셜`,
+      images: ['/og/Teamficial_metatag_Image.jpg'],
+    },
   };

Comment on lines +17 to +24
const res = await axios.get(
`${process.env.NEXT_PUBLIC_API_BASE_URL}/teamficial-log/requester`,
{
params: {
requesterUuid: uuid,
},
},
);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

환경 변수 및 요청 타임아웃 설정을 확인하세요.

  1. NEXT_PUBLIC_ 접두사가 붙은 환경 변수는 클라이언트에 노출됩니다. generateMetadata는 서버에서만 실행되므로 서버 전용 환경 변수(예: API_BASE_URL) 사용을 권장합니다.
  2. 타임아웃이 설정되지 않아 API 응답 지연 시 페이지 렌더링이 블로킹될 수 있습니다.
🔧 타임아웃 추가 예시
     const res = await axios.get(
       `${process.env.NEXT_PUBLIC_API_BASE_URL}/teamficial-log/requester`,
       {
         params: {
           requesterUuid: uuid,
         },
+        timeout: 5000,
       },
     );
🤖 Prompt for AI Agents
In `@src/app/`(main)/teampsylog/head/[uuid]/page.tsx around lines 17 - 24, The
code is using a client-exposed env var and no request timeout; update the axios
call in page.tsx (where generateMetadata/server-side logic runs) to use the
server-only environment variable process.env.API_BASE_URL instead of
process.env.NEXT_PUBLIC_API_BASE_URL, and add a timeout to the request (e.g.,
via the axios config timeout option or by creating an axios instance with a
default timeout) so the GET to /teamficial-log/requester with params {
requesterUuid: uuid } fails fast on slow responses.

Comment on lines +37 to +43
images: [
{
url: '/og/Teamficial_metatag_Image.jpg',
width: 1200,
height: 630,
},
],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

OG 이미지 URL은 절대 경로로 지정해야 합니다.

소셜 미디어 크롤러(Facebook, Twitter 등)는 상대 경로를 인식하지 못합니다. metadataBase를 설정하거나 전체 URL을 직접 명시해야 합니다.

🐛 수정 방안

방안 1: 절대 URL 직접 사용

       images: [
         {
-          url: '/og/Teamficial_metatag_Image.jpg',
+          url: `${process.env.NEXT_PUBLIC_BASE_URL}/og/Teamficial_metatag_Image.jpg`,
           width: 1200,
           height: 630,
         },
       ],

방안 2: metadataBase 설정 (layout.tsx에서)

// layout.tsx
export const metadata: Metadata = {
  metadataBase: new URL('https://your-domain.com'),
};
🤖 Prompt for AI Agents
In `@src/app/`(main)/teampsylog/head/[uuid]/page.tsx around lines 37 - 43, The OG
image URL in the metadata images array is currently a relative path
('/og/Teamficial_metatag_Image.jpg') which social crawlers don't resolve; update
the images entry in the metadata object in page.tsx to use an absolute URL
(e.g., https://your-domain.com/og/Teamficial_metatag_Image.jpg) or alternatively
set metadataBase in your root layout (export const metadata with metadataBase:
new URL('https://your-domain.com')) so the existing relative path resolves
correctly; modify either the images URL in page.tsx or add metadataBase in
layout.tsx accordingly.

Comment on lines +32 to +59
<a
href="https://www.instagram.com/teamficial.official/"
target="_blank"
rel="noopener noreferrer"
aria-label="인스타그램"
>
<Image
src="/icons/mobile-instagram.svg"
alt="instagram"
width={24}
height={24}
className="justify-end"
/>
</a>
<a
href="https://www.threads.com/@teamficial.official"
target="_blank"
rel="noopener noreferrer"
aria-label="쓰레드"
>
<Image
src="/icons/mobile-thread.svg"
alt="thread"
width={24}
height={24}
className="justify-end"
/>
</a>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

fd "Footer.tsx" --type f

Repository: TEAMFICIAL/teamficial-fe

Length of output: 162


🌐 Web query:

Next.js Image component aria-hidden attribute support

💡 Result:

Yes. next/image forwards “other properties” to the underlying <img> element (it only excludes srcSet and decoding), so aria-hidden="true" is supported and will end up on the rendered <img>. [1]

For decorative images, accessibility guidance is to use an empty alt (alt="") so screen readers ignore it; you can add aria-hidden="true" as an extra safeguard, but alt is still required by next/image. [1][2][3]

import Image from "next/image";

<Image
  src="/decorative.png"
  width={200}
  height={200}
  alt=""
  aria-hidden="true"
/>

Sources: [1] Next.js <Image> API (“Other Props” forwarding) • [2] W3C WAI decorative images (use alt="") • [3] MDN aria-hidden behavior


🌐 Web query:

decorative images accessibility best practices alt empty string aria-hidden

💡 Result:

Decorative images: what to do (and when)

1) For a purely decorative <img> (no meaning, no function): use a null alt

<img src="..." alt="">
  • This marks the image as decorative so screen readers ignore it.
  • Do not omit alt (missing alt can cause some AT to announce the filename).
  • Make sure it’s exactly empty—no spaces like alt=" " (some AT may still announce it).
    Sources: WebAIM on decorative images and alt="" [1], W3C Images tutorial (decorative) [2], W3C tips re: no space in empty alt [3].

2) Prefer CSS for purely visual styling when possible

  • If it’s only for decoration/layout (borders, flourishes, background textures), use a CSS background image instead of <img> to keep it out of the semantic content.
    Sources: WebAIM [1], HTML Standard guidance [4].

3) role="presentation" / role="none": usually unnecessary for <img>

  • An <img> with alt="" is already treated as decorative in accessibility mappings; adding role="presentation"/none is typically redundant.
    Source: W3C ACT rule describing “marked as decorative” via alt="" or presentational roles [5].

4) aria-hidden="true": use sparingly, and don’t use it to “fix” missing alt

  • aria-hidden="true" removes content from the accessibility tree, which is a different intent than “this image is decorative.”
  • Avoid putting aria-hidden="true" on anything focusable/interactive (it can create confusing keyboard/AT behavior).
    Source: W3C ACT notes on programmatically hidden content and focusable elements [6].

Practical rule of thumb

  • Decorative <img>alt="" (best default).
  • Decorative pure styling → CSS background (best if feasible).
  • Only use aria-hidden="true" when you intentionally want something not exposed to AT at all (and ensure it’s not focusable/interactive).

References

  1. WebAIM – Alternative Text (Decorative images use alt="") [1]
  2. W3C WAI Images Tutorial – Decorative images (alt="", don’t omit alt) [2]
  3. W3C WAI Images Tips – empty alt must not contain spaces [3]
  4. HTML Standard – decorative/supplemental images and empty alt, CSS for site-wide decoration [4]
  5. W3C ACT – “marked as decorative” includes img with alt="" or role none/presentation [5]
  6. W3C ACT – cautions about aria-hidden and focusable elements [6]

🏁 Script executed:

cat -n src/components/common/Footer.tsx | head -100

Repository: TEAMFICIAL/teamficial-fe

Length of output: 4501


이미지 alt 속성 수정 필요 - 중복 낭독 방지

앵커에 aria-label이 있으므로 이미지는 장식 요소로 처리해야 합니다. alt=""만 사용하면 스크린리더가 무시하므로 중복 낭독을 피할 수 있습니다.

♿ 제안 수정
                 <Image
                   src="/icons/mobile-instagram.svg"
-                  alt="instagram"
+                  alt=""
                   width={24}
                   height={24}
                   className="justify-end"
                 />
                 <Image
                   src="/icons/mobile-thread.svg"
-                  alt="thread"
+                  alt=""
                   width={24}
                   height={24}
                   className="justify-end"
                 />
                 <Image src="/icons/mail.svg" 
-                  alt="mail" 
+                  alt=""
                   width={24} height={24} />
                 <Image src="/icons/instagram.svg" 
-                  alt="instagram" 
+                  alt=""
                   width={24} height={24} />
                 <Image src="/icons/thread.svg" 
-                  alt="thread" 
+                  alt=""
                   width={24} height={24} />
🤖 Prompt for AI Agents
In `@src/components/common/Footer.tsx` around lines 32 - 59, In the Footer
component update the two Image elements for the social links (the Instagram and
Thread images) to be treated as decorative by screen readers: set their alt
attribute to an empty string (alt="") and also add aria-hidden="true" or
role="presentation" to the Image elements so the screen reader ignores them and
avoids duplicate announcements with the anchor's aria-label.

@sunhwaaRj sunhwaaRj merged commit 3215647 into develop Jan 27, 2026
2 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jan 27, 2026
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] OG 태그 수정

1 participant