Auto Internal Link Blogger: Script Similarity-Based untuk SEO Otomatis

Auto internal link adalah teknik SEO yang menghubungkan artikel blog secara otomatis berdasarkan kemiripan konten. Bedanya dengan metode biasa? Script ini nggak pakai exact match judul, tapi algoritma similarity-based yang lebih fleksibel. Jadi kalau ada frase di artikel yang mirip dengan judul artikel lain, langsung jadi link internal.


Kenapa Auto Internal Link Penting Buat SEO

Menurut Google Search Central, internal link membantu mesin pencari memahami struktur situs dan hubungan antar konten. Manfaat yang dirasakan langsung:

  • Distribusi authority — PageRank mengalir ke seluruh artikel, nggak cuma yang di homepage
  • Bounce rate turun — Pembaca klik ke artikel terkait, nggak langsung kabur
  • Dwell time naik — Waktu di situs lebih lama karena eksplorasi konten
  • Indexation lebih cepat — Googlebot menemukan artikel lama lewat link baru
  • Topical authority — Blog dianggap otoritas di niche tertentu

Perbedaan Script Ini vs Auto Link Biasa

Fitur Auto Link Biasa Script Similarity Ini
Pencocokan Harus exact match judul penuh Kemiripan kata minimal 30%
Contoh real Judul "Cara Membuat Kue Bolu" → harus ada frase persis itu Teks "teknik membuat kue bolu lembut" → tetap ke-detect mirip
Fleksibilitas Kaku, sering miss Pintar, nangkep variasi bahasa
Performa Langsung jalan, ringan Lazy load, nggak blok render

Cara Kerja Algoritmanya

Script pakai kombinasi word overlap scoring dan phrase matching. Prosesnya dalam 3 langkah:

1. Tokenisasi

Judul artikel dan teks postingan dipecah jadi kata-kata. Kata umum kayak yang, dan, di, untuk di-skip lewat stop words filtering.

Judul: "Cara Optimasi SEO Blogger"
Token: ["optimasi", "seo", "blogger"]

Teks artikel: "teknik optimasi seo untuk blog"
Token: ["teknis", "optimasi", "seo", "blog"]

2. Hitung Skor Kemiripan

Script itung berapa persen kata dari judul yang muncul di teks:

Kata judul yang cocok: "optimasi", "seo" = 2 dari 3 kata
Skor: 2/3 = 0.67 (67%)
Threshold minimal: 0.3 (30%)
Hasil: ✅ Lolos, jadi kandidat link

3. Cari Frase Terbaik

Dari artikel kandidat, script cari frase spesifik di teks yang paling cocok dijadikan anchor text:

Judul artikel tujuan: "Tips Optimasi SEO Blogger"
Frase di teks ini: "teknik optimasi seo"
Anchor text jadinya: <a href="...">optimasi seo</a>

Pengaturan yang Bisa Diubah

Semua konfigurasi ada di bagian var C = {...}. Berikut penjelasan lengkap tiap parameter:

Kode Nama Default Fungsi
m max-results 50 Jumlah artikel diambil dari feed Blogger
t threshold .3 Minimal skor kemiripan (0 sampai 1)
w words 2 Minimal kata dari judul yang harus cocok
l limit 4 Maksimal link internal per artikel
p phrase 6 Minimal panjang karakter frase link
s selector .post .content Elemen HTML tempat link ditanam
c class auto-internal-link Class CSS untuk link yang dibuat
x stop words daftar panjang Kata yang diabaikan saat hitung kemiripan

m (max-results) — Jumlah Artikel dari Feed

  • m: 25 — Blog baru, performa paling cepat
  • m: 50 — Default, cocok untuk kebanyakan blog
  • m: 100 — Blog besar, lebih banyak pilihan link
  • m: 150 — Blog raksasa, proses lebih lambat

t (threshold) — Ambang Batas Kemiripan

  • t: .15 — Banyak link, kadang kurang relevan
  • t: .3 — Default, seimbang
  • t: .5 — Sedikit link, tapi sangat relevan
  • t: .7 — Hampir exact match, sangat ketat

w (words) — Minimal Kata Cocok

  • w: 1 — Risiko link nggak relevan tinggi
  • w: 2 — Default, paling aman
  • w: 3 — Lebih ketat, untuk judul panjang
  • w: 4 — Sangat ketat, blog teknis/spesifik

l (limit) — Maksimal Link per Artikel

  • l: 2 — Artikel pendek (< 500 kata)
  • l: 4 — Default, artikel standar
  • l: 6 — Artikel panjang (1000+ kata)
  • l: 8 — Long-form content (2000+ kata)

