Datos estructurados WooCommerce: código JSON-LD para productos

Datos estructurados WooCommerce: código JSON-LD para productos

Datos estructurados WooCommerce es una mejora técnica clave para que Google entienda mejor la información de tus productos: nombre, precio, imagen, disponibilidad, moneda, país de envío y URL de compra. En una tienda online, este marcado puede ayudar a que los productos se interpreten correctamente en buscadores y también mejora la vista previa cuando se comparten en redes sociales.

El código explicado en esta guía añade metaetiquetas Open Graph, Twitter Card y datos estructurados JSON-LD directamente en las páginas individuales de producto de WooCommerce. Es una solución útil cuando quieres reforzar el SEO técnico de una tienda sin depender por completo de la configuración automática de otros plugins.

<?php
/**
 * Metaetiquetas Open Graph, Twitter Card y JSON-LD para productos WooCommerce.
 * Compatible con cualquier tienda WooCommerce sin depender de WOOCS.
 */

add_action( 'wp_head', 'dc_agregar_metaetiquetas_y_json_ld_en_productos', 20 );

function dc_agregar_metaetiquetas_y_json_ld_en_productos() {

    // Evita errores si WooCommerce no está activo.
    if ( ! function_exists( 'is_product' ) || ! function_exists( 'wc_get_product' ) ) {
        return;
    }

    // Solo ejecutar en páginas individuales de producto.
    if ( ! is_product() ) {
        return;
    }

    global $post;

    if ( ! $post || empty( $post->ID ) ) {
        return;
    }

    // Obtener producto.
    $product = wc_get_product( $post->ID );

    if ( ! $product ) {
        return;
    }

    /**
     * Datos básicos del producto.
     */
    $titulo = $product->get_name();

    $descripcion = $product->get_short_description();

    if ( empty( $descripcion ) ) {
        $descripcion = $product->get_description();
    }

    $descripcion = wp_strip_all_tags( $descripcion );

    $url_producto = get_permalink( $product->get_id() );

    /**
     * Imagen principal del producto.
     */
    $imagen_id = $product->get_image_id();
    $imagen    = $imagen_id ? wp_get_attachment_url( $imagen_id ) : '';

    /**
     * Moneda de la tienda WooCommerce.
     */
    $moneda_tienda = get_woocommerce_currency();

    /**
     * País base configurado en WooCommerce.
     */
    $ubicacion_tienda = function_exists( 'wc_get_base_location' ) ? wc_get_base_location() : array();

    $pais_tienda = ! empty( $ubicacion_tienda['country'] )
        ? $ubicacion_tienda['country']
        : '';

    /**
     * Precio del producto.
     * En productos variables, toma el precio mínimo.
     */
    if ( $product->is_type( 'variable' ) ) {
        $precio = $product->get_variation_price( 'min', true );
    } else {
        $precio = $product->get_price();
    }

    if ( $precio === '' || $precio === null ) {
        return;
    }

    $precio_formateado = wc_format_decimal( $precio, 2 );

    /**
     * Disponibilidad.
     */
    $disponibilidad = $product->is_in_stock()
        ? 'https://schema.org/InStock'
        : 'https://schema.org/OutOfStock';

    /**
     * Fecha hasta la que el precio es válido.
     */
    $fecha_fin_oferta = $product->get_date_on_sale_to();

    if ( $fecha_fin_oferta ) {
        $precio_valido_hasta = $fecha_fin_oferta->date( 'Y-m-d' );
    } else {
        $precio_valido_hasta = date( 'Y-m-d', strtotime( '+1 year' ) );
    }

    /**
     * SKU.
     * Si el producto no tiene SKU, usa el ID como respaldo.
     */
    $sku = $product->get_sku();

    if ( empty( $sku ) ) {
        $sku = (string) $product->get_id();
    }

    /**
     * Marca.
     * Si usas una marca real, puedes cambiar este fallback.
     */
    $marca = get_bloginfo( 'name' );

    /**
     * Open Graph.
     */
    echo "\n<!-- Metaetiquetas personalizadas para producto WooCommerce -->\n";

    echo '<meta property="og:title" content="' . esc_attr( $titulo ) . '">' . "\n";
    echo '<meta property="og:description" content="' . esc_attr( $descripcion ) . '">' . "\n";
    echo '<meta property="og:url" content="' . esc_url( $url_producto ) . '">' . "\n";
    echo '<meta property="og:type" content="product">' . "\n";

    if ( $imagen ) {
        echo '<meta property="og:image" content="' . esc_url( $imagen ) . '">' . "\n";
    }

    /**
     * Twitter Card.
     */
    echo '<meta name="twitter:card" content="summary_large_image">' . "\n";
    echo '<meta name="twitter:title" content="' . esc_attr( $titulo ) . '">' . "\n";
    echo '<meta name="twitter:description" content="' . esc_attr( $descripcion ) . '">' . "\n";

    if ( $imagen ) {
        echo '<meta name="twitter:image" content="' . esc_url( $imagen ) . '">' . "\n";
    }

    /**
     * Oferta del producto.
     */
    $oferta = array(
        '@type'              => 'Offer',
        'url'                => $url_producto,
        'priceCurrency'      => $moneda_tienda,
        'price'              => $precio_formateado,
        'priceValidUntil'    => $precio_valido_hasta,
        'availability'       => $disponibilidad,
        'itemCondition'      => 'https://schema.org/NewCondition',
    );

    /**
     * Envío.
     *
     * IMPORTANTE:
     * El valor está en 0 porque muchos sitios quieren indicar envío gratis.
     * Si tu tienda cobra envío, cambia el value por el costo real o elimina este bloque.
     */
    if ( ! empty( $pais_tienda ) ) {
        $oferta['shippingDetails'] = array(
            array(
                '@type' => 'OfferShippingDetails',
                'shippingRate' => array(
                    '@type'    => 'MonetaryAmount',
                    'value'    => '0',
                    'currency' => $moneda_tienda,
                ),
                'shippingDestination' => array(
                    '@type'          => 'DefinedRegion',
                    'addressCountry' => $pais_tienda,
                ),
            ),
        );
    }

    /**
     * JSON-LD Product Schema.
     */
    $datos_producto = array(
        '@context'    => 'https://schema.org/',
        '@type'       => 'Product',
        'name'        => $titulo,
        'image'       => $imagen ? array( $imagen ) : array(),
        'description' => $descripcion,
        'sku'         => $sku,
        'brand'       => array(
            '@type' => 'Brand',
            'name'  => $marca,
        ),
        'offers'      => $oferta,
    );

    echo '<script type="application/ld+json">' . wp_json_encode(
        $datos_producto,
        JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT
    ) . '</script>' . "\n";
}

