Configurar OpenGraph en WordPress sin plugins

Si alguna vez has compartido un enlace de tu blog en Facebook, Twitter o WhatsApp y solo aparece un link feo sin imagen ni descripción, este tutorial es para ti.

Las etiquetas OpenGraph y Twitter Card son metadatos que le dicen a las redes sociales cómo mostrar tu contenido cuando alguien lo comparte. Sin ellas, pierdes una oportunidad enorme de generar clics y engagement.

#¿Qué conseguirás con esta implementación?

  • ✅ Previews atractivas con imagen, título y descripción en Facebook, Twitter, LinkedIn y WhatsApp
  • ✅ Control total sobre cómo se ve tu contenido al compartirse
  • ✅ Más clics y mejor engagement en redes sociales
  • ✅ Aspecto profesional que genera confianza
  • ✅ Implementación automática para todos tus posts y páginas

#Paso 1: Añadir la llamada en header.php

Primero, vamos a modificar el archivo header.php de tu tema para que llame a la función que generará las etiquetas.

Abre wp-content/themes/tu-tema/header.php y busca la sección <head>. Justo después de la meta description (o antes de <?php wp_head(); ?>), añade:

text
<?php if (function_exists('mi_tema_social_meta_tags')) : ?>
<?php mi_tema_social_meta_tags(); ?>
<?php endif; ?>

Tu <head> debería quedar algo así:

text
<head>
    <meta charset="<?php bloginfo('charset'); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="...">
    
    <!-- Etiquetas OpenGraph y Twitter Card -->
    <?php if (function_exists('mi_tema_social_meta_tags')) : ?>
    <?php mi_tema_social_meta_tags(); ?>
    <?php endif; ?>
    
    <?php wp_head(); ?>
</head>

#Paso 2: Crear la función en functions.php

Ahora viene la parte importante. Abre wp-content/themes/tu-tema/functions.php y añade esta función completa al final del archivo:

text
/**
 * Generar etiquetas OpenGraph y Twitter Card para redes sociales
 */
function mi_tema_social_meta_tags() {
    // Variables comunes
    $site_name = get_bloginfo('name');
    $site_description = get_bloginfo('description');
    $site_url = home_url('/');
    
    // Imagen por defecto (ajusta la ruta a tu logo)
    $default_image = get_template_directory_uri() . '/assets/img/logo.png';
    
    // Si tienes logo personalizado, úsalo
    if (has_custom_logo()) {
        $custom_logo_id = get_theme_mod('custom_logo');
        $logo = wp_get_attachment_image_src($custom_logo_id, 'full');
        if ($logo) {
            $default_image = $logo[0];
        }
    }
    
    // Inicializar variables
    $og_title = '';
    $og_description = '';
    $og_image = $default_image;
    $og_url = '';
    $og_type = 'website';
    
    // Página de inicio
    if (is_front_page() || is_home()) {
        $og_title = $site_name;
        $og_description = $site_description;
        $og_url = $site_url;
        $og_type = 'website';
    }
    // Post individual
    elseif (is_single()) {
        $og_title = get_the_title();
        
        // Usar excerpt si existe, si no, primeras palabras del contenido
        if (has_excerpt()) {
            $og_description = get_the_excerpt();
        } else {
            $og_description = wp_trim_words(get_the_content(), 25, '...');
        }
        
        $og_url = get_permalink();
        $og_type = 'article';
        
        // Usar imagen destacada si existe
        if (has_post_thumbnail()) {
            $thumbnail = wp_get_attachment_image_src(get_post_thumbnail_id(), 'large');
            if ($thumbnail) {
                $og_image = $thumbnail[0];
            }
        }
    }
    // Página
    elseif (is_page()) {
        $og_title = get_the_title();
        
        if (has_excerpt()) {
            $og_description = get_the_excerpt();
        } else {
            $og_description = wp_trim_words(get_the_content(), 25, '...');
        }
        
        $og_url = get_permalink();
        
        if (has_post_thumbnail()) {
            $thumbnail = wp_get_attachment_image_src(get_post_thumbnail_id(), 'large');
            if ($thumbnail) {
                $og_image = $thumbnail[0];
            }
        }
    }
    // Categoría
    elseif (is_category()) {
        $category = get_queried_object();
        $og_title = single_cat_title('', false) . ' - ' . $site_name;
        $og_description = category_description() ?: 'Artículos sobre ' . single_cat_title('', false);
        $og_url = get_category_link($category->term_id);
    }
    // Fallback
    else {
        $og_title = $site_name;
        $og_description = $site_description;
        $og_url = $site_url;
    }
    
    // Limpiar valores
    $og_title = wp_strip_all_tags($og_title);
    $og_description = wp_strip_all_tags($og_description);
    
    // Generar las etiquetas
    ?>
    
    <!-- Open Graph / Facebook -->
    <meta property="og:type" content="<?php echo esc_attr($og_type); ?>">
    <meta property="og:url" content="<?php echo esc_url($og_url); ?>">
    <meta property="og:title" content="<?php echo esc_attr($og_title); ?>">
    <meta property="og:description" content="<?php echo esc_attr($og_description); ?>">
    <meta property="og:image" content="<?php echo esc_url($og_image); ?>">
    <meta property="og:site_name" content="<?php echo esc_attr($site_name); ?>">
    <meta property="og:locale" content="es_ES">
    
    <!-- Twitter Card -->
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:url" content="<?php echo esc_url($og_url); ?>">
    <meta name="twitter:title" content="<?php echo esc_attr($og_title); ?>">
    <meta name="twitter:description" content="<?php echo esc_attr($og_description); ?>">
    <meta name="twitter:image" content="<?php echo esc_url($og_image); ?>">
    
    <!-- URL Canónica -->
    <link rel="canonical" href="<?php echo esc_url($og_url); ?>">
    <?php
}