p (phrase) — Minimal Panjang Frase

  • p: 4 — Bisa link frase pendek, risiko kata umum
  • p: 6 — Default, seimbang
  • p: 8 — Hanya frase bermakna
  • p: 10 — Frase panjang, blog akademis

Kalau Hasilnya Kurang Pas, Gimana?

Masalah Solusi
Terlalu banyak link salah Naikkan t ke .5, naikkan w ke 3
Terlalu sedikit link Turunkan t ke .15, naikkan l ke 6
Link nggak relevan Naikkan w ke 3, naikkan p ke 8
Performa lambat Turunkan m ke 25
Artikel panjang kurang link Naikkan l ke 6 atau 8
Frase pendek salah link Naikkan p ke 8 atau 10

Cara Pasang di Blogger

Langkah 1: Buka Editor Tema

Masuk ke Tema → Edit HTML. Jangan lupa backup tema dulu ya, jaga-jaga kalau ada yang salah.

Langkah 2: Cari Lokasi Penempatan

Cari tag penutup body di template. Biasanya bentuknya:

</body>

Atau kalau template pakai komentar XML:

&lt;!--</body>--&gt;

Langkah 3: Tempel Script Ini

Copy script berikut dan paste sebelum tag penutup body. Script sudah dibungkus <b:if> jadi cuma aktif di halaman postingan dan static page, nggak ganggu homepage.