¿Qué hace este código en WooCommerce?

El snippet se ejecuta únicamente en páginas de producto. Antes de imprimir cualquier etiqueta, comprueba que WooCommerce esté activo y que la página actual corresponda a un producto individual. Esto evita errores en otras partes del sitio, como entradas, páginas, categorías o la tienda general.

Una vez validada la página, el código obtiene los datos principales desde el producto configurado en WooCommerce:

  • Nombre del producto.
  • Descripción corta o descripción completa.
  • URL permanente del producto.
  • Imagen destacada.
  • Precio actual.
  • Moneda configurada en la tienda.
  • País base de la tienda.
  • Disponibilidad del inventario.
  • SKU o identificador del producto.

Con esta información, el código genera etiquetas para redes sociales y un bloque JSON-LD de tipo Product, que es el formato recomendado para declarar información estructurada de productos.

Por qué los datos estructurados WooCommerce son útiles para SEO

Los datos estructurados WooCommerce ayudan a los motores de búsqueda a comprender el contenido de una página de producto con mayor precisión. Aunque no garantizan resultados enriquecidos, sí facilitan que Google identifique elementos importantes como precio, disponibilidad, imagen, URL y moneda.

Esto es especialmente importante en tiendas online, donde no basta con mostrar productos al usuario. También es necesario que los buscadores puedan leer correctamente qué vendes, cuánto cuesta, si está disponible y desde qué país opera la tienda.

Además, las metaetiquetas Open Graph y Twitter Card mejoran la forma en que se ve un enlace cuando se comparte en plataformas como Facebook, WhatsApp, LinkedIn o X. En lugar de mostrar una vista previa genérica, la página puede mostrar el título, la descripción y la imagen correcta del producto.

