¡Últimas entradas para el 30 de mayo!
Andalu-SEO

Cómo agregar datos estructurados en Magento

Inserta datos estructurados en un Magento de una forma automatizada y efectiva con programación.

Cómo agregar datos estructurados en Magento
Autor:
Carlos Sánchez
Fecha de publicación:
2024-01-19

Última revisión:
2026-01-30

Los datos estructurados son una de esas cosas que en Magento 2 vienen implementados de forma muy básica (por no decir pobre). La instalación por defecto con el tema Luma incluye algunos microdatos, pero le faltan campos importantes como availability, offers, shipping o reviews individuales.

Este artículo surge de una pregunta en mi comunidad de Discord, y como es algo que me preguntan bastante, he decidido desarrollarlo en profundidad.

¿Por qué importan los datos estructurados en ecommerce?

Los datos estructurados (o schema markup) son código que ayuda a los buscadores a entender el contenido de tu página. En el caso de productos, le estás diciendo a Google: "esto es un producto, este es su precio, esta es su disponibilidad, estas son sus valoraciones".

¿El resultado? Los famosos rich snippets en los resultados de búsqueda: estrellas de valoración, precios, disponibilidad... Según varios estudios, los rich snippets pueden aumentar el CTR hasta un 150%.

Google prefiere el formato JSON-LD sobre los microdatos (el formato que usa Magento por defecto). Las ventajas de JSON-LD:

La forma correcta: crear un módulo personalizado

En Magento 2, la forma limpia y escalable de añadir datos estructurados es mediante un módulo propio. Esto te permite:

Vamos paso a paso.

1. Estructura del módulo

Primero, creamos la estructura básica del módulo. En app/code/ creamos:

app/code/TuEmpresa/DatosEstructurados/
├── registration.php
├── etc/
│ └── module.xml
├── Block/
│ └── ProductSchema.php
├── view/
│ └── frontend/
│ ├── layout/
│ │ └── catalog_product_view.xml
│ └── templates/
│ └── product_schema.phtml

2. Archivos de registro del módulo

registration.php:

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'TuEmpresa_DatosEstructurados',
__DIR__
);

etc/module.xml:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="TuEmpresa_DatosEstructurados" setup_version="1.0.0">
<sequence>
<module name="Magento_Catalog"/>
</sequence>
</module>
</config>

3. El bloque PHP con la lógica

Es decir, donde construimos los datos estructurados. Block/ProductSchema.php:

<?php
namespace TuEmpresa\DatosEstructurados\Block;
use Magento\Framework\View\Element\Template;
use Magento\Catalog\Model\ProductRepository;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Review\Model\ReviewFactory;
use Magento\Framework\Registry;
class ProductSchema extends Template
{
protected $productRepository;
protected $storeManager;
protected $reviewFactory;
protected $registry;
public function __construct(
Template\Context $context,
ProductRepository $productRepository,
StoreManagerInterface $storeManager,
ReviewFactory $reviewFactory,
Registry $registry,
array $data = []
) {
$this->productRepository = $productRepository;
$this->storeManager = $storeManager;
$this->reviewFactory = $reviewFactory;
$this->registry = $registry;
parent::__construct($context, $data);
}
public function getProduct()
{
return $this->registry->registry('current_product');
}
public function getJsonLdData()
{
$product = $this->getProduct();
if (!$product) {
return null;
}
$store = $this->storeManager->getStore();
$currencyCode = $store->getCurrentCurrencyCode();
// Estructura básica del producto
$schemaData = [
"@context" => "https://schema.org/",
"@type" => "Product",
"name" => $product->getName(),
"description" => strip_tags($product->getDescription()),
"sku" => $product->getSku(),
"image" => $product->getMediaGalleryImages()->getFirstItem()->getUrl(),
"url" => $product->getProductUrl(),
];
// Marca (si existe)
$brand = $product->getAttributeText('manufacturer');
if ($brand) {
$schemaData['brand'] = [
"@type" => "Brand",
"name" => $brand
];
}
// Offer (precio y disponibilidad)
$schemaData['offers'] = [
"@type" => "Offer",
"url" => $product->getProductUrl(),
"priceCurrency" => $currencyCode,
"price" => number_format($product->getFinalPrice(), 2, '.', ''),
"availability" => $product->isAvailable()
? "https://schema.org/InStock"
: "https://schema.org/OutOfStock",
"itemCondition" => "https://schema.org/NewCondition"
];
// Reviews y ratings (si existen)
$this->reviewFactory->create()->getEntitySummary($product, $store->getId());
$ratingSummary = $product->getRatingSummary();
$reviewCount = $product->getReviewsCount();
if ($reviewCount > 0 && $ratingSummary) {
$schemaData['aggregateRating'] = [
"@type" => "AggregateRating",
"ratingValue" => round($ratingSummary->getRatingSummary() / 20, 1),
"bestRating" => "5",
"worstRating" => "1",
"reviewCount" => $reviewCount
];
}
return $schemaData;
}
public function getJsonLdString()
{
$data = $this->getJsonLdData();
if (!$data) {
return '';
}
return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
}
}

