Datos estructurados JSON-LD para resultados enriquecidos en Google
13 min read

JSON-LD Structured Data en Astro

#SEO #JSON-LD #Schema.org

Has construido un sitio web Astro bien estructurado. El contenido es cuidado, las páginas cargan rápido, el diseño cumple con los estándares de accesibilidad. Pero cuando Google rastrea tus páginas, solo ve texto y elementos HTML. No entiende automáticamente que tu sección de FAQ contiene preguntas y respuestas, que tu página de servicios describe ofertas, o que tu negocio opera en una ubicación específica. Aquí es exactamente dónde entran los datos estructurados.

JSON-LD (JavaScript Object Notation for Linked Data) es el formato preferido de Google para decirle a las máquinas lo que el contenido de una página significa — no solo lo que muestra. Una etiqueta <script> invisible en el head del HTML entrega un conjunto de datos estructurados a los motores de búsqueda que conduce directamente a Rich Results en los resultados de búsqueda: respuestas FAQ desplegables, calificaciones con estrellas, rutas de navegación y tarjetas de negocio con dirección y horarios.

Google utiliza datos estructurados para comprender el contenido de una página y mostrar ese contenido en un formato visualmente más atractivo en los resultados de búsqueda — conocido como Rich Results.

Google Search Central Documentación Oficial

Por qué los datos estructurados son decisivos

4
Tipos de Schema implementados
Este Portfolio
30%
Más clics via Rich Results
Google Search Central
0
Impacto en rendimiento
Sin bloqueo de renderizado

Los Rich Results hacen que tu página destaque visualmente entre la masa de resultados de búsqueda. Mientras que los resultados normales solo muestran título, URL y meta descripción, las páginas con datos estructurados pueden mostrar secciones FAQ desplegables, calificaciones con estrellas, navegación breadcrumb, tablas de precios y detalles del negocio directamente en la SERP. Eso significa más espacio en pantalla, más atención y tasas de clics significativamente más altas.

Los datos estructurados no son un factor de ranking en el sentido estricto — pero ayudan a Google a comprender mejor el contexto de tu contenido. E indirectamente, las tasas de clics más altas, las tasas de rebote más bajas y una mejor interacción del usuario sí mejoran tu posicionamiento.

Qué es JSON-LD?

JSON-LD significa JavaScript Object Notation for Linked Data. Es un formato estandarizado que incrusta información semántica dentro de una etiqueta <script> en el documento HTML. Los motores de búsqueda leen esta etiqueta; los usuarios nunca la ven.

<!-- Invisible para usuarios, legible por maquinas para Google -->
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "WebPage",
  "name": "Mi Pagina",
  "description": "Una descripcion de la pagina"
}
</script>

El punto crucial: JSON-LD no se renderiza. Se encuentra como un script invisible en el <head> o al final del <body>. No bloquea el renderizado ni ralentiza la carga de la página. Es puro marcado de metadatos — Google lo lee, el navegador lo ignora.

Los cuatro tipos de Schema en detalle

Este portfolio implementa cuatro tipos de Schema.org que juntos crean una imagen semántica completa del sitio web para los motores de búsqueda.

Esquema FAQPage JSON-LD con vista previa de Rich Result en Google
FAQPage

Captura pares pregunta-respuesta de forma semántica para que los buscadores y sistemas de IA (Google AI Overviews, ChatGPT, Perplexity) puedan usar tus respuestas. Nota importante: desde agosto de 2023, Google solo muestra rich results de FAQ para sitios autoritativos del ámbito gubernamental o sanitario. Los sitios generales siguen beneficiándose de la claridad semántica para AI-grounding y Knowledge Graph, pero ya no obtienen los desplegables expandibles en la SERP.

Esquema Service JSON-LD con vista previa de Rich Result
Service

Le dice a Google qué servicios ofreces, incluyendo nombre, descripción e información del proveedor. Especialmente relevante para freelancers y agencias cuyas páginas de servicios pueden mostrarse con detalles adicionales en los resultados de búsqueda. Combinado con LocalBusiness, crea una imagen completa de tu oferta.

Esquema BreadcrumbList JSON-LD con navegación breadcrumb en SERP
BreadcrumbList

