Membuat Widget “Artikel Terkait” di WordPress dari Subdomain via GraphQL

Dalam salah satu proyek yang saya kerjakan, saya harus bisa menampilkan artikel terbaru dari blog (blog.domain.com) di website utama (www.domain.com) secara relevan.

Di dokumentasi ini, saya akan membagikan studi kasus lengkap tentang proses yang saya lakukan untuk membuat widget artikel terbaru yang dinamis, mengambil data via GraphQL, dan mengimplementasikan logika fallback yang cerdas.

Tujuan proyek ini adalah memastikan widget berita di web utama selalu relevan dengan konten yang sedang dilihat pengguna, dan yang terpenting, tidak pernah tampil kosong.

Penentuan Alur dan Teknologi

Sebelum memulai coding, langkah pertama adalah melakukan analisis. Karena website utama dan blog berada di domain yang berbeda, saya tidak bisa mengambil data langsung dari database. Solusinya adalah menggunakan jembatan API (Application Programming Interface).

Untuk proyek ini, saya memutuskan menggunakan GraphQL yang disediakan oleh WordPress. Alasan utamanya adalah efisiensi. GraphQL memungkinkan saya untuk meminta hanya data spesifik yang dibutuhkan (judul, link, kutipan), sehingga tidak membebani server. Data mentah ini kemudian akan saya olah menggunakan PHP di sisi website utama.

Membangun Service API Khusus

Pada tahap pengembangan, langkah pertama yang saya ambil adalah membuat sebuah service khusus dalam bentuk class PHP. Tujuan utamanya adalah untuk mengisolasi semua logika yang berhubungan dengan pengambilan data, sehingga struktur kode proyek menjadi lebih rapi dan mudah dikelola di kemudian hari.

1. Membuat File Service API

Saya membuat sebuah file API.php. File ini berisi sebuah class yang bertanggung jawab menangani semua permintaan ke blog di subdomain.

2. Mendefinisikan Properti dan Fungsi Utama

Di dalam class ini, saya mendefinisikan fungsi utama untuk mengambil dan mengubah data JSON dari GraphQL menjadi format array PHP.

<?php
namespace App\Services;

use GuzzleHttp\Client; // Saya menggunakan Guzzle untuk request HTTP.

class API {

    // Definisikan alamat blog target
    private static $domain = "[https://blog.domain-anda.com/](https://blog.domain-anda.com/)";

    /**
     * Fungsi private untuk mengambil dan men-decode data dari API.
     * @param   string $api_url
     * @return  array
    */
    private static function decodeData(string $api_url) {
        $client = new Client(['verify' => false]); // 'verify' => false untuk development

        $response = $client->request('GET', $api_url);
        $body = $response->getBody();
        $data = json_decode($body->getContents());

        if (isset($data->errors)) {
            // Jika ada error dari GraphQL, kembalikan array kosong.
            return [];
        } else {
            return $data->data->posts->nodes;
        }
    }
}
?>

Fungsi decodeData ini menjadi jantung dari service yang saya bangun, karena inilah yang bertugas “berkomunikasi” dengan blog di subdomain.

3. Membuat Fungsi Berdasarkan Tag dan Kategori

Selanjutnya, saya menambahkan dua fungsi publik: satu untuk mengambil artikel berdasarkan slug tag (pencarian utama), dan satu lagi untuk mengambil berdasarkan ID kategori (sebagai rencana fallback).

<?php
// Lanjutan dari class API di atas...

class API {
    // ... (properti $domain dan method decodeData) ...

    /**
     * Mengambil artikel blog berdasarkan slug tag.
     */
    public function getBlogArticlesByTag(string $tag_slug) {
        if (empty($tag_slug)) {
            return [];
        }
        $api_url = self::$domain . '/graphql?query={posts(where:{tag:"' . $tag_slug . '"}){nodes{title,link,date,excerpt}}}';
        return self::decodeData($api_url);
    }