4. El layout XML

view/frontend/layout/catalog_product_view.xml:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<block class="TuEmpresa\DatosEstructurados\Block\ProductSchema"
name="product.schema.jsonld"
template="TuEmpresa_DatosEstructurados::product_schema.phtml"
after="-"/>
</referenceContainer>
</body>
</page>

5. La plantilla phtml

view/frontend/templates/product_schema.phtml:

<?php
$jsonLd = $block->getJsonLdString();
if ($jsonLd):
?>
<script type="application/ld+json">
<?= /* @noEscape */ $jsonLd ?>
</script>
<?php endif; ?>

6. Activar el módulo

Ejecuta los siguientes comandos desde la raíz de Magento:

bin/magento module:enable TuEmpresa_DatosEstructurados
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento setup:static-content:deploy -f
bin/magento cache:clean

Extendiendo el módulo

El código anterior es una base. En mis proyectos suelo añadir condicionales para diferentes escenarios:

La lógica puede complicarse bastante dependiendo del caso, pero siempre partiendo de esta estructura base. Esto es algo que vemos en detalle en mi máster de SEO técnico.

Alternativa: usar el buffer de PHP

Si no quieres o no puedes crear un módulo completo, existe otra opción: usar el todopoderoso buffer de PHP para inyectar los datos estructurados en el HTML antes de enviarlo al navegador.

Esta técnica es especialmente útil cuando:

La idea es interceptar el HTML completo, detectar en qué página estamos, y añadir el JSON-LD correspondiente justo antes del </head> o del </body>.

Un ejemplo simplificado:

<?php
// En un observer o plugin que capture el output
public function addStructuredData($html)
{
// Detectar si es página de producto
if (strpos($_SERVER['REQUEST_URI'], '/product/') !== false) {
$schema = $this->buildProductSchema();
$schemaScript = '<script type="application/ld+json">' . json_encode($schema) . '</script>';
$html = str_replace('</head>', $schemaScript . '</head>', $html);
}
return $html;
}

Esta técnica requiere más cuidado porque trabajas con el HTML ya generado, pero te da flexibilidad total.

Lo que NO recomiendo: Tag Manager y JavaScript

Existe la opción de añadir datos estructurados desde Google Tag Manager. Google en su documentación te especifica cómo hacerlo. Y realmente sería insertando una etiqueta de HTML dentro de un contenedor de la herramienta.

El resumen de cómo funciona esto: si el usuario rastrea la página con JavaScript, una de las funciones de este Tag Manager va a ser poner el código en cuestión. Pero va a tener que renderizar el JavaScript antes. Por lo cual, en el caso en el que Google rastree la página sin JavaScript (lo que es bastante posible), no se verá dicho dato estructurado.

Lo que dice John Mueller al respecto

Según él, Google no tiene problemas a la hora de rastrearlo, pero aun así recomienda insertar los datos estructurados en la propia web y no en herramientas externas por mantenimiento.

En mi propia experiencia, he visto ocasiones donde Google no ha sido capaz de ver los datos estructurados cuando se han insertado por JavaScript con CSR (que es la forma habitual de JS). Se puede comprobar si lo lee por medio de la Search Console.

Mi opinión: ¿por qué insertar los datos estructurados de una forma arriesgada y con menor escalabilidad cuando puedes hacerlo directamente en el servidor?

Verificar que funciona

Después de implementar los datos estructurados, es fundamental verificar que todo está correcto.

1. Google Rich Results Test

La herramienta oficial de Google para validar datos estructurados: Rich Results Test. Introduce la URL de un producto y comprueba que detecta correctamente el schema de Product.

2. Schema.org Validator

Para una validación más exhaustiva contra el estándar schema.org: Schema Markup Validator.

3. Search Console

En Google Search Console, ve a Mejoras > Productos (o el tipo de schema que hayas implementado). Así verás si Google está detectando correctamente los datos estructurados y si hay errores o advertencias.

4. Ver el código fuente

Lo más básico: abre el código fuente de la página (Ctrl+U) y busca application/ld+json. Deberías ver tu bloque de JSON-LD con todos los datos del producto.

Errores comunes a evitar

Schemas adicionales para ecommerce

Además del schema de Product, considera implementar:

Resumen

Banner promocionado:

Geohat LLM

Fuentes

Si te gusta este artículo, me ayudarías un montón compartiendo mi contenido:
No se te da mal el SEO Técnico

Te falta mi máster. Accede a una formación avanzada que te permitirá aplicar e implementar SEO en cualquier tipo de WEB

¡Accede al Máster de SEO Técnico!
Tal vez te interesen otros artículos:
Artículos de SEO
Usamos cookies para asegurar que te damos la mejor experiencia en nuestra web. Aquí tienes nuestra política de Cookies.