Crea una ruta de navegación en los resultados de búsqueda (Inicio > Servicios > Desarrollo Web). Google reemplaza la URL cruda con una estructura de ruta legible. Esto mejora la orientación del usuario directamente en la SERP y señala a Google una jerarquía clara del sitio web. Se genera en cada página a través del componente Breadcrumbs.

Esquema LocalBusiness JSON-LD con vista previa de Knowledge Graph
LocalBusiness

Contiene nombre del negocio, dirección, coordenadas geográficas y datos de contacto. Esencial para SEO local -- Google usa estos datos para el Knowledge Graph, incrustaciones de Google Maps y búsqueda local. Se genera a nivel de todo el sitio a través del componente SEO, obteniendo datos directamente de la configuración central SITE.

Implementación del Schema FAQPage

El schema FAQPage captura pares pregunta-respuesta de forma semántica. La implementación en Astro aprovecha la estructura de datos FAQ existente y genera JSON-LD automáticamente.

---
/* Generacion de JSON-LD FAQPage desde el array de datos FAQ */
interface FaqItem {
  question: string;
  answer: string;
}

interface Props {
  items: FaqItem[];
}

const { items } = Astro.props;

/* Datos estructurados Schema.org FAQPage */
const faqSchema = {
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": items.map((item) => ({
    "@type": "Question",
    "name": item.question,
    "acceptedAnswer": {
      "@type": "Answer",
      "text": item.answer,
    },
  })),
};
---

<!-- Accordion visible para usuarios -->
<section id="faq" class="faq">
  {items.map((item) => (
    <details class="faq__item">
      <summary class="faq__question">{item.question}</summary>
      <p class="faq__answer">{item.answer}</p>
    </details>
  ))}
</section>

<!-- JSON-LD invisible para motores de busqueda -->
<script
  type="application/ld+json"
  set:html={JSON.stringify(faqSchema)}
/>
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Que tecnologias utilizan?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Trabajamos con Astro, React, TypeScript y tecnicas CSS modernas. Todos los proyectos siguen la metodologia Atomic Design."
      }
    },
    {
      "@type": "Question",
      "name": "Cuanto tiempo tarda un proyecto tipico?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Dependiendo del alcance, entre 2 y 8 semanas. Un relanzamiento de portfolio tipicamente toma 3-4 semanas."
      }
    },
    {
      "@type": "Question",
      "name": "Ofrecen mantenimiento?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Si, ofrecemos mantenimiento continuo, actualizaciones de seguridad y monitoreo de rendimiento como servicio mensual."
      }
    }
  ]
}
Resultados de Google con Rich Result FAQPage:

+---------------------------------------------------+
|  Arnold Wender — Desarrollador Web & Creator       |
|  https://arnoldwender.com                          |
|  Diseno web moderno con Astro, React y...          |
|                                                     |
|  > Que tecnologias utilizan?                        |
|  > Cuanto tiempo tarda un proyecto tipico?          |
|  > Ofrecen mantenimiento?                           |
+---------------------------------------------------+

Cada pregunta es clicable y expande la respuesta
directamente en los resultados de busqueda — sin
necesidad de visitar la pagina. Esto triplica el
area visible de tu resultado de busqueda.

Schema Service para la página de servicios

El schema Service comunica a Google qué servicios ofreces. Cada servicio se captura individualmente con nombre, descripción y referencia al proveedor.

---
/* Schema Service para la pagina de servicios */
import { SITE } from '../../lib/constants';

const services = [
  {
    name: 'Desarrollo Web',
    description: 'Sitios web personalizados con Astro, React y CSS moderno.',
  },
  {
    name: 'Diseno UI/UX',
    description: 'Diseno centrado en el usuario con metodologia Atomic Design.',
  },
  {
    name: 'Optimizacion SEO',
    description: 'SEO tecnico, datos estructurados y rendimiento.',
  },
];

/* Cada servicio se convierte en su propio objeto schema */
const serviceSchemas = services.map((service) => ({
  "@context": "https://schema.org",
  "@type": "Service",
  "name": service.name,
  "description": service.description,
  "provider": {
    "@type": "Person",
    "name": SITE.author,
    "url": SITE.url,
  },
}));
---

