+
+
+
+
+```
+
+---
+
+# 3. SEO / GEO / AEO 전략 Rules
+
+## 3-1. SEO 기본 규칙
+
+### useSeoMeta 우선 사용 원칙
+
+Nuxt 4에서는 `useSeoMeta`를 `useHead`보다 우선 사용한다. TypeScript 자동완성 지원 및 XSS 안전성 보장.
+
+```typescript
+// app/composables/useSeo.ts
+interface SeoOptions {
+ title: string
+ description: string
+ image?: string
+ url?: string
+ type?: 'website' | 'article' | 'product'
+ noindex?: boolean
+}
+
+export function useSeo(options: SeoOptions) {
+ const config = useRuntimeConfig()
+ const route = useRoute()
+
+ const canonicalUrl = options.url ?? `${config.public.siteUrl}${route.path}`
+ const ogImage = options.image ?? `${config.public.siteUrl}/og-default.png`
+
+ useSeoMeta({
+ title: options.title,
+ description: options.description,
+ ogTitle: options.title,
+ ogDescription: options.description,
+ ogImage: ogImage,
+ ogUrl: canonicalUrl,
+ ogType: options.type ?? 'website',
+ ogSiteName: config.public.siteName,
+ twitterCard: 'summary_large_image',
+ twitterTitle: options.title,
+ twitterDescription: options.description,
+ twitterImage: ogImage,
+ robots: options.noindex ? 'noindex,nofollow' : 'index,follow',
+ })
+
+ useHead({
+ link: [{ rel: 'canonical', href: canonicalUrl }],
+ })
+}
+```
+
+### 페이지 타이틀 템플릿
+
+```typescript
+// nuxt.config.ts
+export default defineNuxtConfig({
+ app: {
+ head: {
+ titleTemplate: '%s | 사이트명',
+ title: '기본 타이틀',
+ },
+ },
+})
+```
+
+### robots.txt 설정
+
+```
+# public/robots.txt
+User-agent: *
+Allow: /
+Disallow: /admin/
+Disallow: /api/
+Disallow: /private/
+
+# AI 크롤러 허용 (GEO 전략)
+User-agent: GPTBot
+Allow: /
+
+User-agent: ClaudeBot
+Allow: /
+
+User-agent: PerplexityBot
+Allow: /
+
+User-agent: Google-Extended
+Allow: /
+
+Sitemap: https://example.com/sitemap.xml
+```
+
+### sitemap.xml 동적 생성
+
+```typescript
+// nuxt.config.ts
+export default defineNuxtConfig({
+ site: { url: 'https://example.com', name: '사이트명' },
+ sitemap: {
+ sources: ['/api/sitemap/urls'],
+ defaults: { changefreq: 'weekly', priority: 0.8 },
+ exclude: ['/admin/**', '/api/**', '/private/**'],
+ },
+})
+```
+
+---
+
+## 3-2. 구조화 데이터 Schema.org JSON-LD
+
+모든 JSON-LD는 SSR 시점에 렌더링. 페이지 콘텐츠와 구조화 데이터는 반드시 일치해야 함.
+
+```typescript
+// app/composables/useJsonLd.ts
+export function useJsonLd(schema: Record | Record[]) {
+ useHead({
+ script: [{
+ type: 'application/ld+json',
+ innerHTML: JSON.stringify(schema),
+ }],
+ })
+}
+```
+
+### Organization + WebSite (전역 app.vue)
+
+```typescript
+useJsonLd([
+ {
+ '@context': 'https://schema.org',
+ '@type': 'Organization',
+ '@id': 'https://example.com/#organization',
+ name: '회사명',
+ url: 'https://example.com',
+ logo: { '@type': 'ImageObject', url: 'https://example.com/logo.png' },
+ sameAs: ['https://www.instagram.com/example', 'https://twitter.com/example'],
+ },
+ {
+ '@context': 'https://schema.org',
+ '@type': 'WebSite',
+ '@id': 'https://example.com/#website',
+ url: 'https://example.com',
+ name: '사이트명',
+ publisher: { '@id': 'https://example.com/#organization' },
+ potentialAction: {
+ '@type': 'SearchAction',
+ target: { '@type': 'EntryPoint', urlTemplate: 'https://example.com/search?q={search_term_string}' },
+ 'query-input': 'required name=search_term_string',
+ },
+ },
+])
+```
+
+### BreadcrumbList
+
+```typescript
+// app/composables/useBreadcrumb.ts
+interface BreadcrumbItem { name: string; path: string }
+
+export function useBreadcrumb(items: BreadcrumbItem[]) {
+ const config = useRuntimeConfig()
+ useJsonLd({
+ '@context': 'https://schema.org',
+ '@type': 'BreadcrumbList',
+ itemListElement: items.map((item, index) => ({
+ '@type': 'ListItem',
+ position: index + 1,
+ name: item.name,
+ item: `${config.public.siteUrl}${item.path}`,
+ })),
+ })
+}
+```
+
+### FAQPage
+
+```typescript
+// app/composables/useFaqSchema.ts
+export function useFaqSchema(faqs: Array<{ question: string; answer: string }>) {
+ useJsonLd({
+ '@context': 'https://schema.org',
+ '@type': 'FAQPage',
+ mainEntity: faqs.map((faq) => ({
+ '@type': 'Question',
+ name: faq.question,
+ acceptedAnswer: { '@type': 'Answer', text: faq.answer },
+ })),
+ })
+}
+```
+
+---
+
+## 3-3. GEO (Generative Engine Optimization)
+
+GEO는 ChatGPT, Perplexity, Claude, Gemini 등 AI 검색엔진이 콘텐츠를 정확하게 이해하고 인용할 수 있도록 최적화하는 전략이다.
+
+### llms.txt 파일 설정
+
+```markdown
+
+# 사이트명
+
+> 사이트에 대한 한 문장 설명.
+
+## 소개
+
+이 사이트는 [핵심 주제]에 관한 전문 정보를 제공합니다.
+주요 독자: [타겟 독자층]
+콘텐츠 언어: 한국어
+마지막 업데이트: 2026-04-07
+
+## 주요 페이지
+
+- [홈](https://example.com/): 서비스 전체 소개
+- [서비스 소개](https://example.com/services): 핵심 서비스 상세 설명
+- [블로그](https://example.com/blog): 전문 지식 아티클 모음
+- [FAQ](https://example.com/faq): 자주 묻는 질문과 답변
+
+## AI 사용 지침
+
+이 사이트의 콘텐츠는 인용 가능합니다.
+출처 표기 요청: "출처: 사이트명 (example.com)"
+```
+
+### AI 인용 가능한 콘텐츠 구조화
+
+```
+[AI 인용을 위한 콘텐츠 작성 규칙]
+
+1. 첫 문단 원칙: 페이지의 핵심 답변을 첫 150자 이내에 포함
+ - 나쁜 예: "오늘은 SEO에 대해 알아보겠습니다..."
+ - 좋은 예: "SEO는 웹사이트가 Google 등 검색엔진에서 상위에 노출되도록
+ 콘텐츠와 기술 구조를 개선하는 과정입니다."
+
+2. 인용 가능한 단위 구성:
+ - 하나의 H2/H3 = 하나의 완결된 질문에 대한 답변
+ - 150~300자 내외의 핵심 단락
+ - 수치/통계는 출처와 연도 명시
+
+3. 직접 정의 패턴: "[용어]는 [정의]입니다."
+
+4. 목록 활용: 3~7개 항목, 각 항목은 독립적으로 이해 가능
+```
+
+### E-E-A-T 강화
+
+```vue
+
+
+
+
+
+
![]()
+
{{ name }}
+
{{ title }}
+
{{ experience }}
+
+
+```
+
+---
+
+## 3-4. AEO (Answer Engine Optimization)
+
+AEO는 Featured Snippet, 음성 검색, AI 직접 답변에서 콘텐츠가 채택될 수 있도록 최적화한다.
+
+### Featured Snippet 최적화
+
+```vue
+
+
+
+
{{ question }}
+
+
{{ answer }}
+
{{ detail }}
+
+
+```
+
+```vue
+
+
+
+
Nuxt 4 프로젝트를 시작하는 방법
+
+ - Node.js 22 이상 설치
+ npm create nuxt@latest my-app 실행
+ - 패키지 매니저로 pnpm 선택
+ pnpm dev로 개발 서버 시작
+
+
+
+```
+
+### FAQ 마크업
+
+```vue
+
+
+
+ 자주 묻는 질문
+
+ {{ category.name }}
+
+
+ {{ faq.question }}
+
+
+
+
+
+```
+
+### 음성 검색 최적화
+
+```typescript
+// speakable 스키마 (Google Assistant, Alexa 등)
+export function useVoiceSearchSeo(cssSelectors: string[]) {
+ useJsonLd({
+ '@context': 'https://schema.org',
+ '@type': 'WebPage',
+ speakable: {
+ '@type': 'SpeakableSpecification',
+ cssSelector: cssSelectors, // 예: ['.core-answer', 'h1']
+ },
+ url: useRequestURL().href,
+ })
+}
+```
+
+```
+[음성 검색 콘텐츠 작성 규칙]
+- 헤딩에 질문 형태 사용: "Core Web Vitals란 무엇인가요?"
+- 첫 문장에 핵심 답변 완결 (약 75단어 이내)
+- "...에 대해 알아보겠습니다" 금지 → "[주제]는 [정의]입니다" 형식 선호
+```
+
+---
+
+## 3-5. Core Web Vitals 최적화
+
+### LCP (Largest Contentful Paint) — 목표: 2.5초 이하
+
+```vue
+
+
+
+
+
+
+```
+
+**LCP 체크리스트:**
+- 서버 응답 시간(TTFB) 800ms 이하
+- 히어로 이미지 WebP/AVIF 변환
+- `fetchpriority="high"` + `loading="eager"` 적용
+- 폰트 `font-display: swap` + preload 설정
+
+### CLS (Cumulative Layout Shift) — 목표: 0.1 이하
+
+```vue
+
+
+```
+
+```css
+/* 동적 콘텐츠 영역 크기 사전 예약 */
+.ad-slot { min-height: 250px; width: 100%; }
+.dynamic-content { min-height: 200px; }
+
+/* 웹폰트 CLS 방지 */
+@font-face {
+ font-family: 'Noto Sans KR Fallback';
+ src: local('Apple SD Gothic Neo');
+ size-adjust: 96%;
+}
+```
+
+### INP (Interaction to Next Paint) — 목표: 200ms 이하
+
+```typescript
+// app/composables/useOptimizedInteraction.ts
+export function useDeferredTask() {
+ function scheduleTask(task: () => void) {
+ if ('scheduler' in window) {
+ (window as unknown as { scheduler: { postTask: (fn: () => void, opts: object) => void } })
+ .scheduler.postTask(task, { priority: 'background' })
+ return
+ }
+ setTimeout(task, 0)
+ }
+
+ return { scheduleTask }
+}
+```
+
+---
+
+## 3-6. Nuxt 4 특화 SEO
+
+### 렌더링 모드 선택 기준
+
+```typescript
+// nuxt.config.ts
+export default defineNuxtConfig({
+ routeRules: {
+ '/': { isr: 3600 }, // ISR: 1시간 캐시
+ '/about': { prerender: true }, // SSG
+ '/pricing': { prerender: true },
+ '/blog/**': { isr: 1800 }, // ISR: 30분
+ '/products/**': { isr: 3600 },
+ '/search': { ssr: true }, // SSR: 실시간
+ '/dashboard/**': { ssr: false }, // CSR: 인증 필요
+ },
+})
+```
+
+| 렌더링 방식 | 적합한 페이지 |
+|-----------|------------|
+| **SSG** | 마케팅, 블로그, 약관 (변경 빈도 낮음) |
+| **ISR** | 제품, 카테고리 (주기적 업데이트) |
+| **SSR** | 검색, 개인화, 실시간 재고/가격 |
+| **CSR** | 대시보드 (noindex 처리) |
+
+### i18n SEO 전략
+
+```typescript
+// nuxt.config.ts
+export default defineNuxtConfig({
+ i18n: {
+ locales: [
+ { code: 'ko', language: 'ko-KR', file: 'ko.json' },
+ { code: 'en', language: 'en-US', file: 'en.json' },
+ ],
+ defaultLocale: 'ko',
+ strategy: 'prefix_except_default',
+ },
+})
+```
+
+```vue
+
+```
+
+---
+
+## 3-7. 콘텐츠 최적화 체크리스트
+
+### SEO 기본 요소
+- [ ] 타이틀: 30~60자, 핵심 키워드 앞쪽, 각 페이지 고유
+- [ ] 메타 디스크립션: 120~160자, CTA 포함, 각 페이지 고유
+- [ ] H1: 페이지당 1개, 핵심 키워드 포함
+- [ ] 헤딩 구조: H1 → H2 → H3 논리적 계층 (건너뜀 금지)
+- [ ] 이미지: alt 속성, WebP/AVIF, width/height 명시
+- [ ] 내부 링크: 관련 페이지 3~5개, 설명적 앵커 텍스트
+- [ ] 캐노니컬: 모든 페이지 자기 참조
+- [ ] 구조화 데이터: Rich Results Test 검증
+
+### GEO/AEO 최적화
+- [ ] 첫 150자 내 핵심 답변 완결
+- [ ] 명확한 정의 문장 포함 ("[용어]는 [정의]입니다")
+- [ ] 수치/통계 출처 표기
+- [ ] 저자 정보 및 E-E-A-T 신호 포함
+- [ ] FAQ 섹션 + FAQPage 스키마
+- [ ] llms.txt 최신 내용 반영
+- [ ] AI 크롤러 허용 robots.txt 확인
+
+### Core Web Vitals
+- [ ] LCP 이미지: `fetchpriority="high"` + preload
+- [ ] 모든 이미지: `width`/`height` 명시
+- [ ] 동적 콘텐츠 영역 최소 높이 예약
+- [ ] 웹폰트 `font-display: swap`
+- [ ] PageSpeed Insights 모바일 90점 이상
+
+---
+
+## 참고 자료
+
+- [Google Search Central](https://developers.google.com/search/docs)
+- [Schema.org](https://schema.org)
+- [llmstxt.org](https://llmstxt.org) — llms.txt 공식 명세
+- [web.dev Core Web Vitals](https://web.dev/explore/learn-core-web-vitals)
+- [Nuxt SEO 모듈](https://nuxtseo.com)
+- [Google Rich Results Test](https://search.google.com/test/rich-results)
+- [WCAG 2.1](https://www.w3.org/TR/WCAG21/)
+- [WAI-ARIA 1.2](https://www.w3.org/TR/wai-aria-1.2/)
diff --git a/docs/rules/email-html-table.md b/docs/rules/email-html-table.md
new file mode 100644
index 0000000..44beb77
--- /dev/null
+++ b/docs/rules/email-html-table.md
@@ -0,0 +1,747 @@
+# 이메일 발송용 HTML Table 코딩 Rules
+
+> Gmail, Naver Mail, Outlook 등 주요 이메일 클라이언트 호환 기준
+> 최종 업데이트: 2026-04-07
+
+---
+
+## 왜 이메일 HTML은 특별한가?
+
+이메일 클라이언트는 웹 브라우저와 다르게 동작한다.
+
+| 클라이언트 | 렌더링 엔진 | 주요 제한 |
+|-----------|------------|---------|
+| Gmail (웹) | WebKit 기반 | `` 스타일 일부 제거, `
+
+
+
+
+ 미리보기 텍스트가 여기에 표시됩니다.
+
+
+
+
+
+