General

Guía de Creación de Artículos Blog — MUST HAVE

**Versión:** 1.0


name: Guía de Creación de Artículos Blog Postea.la
description: Reglas y checklist para crear artículos SEO sin canibalizmo
type: reference

Guía de Creación de Artículos Blog — MUST HAVE

Versión: 1.0
Fecha: Octubre 2026
Objetivo: Garantizar consistencia, calidad SEO y cero canibalizmo en todos los artículos del blog


1. SEO & ESTRUCTURA

  • ✅ Title: 50-70 caracteres, keyword principal al inicio
  • ✅ Meta description: 120-160 caracteres, CTA implícito
  • ✅ H1: Único por artículo, contiene keyword principal
  • ✅ H2: 4-6 máximo, cada uno enfocado en subtema distinto
  • ✅ H3: Bajo cada H2, detalles específicos
  • ✅ Estructura de headings: MAX 3 niveles (H1 → H2 → H3), NO H4/H5
  • ✅ Canonical tag: Presente en head
  • ✅ Breadcrumbs: Schema JSON-LD (Inicio > Blog > Artículo)

2. CONTENIDO

  • ✅ Largo: 2,400-2,800 palabras por artículo
  • ✅ Párrafos: 2-3 oraciones máximo (legibilidad)
  • ✅ Keyword density: 1-2% (natural, sin stuffing)
  • ✅ Listas con bullets: Máximo 5 items por lista
  • ✅ Tablas: Usar solo si aplica comparaciones (filas/columnas claramente definidas)
  • ✅ Ejemplos reales: Mínimo 1 caso de uso LATAM específico
  • ✅ Call-to-action: 1-2 naturales al final (no invasivos)
  • ✅ Párrafo intro: Resume el artículo en 2-3 oraciones
  • ✅ Enlaces internos: Máximo 2-3 links a otros artículos (anchor text natural)

3. FAQS (GOOGLE FEATURED SNIPPETS)

  • ✅ Cantidad: Mínimo 6, máximo 8 FAQs
  • ✅ Pregunta (Q): Redactada como busca la gente (natural, conversacional)
  • ✅ Respuesta (A): Corta y directa (1-2 párrafos máximo)
  • ✅ Schema FAQPage: Presente en JSON-LD
  • ✅ Contenido único: FAQs NO responden cosas de otros artículos (evita canibalizmo)
  • ✅ Formato: Cada FAQ resuelve una duda específica del usuario

4. SCHEMA JSON-LD

Todos los artículos deben incluir 3 scripts:

4a. Article Schema

{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "[título del artículo]",
  "datePublished": "[YYYY-MM-DD]",
  "dateModified": "[YYYY-MM-DD]",
  "author": {"@type": "Organization", "name": "Postea.la"},
  "description": "[meta description]",
  "wordCount": [número],
  "articleBody": "[resumen del contenido]"
}

4b. BreadcrumbList Schema

{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {"@type": "ListItem", "position": 1, "name": "Inicio", "item": "https://postea.la"},
    {"@type": "ListItem", "position": 2, "name": "Blog", "item": "https://postea.la/blog"},
    {"@type": "ListItem", "position": 3, "name": "[Título artículo]", "item": "[canonical URL]"}
  ]
}

4c. FAQPage Schema

{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "[pregunta 1]",
      "acceptedAnswer": {"@type": "Answer", "text": "[respuesta 1]"}
    },
    ...
  ]
}

5. IMÁGENES (OG TAGS)

  • ✅ OG Image: 1200x630px (ratio 1.9:1)
  • ✅ Selección: Usar imagen existente de frontend/src/assets/images/ (NO crear nuevas)
  • ✅ Relevancia: Imagen debe representar el tema del artículo
  • ✅ Formato: JPG o WEBP preferente
  • ✅ Alt text: Descriptivo, contiene keyword si aplica
  • ✅ Registro: Mapear slug → URL en ARTICLE_OG_IMAGES dict

6. CANIBALIZMO — CRITICAL

ANTES de crear un artículo, verificar:

  1. ✅ Keywords NO compitan con artículos existentes

    • Revisar blog_canibalismo_keywords.md
    • Keyword principal debe ser ÚNICA
  2. ✅ Intención de búsqueda DISTINTA

    • Ej: "fotos boda invitados" (RECOPILAR) ≠ "álbum digital boda" (COMPARATIVA fotógrafo)
    • Ej: "comuniones fotos" (EVENTO) ≠ "fotos privadas evento" (PRIVACIDAD)
  3. ✅ Si menciona otro artículo: enlazar con anchor text natural

  4. ✅ Feature único: cada artículo resuelve UN problema específico

    • NO mezclar moderación + privacidad + seguridad en un solo artículo

7. CÓDIGO — ESTRUCTURA FUNCIÓN