{serviceSchemas.map((schema) => (
  <script
    type="application/ld+json"
    set:html={JSON.stringify(schema)}
  />
))}
[
  {
    "@context": "https://schema.org",
    "@type": "Service",
    "name": "Desarrollo Web",
    "description": "Sitios web personalizados con Astro, React y CSS moderno. Performantes, accesibles y optimizados para SEO.",
    "provider": {
      "@type": "Person",
      "name": "Arnold Wender",
      "url": "https://arnoldwender.com"
    }
  },
  {
    "@context": "https://schema.org",
    "@type": "Service",
    "name": "Diseno UI/UX",
    "description": "Diseno centrado en el usuario con metodologia Atomic Design. Wireframes, prototipos y sistemas de diseno.",
    "provider": {
      "@type": "Person",
      "name": "Arnold Wender",
      "url": "https://arnoldwender.com"
    }
  },
  {
    "@context": "https://schema.org",
    "@type": "Service",
    "name": "Optimizacion SEO",
    "description": "SEO tecnico, datos estructurados y optimizacion de rendimiento Core Web Vitals.",
    "provider": {
      "@type": "Person",
      "name": "Arnold Wender",
      "url": "https://arnoldwender.com"
    }
  }
]

BreadcrumbList es el schema que se genera en cada página individual. Describe la ruta de navegación desde la página de inicio hasta la página actual. En Astro, esta información fluye a través de una elegante cadena de props desde la página, pasando por el layout, hasta el componente Breadcrumbs.

Flujo de datos de Breadcrumbs

  1. Definir Breadcrumbs en la página

    Cada página Astro define sus breadcrumbs como un array de objetos con label y un href opcional. El último elemento no tiene enlace -- representa la página actual.

  2. Pasar al BaseLayout

    La página pasa el array de breadcrumbs como prop al BaseLayout. BlogLayout y PortfolioLayout reenvian automáticamente esta prop al BaseLayout.

  3. Componente Breadcrumbs renderiza HTML y JSON-LD

    El componente molécula Breadcrumbs renderiza tanto la navegación visible como lista HTML como el schema BreadcrumbList invisible como script JSON-LD.

  4. Google muestra la ruta en la SERP

    En lugar de la URL cruda (arnoldwender.com/blog/json-ld), Google muestra la ruta legible: Inicio > Blog > Datos Estructurados JSON-LD. Esto mejora la tasa de clics y la orientación del usuario.

---
/* src/pages/servicios.astro — Breadcrumbs para la pagina de servicios */
import BaseLayout from '../layouts/BaseLayout.astro';

const breadcrumbs = [
  { label: 'Inicio', href: '/' },
  { label: 'Servicios' },  /* Sin href = pagina actual */
];
---

<BaseLayout
  seo={{ title: 'Servicios', description: '...' }}
  breadcrumbs={breadcrumbs}
>
  <section id="servicios">
    <!-- Contenido de la pagina -->
  </section>
</BaseLayout>
---
/* src/components/molecules/Breadcrumbs.astro */
import type { BreadcrumbItem } from '../../types';

interface Props {
  items: BreadcrumbItem[];
}

const { items } = Astro.props;

/* Generar schema BreadcrumbList */
const breadcrumbSchema = {
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": items.map((item, index) => ({
    "@type": "ListItem",
    "position": index + 1,
    "name": item.label,
    ...(item.href && { "item": `${Astro.site}${item.href}` }),
  })),
};
---

<!-- Navegacion breadcrumb visible -->
<nav aria-label="Breadcrumb" class="breadcrumbs">
  <ol class="breadcrumbs__list">
    {items.map((item, i) => (
      <li class="breadcrumbs__item">
        {item.href
          ? <a href={item.href}>{item.label}</a>
          : <span aria-current="page">{item.label}</span>
        }
      </li>
    ))}
  </ol>
</nav>

<!-- Datos estructurados para Google -->
<script
  type="application/ld+json"
  set:html={JSON.stringify(breadcrumbSchema)}
/>
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Inicio",
      "item": "https://arnoldwender.com/"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Blog",
      "item": "https://arnoldwender.com/blog"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "Datos Estructurados JSON-LD"
    }
  ]
}

LocalBusiness para segmentación geográfica