<b:if cond='data:view.isPost or data:view.isPage'>
<script>//<![CDATA[
(function(){
    "use strict";
    var C = {
        m: 50,
        t: .3,
        w: 2,
        l: 4,
        p: 6,
        s: ".post-body, .content, .post .content",
        c: "auto-internal-link",
        x: "yang dan di dari ke pada untuk dengan ini itu adalah atau sebagai juga sudah akan bisa ada tidak oleh karena dalam saat setelah sebelum namun tetapi jika maka agar supaya saja hanya lebih sangat terlalu belum pernah sering kadang mungkin mestinya seharusnya cara tips tutorial panduan bagaimana apa siapa kapan dimana mengapa kenapa the a an is are was were be been being have has had do does did will would could should may might must shall can need dare ought used to of in on at by about into through during before after above below between under again further then once here there when where why how all any both each few more most other some such no nor not only own same so than too very just now".split(" ")
    };

    function T(t){
        return t.toLowerCase().replace(/[^a-z0-9\s]/g," ").split(/\s+/).filter(function(w){
            return w.length > 2 && C.x.indexOf(w) === -1;
        });
    }

    function O(a,b){
        var m = 0;
        for(var i = 0; i < b.length; i++) if(a.indexOf(b[i]) !== -1) m++;
        return b.length === 0 ? 0 : m / b.length;
    }

    function F(tt,tx){
        var tl = tx.toLowerCase();
        for(var len = Math.min(tt.length,3); len >= 2; len--){
            for(var s = 0; s <= tt.length - len; s++){
                var ph = tt.slice(s,s+len).join(" ");
                if(ph.length < C.p) continue;
                var re = new RegExp("\b" + tt.slice(s,s+len).map(function(w){
                    return w.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");
                }).join("(?:[\s\-.,;:!?]{1,3}\w*?){0,2}[\s\-.,;:!?]{1,3}") + "\b","i");
                if(re.test(tl)) return {ph:ph, re:re};
            }
        }
        return null;
    }

    function I(){
        var ct = document.querySelector(C.s);
        if(!ct) return;
        var cu = window.location.href.split(/[?#]/)[0],
            fu = window.location.origin + "/feeds/posts/summary?alt=json&max-results=" + C.m;

        fetch(fu).then(function(r){return r.json()}).then(function(d){
            var e = d.feed.entry || [], ar = [];
            e.forEach(function(en){
                var ti = en.title.$t.trim(), ur = "", ls = en.link || [];
                for(var i = 0; i < ls.length; i++) {
                    if(ls[i].rel === "alternate"){
                        ur = ls[i].href.split(/[?#]/)[0];
                        break;
                    }
                }
                if(ur && ur !== cu && ti.length > 5){
                    ar.push({t:ti, u:ur, k:T(ti)});
                }
            });
            if(ar.length === 0) return;

            var wk = document.createTreeWalker(ct, NodeFilter.SHOW_TEXT, null, false), at = "", tn = [];
            while(wk.nextNode()){
                var pn = wk.currentNode.parentNode, tg = pn.tagName;
                if(tg !== "A" && tg !== "SCRIPT" && tg !== "STYLE" && !/^H[1-6]$/.test(tg)){
                    at += " " + wk.currentNode.nodeValue;
                    tn.push(wk.currentNode);
                }
            }

            var tk = T(at), sc = [];
            ar.forEach(function(a){
                var scv = O(tk, a.k), mt = 0;
                a.k.forEach(function(w){ if(tk.indexOf(w) !== -1) mt++; });
                if(scv >= C.t && mt >= C.w) sc.push({a:a, v:scv});
            });

            sc.sort(function(a,b){return b.v - a.v});
            var cd = sc.slice(0, C.l);
            if(cd.length === 0) return;

            var lp = [];
            cd.forEach(function(c){
                var ph = F(c.a.k, at);
                if(ph) lp.push({re:ph.re, u:c.a.u, ti:c.a.t, us:false});
            });

            lp.sort(function(a,b){return b.ti.length - a.ti.length});
            var ad = 0;

            tn.forEach(function(nd){
                if(ad >= C.l) return;
                var tx = nd.nodeValue;
                for(var i = 0; i < lp.length; i++){
                    if(lp[i].us) continue;
                    if(lp[i].re.test(tx)){
                        var sp = document.createElement("span");
                        sp.innerHTML = tx.replace(lp[i].re, function(m){
                            lp[i].us = true;
                            ad++;
                            return '<a href="' + lp[i].u + '" class="' + C.c + '" title="' + lp[i].ti.replace(/"/g,"&quot;") + '">' + m + '</a>';
                        });
                        var pa = nd.parentNode;
                        while(sp.firstChild) pa.insertBefore(sp.firstChild, nd);
                        pa.removeChild(nd);
                        break;
                    }
                }
            });
            console.log("AIL:", ad, "links");
        }).catch(function(e){console.error("AIL:", e)});
    }

    var ob = new IntersectionObserver(function(en){
        en.forEach(function(e){
            if(e.isIntersecting){
                if("requestIdleCallback" in window) requestIdleCallback(I,{timeout:2e3});
                else setTimeout(I, 500);
                ob.disconnect();
            }
        });
    }, {rootMargin:"200px 0px"});

    var tg = document.querySelector(C.s);
    if(tg) ob.observe(tg);
})();
//]]></script>
</b:if>

Langkah 4: Sesuaikan Selector (Kalau Perlu)

Untuk template Blogger standar:

s: ".post-body"

Untuk template custom (seperti ruangdebug):

s: ".post .content"

Untuk universal (support semua template):

s: ".post-body, .content, .post .content"

Langkah 5: Verifikasi Instalasi

Buka artikel postingan, tekan F12 buka Developer Tools, pilih tab Console. Scroll ke area artikel. Kalau muncul log kayak gini, berarti sukses:

AIL: 3 links

Angkanya menunjukkan berapa link internal yang berhasil dibuat di artikel tersebut.


Optimasi Performa yang Sudah Built-in

Script ini dirancang dengan beberapa optimasi biar nggak ganggu performa blog:

Lazy Loading via IntersectionObserver

Script nggak jalan saat halaman pertama kali dibuka. Ia nunggu sampai pembaca scroll mendekati area artikel (dengan margin 200px). Ini jaga-jaga biar LCP (Largest Contentful Paint) tetap cepat dan nggak kena penalty Core Web Vitals.

Idle Execution via requestIdleCallback

Ketika elemen artikel ke-detect, script nunggu browser dalam kondisi idle baru mulai proses. Jadi nggak blocking main thread saat pembaca lagi baca artikel.

SEO Safety

Googlebot tetap bisa mengenali internal link karena beberapa alasan:

  • Feed Blogger (/feeds/posts/summary) juga di-crawl Google
  • Link dibuat setelah render, tapi tetap ada di DOM final
  • Class auto-internal-link memudahkan identifikasi struktur

Support Dark Mode Otomatis

Link mengikuti variabel CSS --color-link dari template. Di dark mode jadi putih, di light mode jadi biru. Nggak perlu nambah CSS apapun.


Kesimpulan

Auto internal link berbasis similarity ini solusi SEO yang lebih cerdas dari exact match biasa. Dengan algoritma word overlap dan phrase matching, script mampu nangkep kemiripan konten meski frase nggak identik persis dengan judul.

Kombinasi lazy loading, idle execution, dan threshold yang bisa disesuaikan bikin script ini cocok untuk berbagai ukuran blog tanpa ngorbankan performa. Pengaturan default udah optimal untuk kebanyakan kasus, tapi tetap fleksibel kalau mau disesuaikan.

Mulai dengan pengaturan default, monitor via console, lalu sesuaikan threshold dan limit berdasarkan jumlah serta relevansi link yang dihasilkan. Selamat mencoba.

Aurealisa ID
Fakta Gambar (Science Fact), Kutipan (Quote Of The Day), Ulasan (Science Review), Tips, Artikel.

Komentar