    /**
     * Mengambil artikel blog berdasarkan ID kategori.
     */
    public function getBlogArticlesByCategory(int $category_id) {
        $api_url = self::$domain . '/graphql?query={posts(where:{categoryId: ' . $category_id . '}){nodes{title,link,date,excerpt}}}';
        return self::decodeData($api_url);
    }
}
?>

Dengan ini, mesin API saya telah siap dengan dua kemampuan: getBlogArticlesByTag untuk pencarian prioritas dan getBlogArticlesByCategory sebagai jaring pengaman.

Integrasi ke Template dengan Logika Fallback

Setelah service API siap, tahap selanjutnya adalah integrasi. Di sinilah saya menggunakan class yang telah dibuat di dalam file template WordPress (misalnya single.php) untuk membuat widget artikel terbaru menjadi benar-benar dinamis.

Logika yang saya terapkan sederhana:

  • Pertama, coba cari artikel dengan tag yang relevan (misalnya, berdasarkan slug halaman saat ini).
  • Jika pencarian pertama tidak membuahkan hasil (array kosong), jangan tampilkan error.
  • Sebagai gantinya, lakukan pencarian kedua untuk mengambil artikel dari kategori umum yang sudah ditentukan (ID 37).

Berikut adalah cuplikan kode implementasinya di dalam file template:

<?php
// Asumsikan class API sudah bisa diakses
global $post;
$api_service = new \App\Services\API();

// 1. Ambil sumber tag dinamis dari slug halaman ini
$tag_slug = $post->post_name;

// 2. Lakukan pencarian pertama berdasarkan tag
$blogs = $api_service->getBlogArticlesByTag($tag_slug);

// 3. LOGIKA FALLBACK: Jika hasil pencarian tag kosong...
if (empty($blogs)) {
    // ...lakukan pencarian kedua berdasarkan kategori ID 37.
    $blogs = $api_service->getBlogArticlesByCategory(37);
}

// Sekarang, variabel $blogs dijamin berisi artikel.
// Siap untuk ditampilkan di widget.
?>

<?php if (!empty($blogs)): ?>
    <h2>Berita Terbaru</h2>
    <?php foreach (array_slice($blogs, 0, 4) as $article): // Ambil 4 artikel pertama ?>
        <div class="artikel-item">
            <a href="<?= esc_url($article->link) ?>">
                <h5><?= esc_html($article->title) ?></h5>
                <p><?= esc_html($article->excerpt) ?></p>
            </a>
        </div>
    <?php endforeach; ?>
<?php endif; ?>

Hasilnya sesuai harapan. Widget kini selalu menampilkan artikel yang paling relevan. Jika tidak ada yang cocok, widget tidak akan kosong, melainkan menampilkan berita dari kategori umum.

Dampak pada SEO dan Pengalaman Pengguna

Lebih dari sekadar solusi teknis, implementasi ini menjadi sebuah langkah strategis yang berdampak positif pada SEO dan pengalaman pengguna (UX). Bukan hanya tentang menampilkan artikel, tetapi tentang membangun ekosistem konten yang lebih kuat.

Dari sisi SEO, sistem ini secara efektif menerapkan internal linking otomatis ke artikel-artikel terbaru di subdomain. Setiap kali halaman di domain utama dimuat, ia menyajikan tautan segar ke konten relevan di blog.

Hal ini membantu mesin pencari seperti Google untuk lebih cepat menemukan dan mengindeks konten baru, sekaligus memberi sinyal bahwa artikel-artikel tersebut penting dalam ekosistem website kita.

Dari sisi pengguna, pendekatan ini memberikan nilai lebih kepada pengunjung. Alih-alih melihat widget statis yang sama di setiap halaman, mereka disajikan artikel yang relevan dengan topik yang sedang dibaca.

Logika fallback memastikan selalu ada konten lanjutan yang menarik, yang berpotensi meningkatkan durasi kunjungan dan menurunkan bounce rate. Pada akhirnya, pengalaman pengguna yang baik adalah sinyal positif yang sangat kuat untuk SEO.

Published by rendyandriyanto

Your go-to SEO Specialist. Passionate about achieving growth in digital marketing and financial markets.

Leave a comment

Your email address will not be published. Required fields are marked *