El schema LocalBusiness es esencial para cualquier negocio que atiende clientes en una región específica. Contiene el nombre de la empresa, dirección, coordenadas geográficas y datos de contacto. Google utiliza esta información para el Knowledge Graph, resultados de búsqueda local e incrustaciones de Google Maps.

En este portfolio, los datos geográficos se mantienen centralmente en la configuración SITE y se transfieren automáticamente al schema LocalBusiness.

/* src/lib/constants.ts — Configuracion central */
export const SITE: SiteConfig = {
  name: 'Arnold Wender',
  description: 'Desarrollador Web & Creador Digital',
  url: 'https://arnoldwender.com',
  locale: 'es',
  author: 'Arnold Wender',
  geo: {
    latitude: 51.4818,
    longitude: 11.9689,
    placeName: 'Halle (Saale), Germany',
    region: 'ST',
  },
};
{
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "name": "Arnold Wender — Desarrollo Web",
  "description": "Desarrollador Web & Creador Digital",
  "url": "https://arnoldwender.com",
  "telephone": "+49-XXX-XXXXXXX",
  "address": {
    "@type": "PostalAddress",
    "addressLocality": "Halle (Saale)",
    "addressRegion": "ST",
    "addressCountry": "DE"
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": 51.4818,
    "longitude": 11.9689
  },
  "areaServed": {
    "@type": "GeoCircle",
    "geoMidpoint": {
      "@type": "GeoCoordinates",
      "latitude": 51.4818,
      "longitude": 11.9689
    },
    "geoRadius": "50000"
  }
}
---
/* src/components/seo/SEO.astro — Extracto */
import { SITE } from '../../lib/constants';

/* LocalBusiness solo en la pagina de inicio */
const isHomepage = Astro.url.pathname === '/';

const localBusinessSchema = isHomepage && SITE.geo ? {
  "@context": "https://schema.org",
  "@type": "LocalBusiness",
  "name": SITE.name,
  "description": SITE.description,
  "url": SITE.url,
  "address": {
    "@type": "PostalAddress",
    "addressLocality": SITE.geo.placeName,
    "addressRegion": SITE.geo.region,
    "addressCountry": "DE",
  },
  "geo": {
    "@type": "GeoCoordinates",
    "latitude": SITE.geo.latitude,
    "longitude": SITE.geo.longitude,
  },
} : null;
---

{localBusinessSchema && (
  <script
    type="application/ld+json"
    set:html={JSON.stringify(localBusinessSchema)}
  />
)}

Datos estructurados multilingües

En sitios web multilingües, cada versión de idioma debe generar sus propios datos estructurados. Esto significa: la página en alemán entrega JSON-LD en alemán, la página en inglés entrega JSON-LD en inglés, la página en español entrega JSON-LD en español. Los motores de búsqueda asocian los datos estructurados con la versión de idioma respectiva. Si quieres saber cómo implementar un sitio multilingüe con URLs traducidas y etiquetas hreflang, lee nuestra guía sobre i18n sin plugins con mapeo de slugs.

En Astro, las páginas multilingües se gestionan a través de la estructura de carpetas (/de/, /en/, /es/) o mediante Content Collections con un campo locale. Cada versión de idioma de la página renderiza su propio <script type="application/ld+json"> con el contenido traducido. La estructura del schema (@type, @context) permanece idéntica — solo los campos legibles por humanos (name, description, text) se traducen.

La implementación utiliza la información de locale del frontmatter o la URL. Las preguntas FAQ, descripciones de servicios y etiquetas de breadcrumbs provienen de archivos de datos específicos por idioma. El schema se genera en tiempo de build para cada idioma por separado — no hay cambio dinámico de idioma en JSON-LD.

El error más común es mezclar idiomas dentro de un solo bloque JSON-LD. Si la página está en español, todo el texto en el schema también debe estar en español. Un segundo error: olvidar establecer la propiedad inLanguage. Tercer error: datos estructurados idénticos en todas las versiones de idioma — Google reconoce esto como contenido duplicado.

Pruebas y validación

Implementar datos estructurados es solo la mitad del trabajo. Sin pruebas sistematicas, no puedes estar seguro de que Google interpreta correctamente tus schemas. Hay cuatro herramientas que deberias usar en tu flujo de trabajo.

