์ปจํ
์คํธ ๋ธ๋ก
| Key |
Value |
| Category |
frontend |
| Checklist |
ISS-UI-04 โ Missing generateMetadata/metadata export (SEO + OG tags) |
| Priority |
P1 ๐ |
| Scan Date |
2026-04-16 |
| Flagged By |
main-session verification |
์์ฝ
- WHAT:
frontend/src/app/ ํ์ 14๊ฐ page.tsx/layout.tsx ์ค root layout.tsx ํ๋๋ง metadata export๋ฅผ ๊ฐ์ง๊ณ ์์. ๋ก๊ทธ์ธ, ํ์๊ฐ์
, admin, chat ํ์ด์ง ๋ชจ๋ OG/Twitter ๋ฉํ ๋๋ฝ
- WHY: ๋ชจ๋ ๊ณต์ ๋งํฌ๊ฐ ๋์ผํ root metadata๋ฅผ ์ฌ์ฉ โ ํ์ด์ง๋ณ title/description ์์. ๊ฒ์ ์์ง SEO ์์ค + Slack/Discord/Twitter ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ ํ
- WHERE:
frontend/src/app/(auth)/login/page.tsx, (auth)/register/page.tsx, (main)/page.tsx, (main)/admin/**/page.tsx, ๊ธฐํ page.tsx ํ์ผ๋ค
- SEVERITY: HIGH โ ๊ณต๊ฐ ๋ฐฐํฌ ์ SEO/shareability ์ง์ ์ํฅ
Evidence
| # |
File |
Line |
Finding |
Flagged By |
Confidence |
| 1 |
frontend/src/app/layout.tsx |
โ |
export const metadata ์กด์ฌ (root๋ง) |
main-session |
High |
| 2 |
frontend/src/app/(auth)/login/page.tsx |
โ |
metadata export ์์ |
main-session |
High |
| 3 |
frontend/src/app/(auth)/register/page.tsx |
โ |
metadata export ์์ |
main-session |
High |
| 4 |
frontend/src/app/(main)/admin/page.tsx |
โ |
metadata export ์์ |
main-session |
High |
| 5 |
frontend/src/app/(main)/admin/users/page.tsx |
โ |
metadata export ์์ |
main-session |
High |
| 6 |
frontend/src/app/(main)/admin/settings/page.tsx |
โ |
metadata export ์์ |
main-session |
High |
| 7 |
frontend/src/app/(main)/admin/approvals/page.tsx |
โ |
metadata export ์์ |
main-session |
High |
| 8 |
frontend/src/app/(auth)/pending-approval/page.tsx |
โ |
metadata export ์์ |
main-session |
High |
| 9 |
frontend/src/app/(auth)/account-suspended/page.tsx |
โ |
metadata export ์์ |
main-session |
High |
| 10 |
frontend/src/app/(auth)/verify-request/page.tsx |
โ |
metadata export ์์ |
main-session |
High |
์ด 13/14 ํ์ผ์์ metadata ๋๋ฝ.
์ํฅ ๋ถ์
์ํฅ ๋ฒ์
- ๋ชจ๋ ๊ณต๊ฐ URL (์ฃผ๋ก ๋ก๊ทธ์ธ/ํ์๊ฐ์
/๋๋ฉ)
- Slack/Discord/Twitter/LinkedIn ๋ฏธ๋ฆฌ๋ณด๊ธฐ
- Google/Bing SEO ์ธ๋ฑ์ฑ
์ฅ์ ์๋๋ฆฌ์ค
- ์ฌ์ฉ์๊ฐ Slack์ ๋ก๊ทธ์ธ ํ์ด์ง URL ๊ณต์
- ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์นด๋์ root layout์ generic title/description๋ง ํ์
- ๋ก๊ทธ์ธ ํ์ด์ง์ธ์ง ์์๋ณผ ์ ์์ โ ํด๋ฆญ ์ฃผ์
- ๋๋ Google ๊ฒ์ ๊ฒฐ๊ณผ์์ ๋ชจ๋ ํ์ด์ง๊ฐ ๋์ผ title/description๋ก ํ์ โ ํด๋ฆญ๋ฅ ์ ์กฐ
๊ธด๊ธ๋
- ๊ณต๊ฐ OSS ํ๋ก์ ํธ๋ก์ marketing/SEO ์ค์
- Vercel ๋ฐฐํฌ ๋ฒํผ์ด README์ ์์ด ๋ค์ ์ฌ์ฉ์๊ฐ ์์ฒด ๋ฐฐํฌํ๋๋ฐ, ๊ฐ ๋ฐฐํฌ๋ณธ์ ๊ธฐ๋ณธ SEO๊ฐ ๋ถ์ค
์ ์ ํด๊ฒฐ ๋ฐฉ์
์ ๊ทผ ๋ฐฉ๋ฒ
๊ฐ ๋ผ์ฐํธ segment์ ์ ์ ํ metadata ์ถ๊ฐ:
// frontend/src/app/(auth)/login/page.tsx
import type { Metadata } from \"next\";
export const metadata: Metadata = {
title: \"Sign In\",
description: \"Sign in to access your LangGraph Chat UI.\",
};
admin ๋ผ์ฐํธ ๊ทธ๋ฃน์ layout.tsx์์ ๊ณตํต metadata ์ค์ :
// frontend/src/app/(main)/admin/layout.tsx
export const metadata: Metadata = {
title: {
template: \"%s โ Admin\",
default: \"Admin\",
},
robots: { index: false, follow: false }, // admin์ ๊ฒ์ ์์ง ์ ์ธ
};
i18n ๋ผ๋ฒจ์ ํ์ฉํด locale๋ณ metadata:
// app/(auth)/login/page.tsx
export async function generateMetadata(): Promise<Metadata> {
const t = await getTranslations(\"login\");
return {
title: t(\"meta.title\"),
description: t(\"meta.description\"),
};
}
๋์
- root layout์๋ง ๋ชจ๋ ๊ฒ ๋ชฐ๊ธฐ: ํ์ด์ง๋ณ ๊ตฌ๋ถ ์๋จ โ ํ์ฌ ์ํ, ํด๊ฒฐ ์๋จ
- Client-side
<Head>: Next.js 15 App Router๋ metadata API ์ฌ์ฉ ๊ถ์ฅ, react-head ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋์์ด์ง๋ง SSR SEO์ ๋ถ๋ฆฌ
์์ฉ ๊ธฐ์ค
์ฐธ์กฐ
- ๊ด๋ จ ํ์ผ:
frontend/src/app/**/page.tsx, frontend/src/app/**/layout.tsx
- Checklist ํญ๋ชฉ: ISS-UI-04
- Next.js 15 Metadata API
- ๊ด๋ จ ์ด์: ์์
์ฌํ ๋ฐฉ๋ฒ
์ฌ์ ์กฐ๊ฑด
๋จ๊ณ
curl -s http://localhost:3000/login | grep '<title>'
- root layout์ title๋ง ํ์๋๋์ง ํ์ธ
<meta property=\"og:title\"> ์กด์ฌ ํ์ธ
๊ธฐ๋ ๊ฒฐ๊ณผ
ํ์ด์ง๋ณ ๊ณ ์ title, og:title, og:description
์ค์ ๊ฒฐ๊ณผ
๋ชจ๋ ํ์ด์ง์ root layout์ ๋์ผํ title๋ง
๊ด๋ จ ์ฝ๋ ์ปจํ
์คํธ
| File |
Role |
Relevance |
frontend/src/app/layout.tsx |
Root metadata (์ ์ผํ ๊ธฐ์กด ๊ตฌํ) |
์ฐธ๊ณ ํ
ํ๋ฆฟ |
frontend/src/app/(auth)/**/page.tsx |
์ธ์ฆ ํ์ด์ง๋ค |
์์ ๋์ (๋ค์) |
frontend/src/app/(main)/admin/**/page.tsx |
admin ํ์ด์ง๋ค |
์์ ๋์ (๋ค์) |
frontend/src/i18n/messages/*.json |
i18n ๋ฉ์์ง |
metadata ๋ฒ์ญ์ ํ์ฉ |
Detected by oh-my-braincrew `omb:issue` scan
Category: frontend | Scan date: 2026-04-16
`omb-issue-scan category=frontend checklist=ISS-UI-04`
์ปจํ ์คํธ ๋ธ๋ก
ISS-UI-04โ Missing generateMetadata/metadata export (SEO + OG tags)์์ฝ
frontend/src/app/ํ์ 14๊ฐpage.tsx/layout.tsx์ค rootlayout.tsxํ๋๋งmetadataexport๋ฅผ ๊ฐ์ง๊ณ ์์. ๋ก๊ทธ์ธ, ํ์๊ฐ์ , admin, chat ํ์ด์ง ๋ชจ๋ OG/Twitter ๋ฉํ ๋๋ฝfrontend/src/app/(auth)/login/page.tsx,(auth)/register/page.tsx,(main)/page.tsx,(main)/admin/**/page.tsx, ๊ธฐํ page.tsx ํ์ผ๋คEvidence
frontend/src/app/layout.tsxexport const metadata์กด์ฌ (root๋ง)frontend/src/app/(auth)/login/page.tsxfrontend/src/app/(auth)/register/page.tsxfrontend/src/app/(main)/admin/page.tsxfrontend/src/app/(main)/admin/users/page.tsxfrontend/src/app/(main)/admin/settings/page.tsxfrontend/src/app/(main)/admin/approvals/page.tsxfrontend/src/app/(auth)/pending-approval/page.tsxfrontend/src/app/(auth)/account-suspended/page.tsxfrontend/src/app/(auth)/verify-request/page.tsx์ด 13/14 ํ์ผ์์ metadata ๋๋ฝ.
์ํฅ ๋ถ์
์ํฅ ๋ฒ์
์ฅ์ ์๋๋ฆฌ์ค
๊ธด๊ธ๋
์ ์ ํด๊ฒฐ ๋ฐฉ์
์ ๊ทผ ๋ฐฉ๋ฒ
๊ฐ ๋ผ์ฐํธ segment์ ์ ์ ํ metadata ์ถ๊ฐ:
admin๋ผ์ฐํธ ๊ทธ๋ฃน์ layout.tsx์์ ๊ณตํต metadata ์ค์ :i18n ๋ผ๋ฒจ์ ํ์ฉํด locale๋ณ metadata:
๋์
<Head>: Next.js 15 App Router๋ metadata API ์ฌ์ฉ ๊ถ์ฅ, react-head ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋์์ด์ง๋ง SSR SEO์ ๋ถ๋ฆฌ์์ฉ ๊ธฐ์ค
metadata๋๋generateMetadata์ถ๊ฐ (์ต์ title, description)robots: { index: false }์ถ๊ฐview-source:์์<meta>ํ๊ทธ ํ์ธcd frontend && pnpm build && curl -s http://localhost:3000/login | grep '<title>'์ฐธ์กฐ
frontend/src/app/**/page.tsx,frontend/src/app/**/layout.tsx์ฌํ ๋ฐฉ๋ฒ
์ฌ์ ์กฐ๊ฑด
๋จ๊ณ
curl -s http://localhost:3000/login | grep '<title>'<meta property=\"og:title\">์กด์ฌ ํ์ธ๊ธฐ๋ ๊ฒฐ๊ณผ
ํ์ด์ง๋ณ ๊ณ ์ title, og:title, og:description
์ค์ ๊ฒฐ๊ณผ
๋ชจ๋ ํ์ด์ง์ root layout์ ๋์ผํ title๋ง
๊ด๋ จ ์ฝ๋ ์ปจํ ์คํธ
frontend/src/app/layout.tsxfrontend/src/app/(auth)/**/page.tsxfrontend/src/app/(main)/admin/**/page.tsxfrontend/src/i18n/messages/*.json