Eleventy에서 GEO 자동화: JSON‑LD, BLUF 및 표를 수동 마크업 없이

발행: (2026년 6월 10일 PM 06:01 GMT+9)
6 분 소요
원문: Dev.to

BLUF - GEO/SEO 2026 시리즈 파트 3

문제: 모든 포스트마다 JSON‑LD, BLUF 블록, HTML 테이블을 수동으로 작성하는 것은 시간도 많이 들고 오류가 발생하기 쉽습니다.

해결책: Eleventy의 Nunjucks include와 shortcode를 활용합니다. 템플릿을 한 번만 설정하면, 새로운 포스트마다 프론트매터만으로 전체 GEO 인프라가 자동으로 적용됩니다.

자동화 대상: Article 스키마, FAQPage 스키마, HowTo 스키마, BLUF 블록, data-label이 포함된 HTML 테이블, 그리고 robots.txt.

설정 시간: 한 번에 1.5~2시간 → 이후 포스트당 0분.

파트 1: GEO 기술 아키텍처: robots.txt, JSON‑LD, 시맨틱 HTML

파트 2: LLM용 콘텐츠 엔지니어링: 정보 밀도와 BLUF 구조


왜 수동 마이크로 마크업은 확장되지 않는가

파트 1에서는 각 스키마 타입마다 JSON‑LD를 수동으로 작성했습니다. 파트 2에서는 각 포스트에 BLUF 블록과 HTML 테이블을 개별적으로 추가했습니다. 5개의 포스트라면 괜찮지만, 50개가 되면 기술 부채가 쌓여 드리프트가 발생합니다: 어떤 포스트는 FAQPage 스키마가 빠지고, 어떤 포스트는 오래된 저자 URL을 가지고, 또 어떤 포스트는 BLUF가 없습니다.

올바른 해결책: 템플릿 하나만 수정하면 모든 포스트에 동시에 적용됩니다.


Step 1. 기본 설정: _data/metadata.json

모든 Nunjucks 템플릿은 여기서 전역 사이트 데이터를 가져옵니다. 파일이 이미 존재한다면 아래 필드가 포함돼 있는지 확인하세요.

{
  "title": "Your Blog Title",
  "description": "A technical blog about development and AI tools",
  "url": "https://your-domain.com",
  "language": "en",
  "author": {
    "name": "Your Name",
    "url": "https://your-domain.com/about/",
    "email": "contact@your-domain.com"
  },
  "logo": "https://your-domain.com/images/logo.png"
}

전체 화면 모드 진입
전체 화면 모드 종료


Step 2. Article Schema – 모든 포스트에 자동 적용

_includes/schema-article.njk 파일을 생성합니다. 현재 페이지의 frontmatter에서 title, description, date, thumbnail을 읽어 유효한 JSON‑LD를 생성합니다.

{% raw %}{%- if title and page.url -%}

{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": {{ title | dump | safe }},
  "description": {{ description | dump | safe }},
  "datePublished": "{{ date | dateToISO }}",
  "dateModified": "{{ date | dateToISO }}",
  "author": {
    "@type": "Person",
    "name": {{ metadata.author.name | dump | safe }},
    "url": {{ metadata.author.url | dump | safe }}
  },
  "publisher": {
    "@type": "Organization",
    "name": {{ metadata.title | dump | safe }},
    "url": {{ metadata.url | dump | safe }},
    "logo": {
      "@type": "ImageObject",
      "url": {{ metadata.logo | dump | safe }}
    }
  },
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": {{ (metadata.url + page.url) | dump | safe }}
  }
  {%- if thumbnail -%}
  ,
  "image": {{ (metadata.url + "/" + thumbnail.image) | dump | safe }}
  {%- endif -%}
}

{%- endif -%}{% endraw %}

전체 화면 모드 진입
전체 화면 모드 종료

.eleventy.jsdateToISO 필터 추가

Eleventy에는 ISO 필터가 기본으로 없습니다. 아래 코드를 .eleventy.js에 추가하세요.

module.exports = function(eleventyConfig) {

  // Filter: Date → ISO 8601 string for JSON-LD
  eleventyConfig.addFilter("dateToISO", (date) => {
    if (!date) return "";
    return new Date(date).toISOString();
  });

  // ... other settings
};

전체 화면 모드 진입
전체 화면 모드 종료

기본 레이아웃에 포함시키기

_includes/base.njk 혹은 _includes/layouts/post.njk 파일의 <head> 블록 안에 다음을 넣습니다.

{% raw %}
  
  {{ title }} | {{ metadata.title }}
  

  {# ── GEO Schema Markup ──────────────────────────── #}
  {% include "schema-article.njk" %}
  {% include "schema-faq.njk" %}
  {% include "schema-howto.njk" %}

{% endraw %}

전체 화면 모드 진입
전체 화면 모드 종료

이제 새 포스트를 만들면 별도 작업 없이 Article Schema가 자동으로 삽입됩니다.


Step 3. FAQPage Schema – Frontmatter 배열 활용

아이디어: FAQ 질문·답변을 포스트의 frontmatter에 직접 정의합니다. 템플릿이 스키마를 자동으로 생성하고, 같은 데이터가 HTML FAQ 섹션에도 렌더링됩니다.

Frontmatter 구조

---
title: "Post Title"
faq:
  - q: "What is GEO and how does it differ from SEO?"
    a: "GEO is optimization for citation in AI responses; SEO is for ranking in search results."
  - q: "Which AI bots should be allowed in robots.txt?"
    a: "GPTBot, PerplexityBot, Google-Extended, ClaudeBot, anthropic-ai, FacebookBot."
  - q: "Are GEO and SEO compatible?"
    a: "Yes, most GEO techniques reinforce classical SEO."
---

전체 화면 모드 진입
전체 화면 모드 종료

템플릿 _includes/schema-faq.njk

{% raw %}{%- if faq and faq.length -%}

{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {%- for item in faq -%}
    {
      "@type": "Question",
      "name": {{ item.q | dump | safe }},
      "acceptedAnswer": {
        "@type": "Answer",
        "text": {{ item.a | dump | safe }}
      }
    }{% if not loop.last %},{% endif %}
    {%- endfor -%}
  ]
}

{%- endif -
0 조회
Back to Blog

관련 글

더 보기 »

Eidentic 소개

Today we're releasing Eidentic, an open-source TypeScript SDK for building AI agents with self-improving memory and the production fundamentals built in — not b...

Typescript의 타입

Introdução Tipos são uma forma de definir a “forma” ou o contrato dos dados que estamos usando no código. Pensando em Javascript puro, ele é dinâmico: você pode...