Flujo de validación

  1. Google Rich Results Test

    La herramienta oficial de Google en search.google.com/test/rich-results. Ingresa tu URL o pega código HTML. Te muestra exactamente qué Rich Results puede generar Google a partir de tus datos estructurados -- y reporta errores o advertencias.

  2. Validador Schema.org

    En validator.schema.org puedes validar tu JSON-LD contra la especificación de Schema.org. Esta herramienta es más estricta que el test de Google y también verifica campos que Google mismo ignora. Ideal para conformidad completa.

  3. Inspección con Chrome DevTools

    Abre DevTools (F12), ve a Elements y busca <script type="application/ld+json">. Aquí ves la salida JSON-LD real de tu página. Verifica que los datos son correctos, todos los campos están presentes y ningún error de JavaScript interfiere con la generación.

  4. Google Search Console

    Después del despliegue, monitorea el estado de los datos estructurados a lo largo del tiempo en la sección "Mejoras" > "Rich Results". Google te muestra que páginas son elegibles para Rich Results, cuáles tienen errores y cómo se desarrollan las impresiones.

Evitar errores comunes

La implementación correcta de datos estructurados requiere precision. Pequenos errores pueden hacer que Google ignore completamente tu schema. Aquí están las trampas más comunes y cómo evitarlas.

Aspecto Correcto Recommended Incorrecto
Schema por página Un schema FAQPage con todas las preguntas Multiples schemas FAQPage en la misma página
Campos obligatorios Todos los campos requeridos según Schema.org Omitir campos y esperar que Google lo acepte
Escritura de @type @type: "FAQPage" (exacto) @type: "faqpage" o @type: "FAQ"
Coincidencia de contenido Texto JSON-LD = contenido visible de la página Texto diferente en el schema que en la página
Anidamiento Estructura plana, asignaciones @type limpias Anidamiento excesivo sin jerarquía clara
Multiples schemas Etiquetas <script> separadas para cada tipo Todos los schemas en una sola etiqueta <script>
Idioma inLanguage coincide con el idioma de la página Sin inLanguage o idioma incorrecto

Integración con Sitemap

Los datos estructurados y el sitemap trabajan de la mano. Las páginas con marcado schema rico merecen una mayor prioridad de rastreo porque potencialmente entregan más información para el índice de Google. En la configuración de Astro, esto se implementa a través de un sistema de prioridades escalonado.

Prioridad 1.0 — Inicio

La página de inicio contiene schemas Organization y LocalBusiness. Maxima prioridad de rastreo con frecuencia diaria.

Prioridad 0.9 — Páginas principales

Servicios, Sobre mi, Contacto -- páginas con schemas Service y ContactPage. Frecuencia de rastreo semanal.

Prioridad 0.8 — Artículos del blog

Cada artículo tiene un schema Article con autor, fecha y etiquetas. Frecuencia de rastreo mensual para posts antiguos.

Prioridad 0.7 — Portfolio

Páginas de proyectos con schema CreativeWork. Se actualizan con menos frecuencia pero son importantes para la estructura general.

Prioridad 0.5 — Archivos

Páginas de etiquetas y categorías con schema CollectionPage. Ayudan a Google a entender la taxonomía.

Prioridad 0.3 — Búsqueda

Páginas de búsqueda y paginación. Baja prioridad pero necesarias para indexación completa.

Preguntas frecuentes

Frequently Asked Questions

Conclusión

Los datos estructurados con JSON-LD no son un bonus SEO opcional — son una parte fundamental del desarrollo web moderno. No cuestan rendimiento (como detallamos en nuestra guía de Core Web Vitals), no requieren cambio de framework y pueden integrarse elegantemente en la arquitectura de componentes existente de Astro. Cuatro tipos de schema — FAQPage, Service, BreadcrumbList y LocalBusiness — cubren los casos de uso más importantes para un portfolio o sitio web empresarial.

La clave está en la automatización: los datos estructurados no deben mantenerse manualmente sino alimentarse de las mismas fuentes de datos que el contenido visible. En Astro, esto significa: props y Content Collections fluyen hacia componentes que renderizan tanto el HTML visual como el JSON-LD invisible. Una única fuente de verdad para humanos y máquinas por igual.