def article_[slug_corto]():
    slug = "[slug-completo]"
    canonical = f"{BASE_URL}/{slug}"
    title = "[Título 50-70 chars]"
    meta_desc = "[Meta description 120-160 chars]"

    # Schema Article
    schema = {
        "@context": "https://schema.org",
        "@type": "Article",
        "headline": title,
        "datePublished": "2026-10-DD",
        "dateModified": "2026-10-DD",
        "author": {"@type": "Organization", "name": "Postea.la"},
        "description": meta_desc,
        "wordCount": XXXX,
        "articleBody": "[resumen]"
    }

    # Schema Breadcrumb
    breadcrumb = {
        "@context": "https://schema.org",
        "@type": "BreadcrumbList",
        "itemListElement": [
            {"@type": "ListItem", "position": 1, "name": "Postea.la", "item": BASE_URL},
            {"@type": "ListItem", "position": 2, "name": "Blog", "item": f"{BASE_URL}/blog"},
            {"@type": "ListItem", "position": 3, "name": title, "item": canonical}
        ]
    }

    # FAQs (6-8)
    faqs = [
        ("¿Pregunta 1?", "Respuesta 1..."),
        ("¿Pregunta 2?", "Respuesta 2..."),
        # ... máximo 8
    ]

    # Hero section
    hero = _hero(
        tags=["Tag1", "Tag2", "Tag3"],
        h1_line1="Primera línea del H1:",
        h1_line2="Segunda línea del H1",
        subtitle="Subtítulo/descripción corta",
        stats=[("stat1", "label1"), ("stat2", "label2")]
    )

    # Body (HTML)
    body = hero + f"""
    <section style="max-width:900px;margin:60px auto;padding:0 20px;">
      <h2>Título H2</h2>
      <p>Párrafo intro...</p>
      
      <h3>Subtítulo H3</h3>
      <p>Contenido...</p>
      
      <h2>Otro H2</h2>
      <p>Más contenido...</p>
      
      <h2>Preguntas frecuentes</h2>
      <div style="margin-top:8px;">
        {{''.join(f'<div class="faq-item"><p class="faq-q">❓ {{q}}</p><p class="faq-a">{{a}}</p></div>' for q, a in faqs)}}
      </div>
    </section>
    """ + _related_articles(slug)

    # Schema FAQPage
    faq_schema = {
        "@context": "https://schema.org",
        "@type": "FAQPage",
        "mainEntity": [{"@type": "Question", "name": q, "acceptedAnswer": {"@type": "Answer", "text": a}} for q, a in faqs]
    }

    return html_page(title, meta_desc, canonical,
                     _json.dumps(schema, ensure_ascii=False),
                     _json.dumps(breadcrumb, ensure_ascii=False),
                     body, _json.dumps(faq_schema, ensure_ascii=False),
                     og_image=ARTICLE_OG_IMAGES.get(slug))

8. FORMATO & ESTILOS

  • ✅ CSS: Mismo que artículos existentes (variables de paleta)
  • ✅ Paleta de colores:
    • Dorado: #c9a96e
    • Crema: #f9f7f4
    • Gris oscuro: #333 / #555
  • ✅ Tipografía:
    • Títulos (H1/H2): Playfair Display serif
    • Body: Inter sans-serif
  • ✅ Estilos: Inline styles, NO clases CSS, NO ::ng-deep
  • ✅ Bootstrap: NO usar clases Bootstrap
  • ✅ Consistencia: Márgenes, paddings, tamaños de fuente idénticos a artículos existentes

9. GIT WORKFLOW

Commit 1: Crear funciones

git add frontend/scripts/blog-generator.py
git commit -m "feat: create 3 article functions (slug1, slug2, slug3)"

Commit 2: Registrar imágenes OG

git add frontend/scripts/blog-generator.py
git commit -m "feat: add OG images mapping for 3 articles"

Commit 3: Registrar en ARTICLES array

git add frontend/scripts/blog-generator.py
git commit -m "feat: register 3 articles in ARTICLES array (Lote X)"

Generate & Deploy

python3 frontend/scripts/blog-generator.py frontend/dist/postea-la/browser
./deploy-frontend.sh

10. VALIDACIÓN FINAL — CHECKLIST

  • ✅ Compilación sin errores (python3 blog-generator.py exitoso)
  • ✅ Archivos .html generados (tamaño 25-30KB cada uno)
  • ✅ Schema JSON válido (sin syntax errors, se puede parsear)
  • ✅ Sitemap actualizado con URLs nuevas
  • ✅ URLs accesibles en producción (https://postea.la/[slug])
  • ✅ Title visible en browser tab
  • ✅ H1 visible en pantalla
  • ✅ FAQs renderizadas correctamente
  • ✅ OG Image se carga sin errores 404
  • ✅ Canonical tag correcto
  • ✅ NO hay canibalizmo con artículos existentes

CHECKLIST RÁPIDO ANTES DE CREAR

[ ] ¿Keyword principal es ÚNICA? (revisar blog_canibalismo_keywords.md)
[ ] ¿Intención de búsqueda es DISTINTA a otros artículos?
[ ] ¿Title 50-70 chars? ¿Meta desc 120-160 chars?
[ ] ¿H1 único? ¿H2 entre 4-6?
[ ] ¿6-8 FAQs naturales?
[ ] ¿2,400-2,800 palabras?
[ ] ¿Mínimo 1 caso LATAM real?
[ ] ¿OG Image 1200x630px existe?
[ ] ¿Funciones → OG_IMAGES → ARTICLES (3 commits)?
[ ] ¿Deploy exitoso?
[ ] ¿URL accesible en producción?

Última actualización: Octubre 2026
Responsable: César Estrada / Melissa Vásquez