#Paso 3: Personalizar (opcional)

#Añadir tu cuenta de Twitter

Si tienes cuenta de Twitter, añade estas líneas dentro de la sección de Twitter Card:

text
<meta name="twitter:site" content="@tu_usuario">
<meta name="twitter:creator" content="@tu_usuario">

#Cambiar la imagen por defecto

Modifica esta línea para usar tu propia imagen:

text
$default_image = get_template_directory_uri() . '/assets/img/logo.png';

Recomendación: Usa una imagen de 1200×630 píxeles en formato JPG o PNG.

#Paso 4: Probar que funciona

Una vez implementado, es hora de verificar que todo funciona correctamente:

#1. Verificar el código fuente

  1. Abre cualquier post de tu blog
  2. Clic derecho → «Ver código fuente»
  3. Busca (Ctrl+F) og: o twitter:
  4. Deberías ver todas las etiquetas meta generadas

#2. Facebook Sharing Debugger

#3. Twitter Card Validator

#4. LinkedIn Post Inspector

#💡 Mejores prácticas

Para obtener los mejores resultados al compartir en redes sociales:

#📸 Imágenes

  • Tamaño ideal: 1200×630 píxeles (ratio 1.91:1)
  • Tamaño mínimo: 600×315 píxeles
  • Formato: JPG o PNG (WebP también funciona)
  • Peso: Menos de 1MB para carga rápida
  • Contenido: Evita texto pequeño que no se lea en móvil

#✍️ Textos

  • Título: Máximo 60 caracteres para evitar que se corte
  • Descripción: Entre 120-160 caracteres
  • Excerpt: Escribe excerpts personalizados para cada post importante

#🎯 Consejos adicionales

  • Siempre usa imagen destacada en tus posts
  • Escribe títulos llamativos que generen curiosidad
  • Las descripciones deben ser atractivas, no solo informativas
  • Prueba diferentes imágenes para ver cuál genera más clics

#🚨 Solución de problemas comunes

#❌ «La imagen no aparece en Facebook»

Solución:

  • Verifica que la imagen sea accesible públicamente (no esté bloqueada por .htaccess)
  • Usa el Facebook Debugger y haz clic en «Scrape Again»
  • Asegúrate de que la imagen sea al menos 600×315 píxeles

#❌ «Aparece contenido antiguo al compartir»

Solución:

  • Facebook cachea las previews. Usa el Debugger y «Scrape Again»
  • Para LinkedIn, usa el Post Inspector
  • Twitter actualiza automáticamente, pero puede tardar unos minutos

#❌ «No veo las etiquetas en el código fuente»

Solución:

  • Verifica que hayas guardado los cambios en functions.php y header.php
  • Limpia la caché de WordPress si usas un plugin de caché
  • Verifica que no haya errores de PHP (activa WP_DEBUG)

#🆚 ¿Plugin o código personalizado?

Existen plugins como Yoast SEO o Rank Math que también añaden estas etiquetas. ¿Por qué usar código personalizado?

#✅ Ventajas del código personalizado:

  • 🚀 Más rápido: No cargas un plugin pesado solo para esto
  • 🎯 Control total: Personalizas exactamente lo que necesitas
  • 🧹 Código limpio: Solo lo necesario, sin funciones extra
  • 📚 Aprendes: Entiendes cómo funciona WordPress por dentro
  • 💰 Gratis: No necesitas versión premium de ningún plugin

#❌ Desventajas:

  • Requiere editar código (pero es muy sencillo)
  • No tiene interfaz visual para editar por post (aunque puedes añadirla con custom fields)