master-project
CHAPTER 24 / 50
읽기 약 2분
FUNCTION
접근성 + SEO 메타데이터
핵심 개념
ARIA·키보드 내비·시맨틱 마크업·metadata API·OpenGraph·sitemap·robots — 검색·접근 양쪽 최적화.
본문
시맨틱 마크업
// ❌ 안티패턴
<div onClick={...}>버튼</div>
// ✅ 시맨틱
<button onClick={...}>버튼</button>
<nav><a href="/dashboard">대시보드</a></nav>
<main><article><h1>제목</h1></article></main>
<aside>사이드바</aside>
<footer>푸터</footer>ARIA
// 아이콘 버튼 — 라벨 필수
<button aria-label="알림 보기">
<Bell className="h-5 w-5" aria-hidden="true" />
</button>
// 모달
<div role="dialog" aria-modal="true" aria-labelledby="dialog-title">
<h2 id="dialog-title">정말 삭제하시겠습니까?</h2>
</div>
// Live region (실시간 상태 변화)
<div role="status" aria-live="polite">
{isGenerating && '생성 중'}
</div>키보드 내비게이션
✓ Tab으로 모든 인터랙티브 요소 순회
✓ Enter/Space로 버튼 활성화
✓ Esc로 모달 닫기
✓ 화살표로 메뉴 항목 이동
✓ focus ring 표시 (Tailwind: focus:ring-2)<button className="focus:ring-2 focus:ring-primary focus:outline-none">
Generate
</button>Lighthouse 접근성 100점 체크리스트
✓ <html lang="ko">
✓ alt 모든 이미지 (장식은 alt="")
✓ 색 대비 4.5:1 이상 (WCAG AA)
✓ 폼 input마다 <label>
✓ 폰트 12px 이상
✓ Skip to main content 링크
✓ heading 계층 (h1 → h2 → h3 순서)generateMetadata API
// src/app/(app)/generate/page.tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'AI 카피 생성', // → "AI 카피 생성 | My SaaS"
description: '한국 마케터를 위한 AI 카피 도구. 1분 안에 마케팅 카피 5개 생성.',
}
// 동적
export async function generateMetadata({ params }): Promise<Metadata> {
const { id } = await params
const gen = await getGeneration(id)
return {
title: gen.prompt.slice(0, 30),
description: gen.result.slice(0, 160),
}
}OpenGraph + Twitter Card
// src/app/layout.tsx
export const metadata: Metadata = {
metadataBase: new URL('https://mysaas.com'),
title: { template: '%s | My SaaS', default: 'My SaaS — AI 글쓰기' },
description: '한국 마케터를 위한 AI 카피 SaaS',
openGraph: {
title: 'My SaaS — AI 글쓰기',
description: '한국 마케터를 위한 AI 카피 SaaS',
url: 'https://mysaas.com',
siteName: 'My SaaS',
images: [{ url: '/og.png', width: 1200, height: 630 }],
locale: 'ko_KR',
type: 'website',
},
twitter: {
card: 'summary_large_image',
title: 'My SaaS',
description: '...',
images: ['/og.png'],
},
}sitemap.ts
// src/app/sitemap.ts
import type { MetadataRoute } from 'next'
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const staticPages = ['/', '/pricing', '/blog'].map(path => ({
url: `https://mysaas.com${path}`,
lastModified: new Date(),
changeFrequency: 'weekly' as const,
priority: path === '/' ? 1 : 0.8,
}))
// 동적 페이지 (블로그 등)
const posts = await getPosts()
const dynamicPages = posts.map(p => ({
url: `https://mysaas.com/blog/${p.slug}`,
lastModified: p.updatedAt,
}))
return [...staticPages, ...dynamicPages]
}robots.ts
// src/app/robots.ts
import type { MetadataRoute } from 'next'
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: '*',
allow: '/',
disallow: ['/dashboard', '/api', '/settings'], // 인증 필요 페이지 X
},
sitemap: 'https://mysaas.com/sitemap.xml',
}
}JSON-LD (Structured Data)
// 랜딩 페이지
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify({
'@context': 'https://schema.org',
'@type': 'SoftwareApplication',
name: 'My SaaS',
applicationCategory: 'BusinessApplication',
offers: { '@type': 'Offer', price: '19', priceCurrency: 'USD' },
aggregateRating: { '@type': 'AggregateRating', ratingValue: '4.8', ratingCount: '120' },
}) }}
/>다음 챕터
CH.25 "프론트엔드 종합: 전체 UI 코드 리뷰".
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 마스터 프로젝트의 a11y + SEO 부분을 분석해서 실전 적용 + 개선 우선순위 3가지를 알려줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
a11y + SEO 관련 모범 사례·안티패턴 5개를 비교 분석해서 실전 적용를 위한 추천 방안을 알려줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 프로젝트 전체에서 a11y + SEO 최적화 가능 위치와 리스크를 보고해줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 한국 1인 개발자 시장의 a11y + SEO 트렌드와 차별화 포인트를 정리해줘.
⭐ 이것만 기억하세요
접근성 + SEO 메타데이터는 이 3가지만 확실히 잡으세요
1.시맨틱 + ARIA + 키보드 = a11y 100점 기반
2.Metadata API + sitemap.ts + robots.ts = SEO 표준
3.다음 챕터에서 프론트엔드 종합
공유하기
진행도 24 / 50