Qué necesitas antes de usar este código

Para implementar este snippet correctamente, necesitas una instalación funcional de WordPress con WooCommerce activo. También es importante que cada producto tenga bien configurada su información comercial y visual.

Antes de añadir el código, revisa estos puntos:

  • WooCommerce debe estar instalado y activo.
  • Los productos deben tener precio configurado.
  • La moneda debe estar definida en los ajustes de WooCommerce.
  • El país base de la tienda debe estar configurado correctamente.
  • Cada producto debería tener imagen destacada.
  • La descripción corta debe estar optimizada para SEO y conversión.
  • El stock debe estar bien configurado si usas inventario.

También puedes trabajar con plugins SEO como Yoast SEO, Rank Math o All in One SEO. Sin embargo, debes revisar si estos plugins ya están generando Schema de producto u Open Graph. Si varias herramientas imprimen la misma información, podrías terminar con datos duplicados.

¿Es obligatorio usar Yoast SEO?

No, Yoast SEO no es obligatorio para que este código funcione. El snippet toma la información directamente desde WooCommerce y la imprime en el head de la página mediante el hook wp_head.

Un plugin como Yoast SEO sigue siendo útil para otras tareas: títulos SEO, meta descripciones, sitemap XML, breadcrumbs, indexación y configuración general del sitio. La diferencia es que este código se centra en enriquecer las páginas de producto con marcado JSON-LD y etiquetas sociales.

La recomendación es revisar primero qué está generando tu sitio. Si Yoast, Rank Math u otro plugin ya añade datos estructurados de producto, quizá solo necesites una versión parcial del snippet para corregir o completar propiedades específicas.

Cómo funciona el marcado JSON-LD del producto

El bloque JSON-LD generado por este tipo de implementación usa el tipo Product de Schema.org. Dentro de ese objeto se incluyen propiedades relevantes para una tienda online.

Entre las propiedades más importantes están:

  • name: nombre del producto.
  • image: imagen principal del producto.
  • description: descripción del producto.
  • sku: SKU o identificador del producto.
  • offers: información comercial del producto.
  • priceCurrency: moneda configurada en WooCommerce.
  • price: precio actual del producto.
  • availability: disponibilidad del producto.
  • shippingDetails: detalles básicos de envío.

Una ventaja importante de esta versión del código es que no fuerza una moneda ni un país específico. En lugar de usar valores fijos como COP o Colombia, toma la moneda y el país desde la configuración real de WooCommerce.

Cómo comprobar los datos estructurados en Google

Después de instalar el código, debes validar que Google pueda leer correctamente el marcado. La herramienta principal para hacerlo es Google Rich Results Test.

Solo tienes que pegar la URL de un producto y ejecutar la prueba. Si el marcado está bien implementado, la herramienta puede detectar elementos relacionados con productos, ofertas o resultados enriquecidos.

También puedes revisar la documentación oficial de datos estructurados de productos de Google para comprobar qué propiedades son obligatorias, recomendadas o útiles según el tipo de resultado que quieres conseguir.

Buenas prácticas antes de publicarlo en producción

Antes de activar este código en toda una tienda, lo ideal es probarlo en un entorno de staging o en una página de producto concreta. Así puedes detectar conflictos con otros plugins SEO, el tema activo o snippets anteriores.

También conviene revisar el código fuente de una página de producto. Busca bloques application/ld+json y comprueba si ya existe información de producto generada por otro plugin. Si encuentras varios bloques repitiendo los mismos datos, puede ser necesario ajustar el snippet.

Otra buena práctica es mantener consistencia entre lo que ve el usuario y lo que aparece en el JSON-LD. El precio, la disponibilidad, la moneda y el estado del producto deben coincidir con la información visible en la página.

Conclusión

Implementar datos estructurados WooCommerce con JSON-LD es una mejora técnica valiosa para tiendas online que quieren comunicar mejor sus productos a Google y otras plataformas. Este tipo de código permite automatizar datos importantes como precio, moneda, país, disponibilidad, imagen y URL del producto.

La clave está en usarlo con cuidado. WooCommerce debe estar bien configurado, los productos deben tener información completa y cualquier plugin SEO activo debe revisarse para evitar duplicidades.

Compartir esta información