BookinglyTech News
Software

Quitar un nodo Product del JSON-LD: así se arregló un rich result engañoso

Un sitio de avisos de retirada en tres idiomas marcaba cada artículo con un Product anidado. Google esperaba precios o valoraciones, y la solución fue borrar el nodo, no inventar datos.

2 min de lecturaDev.to0 vistas

Un sitio que publica avisos de retirada de productos marcaba sus artículos con un nodo Product anidado dentro del Article del JSON-LD. Search Console le devolvió nueve URLs inválidas por snippets de producto a los que les faltaban los campos offers, review o aggregateRating. La corrección no fue rellenar esos campos, sino eliminar el nodo entero.

El caso lo cuenta PiFl Labs, que es quien opera el sitio. Conviene tenerlo presente: el material es suyo y de nadie más. El sitio está hecho con Astro y sirve avisos de seguridad pública en coreano, japonés e inglés, a partir de material de la FDA. Son artículos que describen una retirada, no fichas de venta ni análisis.

De dónde salía el aviso

La plantilla incluía un Article con un campo about que apuntaba a un Product con solo el nombre. Para el validador, Product es una entidad de producto, y Google le exige al menos uno de review, aggregateRating u offers además del nombre. De ahí el error. El problema real era el tipo de schema, no la falta de datos comerciales: la página no vende ni reseña nada, así que no había precio ni valoración que poner sin mentir.

El diff que lo arregla es una resta: se borra la propiedad about con su Product anidado, y Article y BreadcrumbList se quedan donde estaban, con su idioma y su URL. Un detalle que importa: las nueve URLs del informe original eran páginas antiguas que hoy devuelven 404. No son las páginas actuales, así que el error listado y el markup corregido no eran lo mismo.

Lo que se probó y lo que no

Borrar el nodo no bastaba. El pull request añade un test de regresión que valida el JSON-LD de la plantilla para cada registro de retirada en los tres idiomas, y trae un modo que además parsea el HTML ya construido. Por cada página comprueba tres cosas: que no haya ningún nodo anidado con @type Product, que siga habiendo un Article con el inLanguage y el mainEntityOfPage esperados, y que se mantenga el BreadcrumbList con la URL de la página de detalle.

En el checkout actual pasan 357 combinaciones de página e idioma: 119 registros por 3 idiomas. Eso valida el markup que genera la plantilla, no que Google haya rastreado 357 URLs públicas. Aparte se comprobó una URL pública representativa por idioma: HTTP 200, con Article y BreadcrumbList y sin Product. Tres muestras en vivo no son un rastreo.

Y la validación de Search Console se lanzó después del despliegue, pero no había terminado cuando se escribió la nota. No hay forma de afirmar que los nueve errores originales estén resueltos, ni que aparezca un rich result, ni que suban los clics.

Lo que sí queda es el patrón: cuando un validador pide campos que faltan, conviene preguntarse antes si el tipo de schema es el correcto. Y mantener despliegue, rastreo, elegibilidad y tráfico como afirmaciones separadas.