Cara Membuat Tombol Salin Kode Otomatis di Blogger (Ala GitHub) Tanpa Edit Template

Ilustrasi halaman Blogger yang menampilkan tutorial cara membuat tombol salin kode otomatis ala GitHub lengkap dengan blok kode dan tombol Salin.

Pendahuluan

Pada era blogging modern, tampilan konten yang rapi dan interaktif bukan lagi sekadar bonus, melainkan kebutuhan. Terutama bagi blogger yang sering membagikan tutorial, skrip, perintah Termux, atau kode pemrograman. Salah satu fitur penting yang membantu pembaca adalah tombol “Salin” (Copy Code) seperti yang biasanya kita lihat di GitHub atau platform dokumentasi modern.

Sayangnya, platform Blogger tidak menyediakan fitur ini secara bawaan. Kamu harus menambahkannya sendiri. Kabar baiknya, membuat tombol salin di setiap blok kode bisa dilakukan tanpa mengedit template, cukup dengan menempelkan script sederhana langsung di postingan.

Artikel ini membahas langkah lengkap cara membuat tombol salin otomatis ala GitHub yang modern, rapi, elegan, dan kompatibel dengan semua template Blogger, baik bawaan maupun premium seperti Median UI, Fletro, Sinilad, atau yang lainnya.

Dengan mengikuti panduan ini, setiap blok <pre><code> di artikel Anda akan otomatis memiliki tombol Salin dengan ikon clipboard, animasi, dan tampilan profesional.


Mengapa Blogger Perlu Memiliki Tombol Salin Kode?

Menambahkan tombol salin tidak hanya untuk mempercantik tampilan blog. Ada beberapa manfaat praktis yang sangat membantu pembaca:

1. Meningkatkan Pengalaman Pengguna

Pembaca tidak perlu lagi melakukan blok manual, menahan drag, atau kesulitan menyalin kode yang panjang.

2. Mempercepat Akses Informasi

Satu klik langsung menyalin kode. Efektif untuk tutorial teknis seperti Termux, coding, command line, dan konfigurasi server.

3. Tampilan Blog Lebih Profesional

Blog yang punya fitur seperti GitHub cenderung terlihat lebih modern dan dipercaya oleh pengguna.

4. Mengurangi Kesalahan Copy-Paste

Kode yang disalin manual sering kurang rapi. Tombol otomatis memastikan isi pre/code tersalin utuh tanpa spasi aneh.


Fitur Tombol Salin Ala GitHub yang Akan Kita Buat

Script yang kita gunakan memiliki sejumlah kelebihan:

  • Bisa dipasang tanpa mengedit template Blogger.
  • Bisa berjalan di semua template, termasuk premium.
  • Tampilannya modern, mirip GitHub.
  • Terdapat ikon clipboard yang responsif.
  • Ada indikator sukses ("Tersalin!").
  • Bekerja di desktop maupun mobile.
  • Aman untuk SEO dan tidak mengurangi performa halaman.

Berikut ini adalah tampilan fitur secara garis besar:

Fitur Deskripsi
Tombol Salin Muncul otomatis di pojok kanan blok kode
Ikon Clipboard Ikon SVG ringan (tanpa gambar tambahan)
Animasi Feedback Perubahan warna dan teks ketika berhasil disalin
Fallback Copy Tetap berjalan walau browser tidak mendukung Clipboard API
Ringan Kurang dari 5KB

Langkah-Langkah Membuat Tombol Salin Otomatis di Blogger

Bagian ini menjelaskan tutorial lengkap yang bisa kamu ikuti dari awal sampai selesai. Pastikan menggunakan mode HTML di editor Blogger.


1. Siapkan Blok Kode <pre><code> di Postingan

Setiap script yang ingin diberi tombol salin harus ditulis dalam format standar:

<pre><code>
pkg install python
pkg install curl
pkg update
</code></pre>

Template apapun akan mendeteksi blok di dalam <pre>.


2. Tempelkan CSS Tombol Salin di Dalam Posting

Letakkan CSS ini di bagian paling atas atau paling bawah posting (tanpa mengubah template).

<style>
.code-wrapper { position: relative; margin: .8rem 0; }
pre { position: relative; padding: 1rem; border-radius: 8px; overflow: auto; }

.copy-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  font-size: 13px;
  border-radius: 6px;
  border: 0;
  cursor: pointer;
  user-select: none;
  background: rgba(31,41,55,0.95);
  color: #fff;
  box-shadow: 0 4px 10px rgba(2,6,23,0.35);
  opacity: 0.95;
  transition: .12s ease;
}
.copy-btn:hover { opacity: 1; }
.copy-btn:active { transform: translateY(1px) scale(.995); }

.copy-btn.copied { background: #10b981; color: white; }

.copy-btn svg { width: 16px; height: 16px; }

@media (prefers-color-scheme: light) {
  .copy-btn { background: rgba(255,255,255,0.95); color: #111; }
  .copy-btn.copied { background: #059669; color: #fff; }
  pre { background: #f8fafc; }
}
</style>

3. Tambahkan Script JavaScript di Postingan Blogger

JavaScript ini bertugas mendeteksi setiap <pre> dan menambahkan tombol salin otomatis.

<script>
(function () {
  function createButton() {
    const btn = document.createElement('button');
    btn.type = 'button';
    btn.className = 'copy-btn';
    btn.innerHTML = `
      <svg viewBox="0 0 24 24" fill="none">
        <path d="M16 21H8a2 2 0 0 1-2-2V7h2v12h8v2z" fill="currentColor" opacity="0.9"></path>
        <path d="M20 5h-8a2 2 0 0 0-2 2v10h2V7h8V5z" fill="currentColor"></path>
      </svg>
      <span class="copy-text">Salin</span>
    `;
    return btn;
  }

  function fallbackCopy(text) {
    return new Promise(function (resolve, reject) {
      try {
        const ta = document.createElement('textarea');
        ta.value = text;
        ta.style.position = 'fixed';
        ta.style.left = '-9999px';
        document.body.appendChild(ta);
        ta.select();
        const ok = document.execCommand('copy');
        document.body.removeChild(ta);
        ok ? resolve() : reject();
      } catch { reject(); }
    });
  }

  function copyText(text) {
    return navigator.clipboard && navigator.clipboard.writeText
      ? navigator.clipboard.writeText(text)
      : fallbackCopy(text);
  }

  function attachButtons() {
    const blocks = document.querySelectorAll('pre');

    blocks.forEach(pre => {
      if (pre.parentNode.classList.contains('code-wrapper')) return;

      const wrapper = document.createElement('div');
      wrapper.className = 'code-wrapper';
      pre.parentNode.insertBefore(wrapper, pre);
      wrapper.appendChild(pre);

      const btn = createButton();
      const label = btn.querySelector('.copy-text');

      btn.addEventListener('click', () => {
        const codeChild = pre.querySelector('code');
        const text = (codeChild ? codeChild.innerText : pre.innerText)
          .replace(/\u00A0/g, ' ');
        
        copyText(text).then(() => {
          btn.classList.add('copied');
          label.innerText = 'Tersalin!';
          setTimeout(() => {
            btn.classList.remove('copied');
            label.innerText = 'Salin';
          }, 1500);
        });
      });

      wrapper.appendChild(btn);
    });
  }

  document.readyState === 'loading'
    ? document.addEventListener('DOMContentLoaded', attachButtons)
    : attachButtons();
})();
</script>

Cara Menggunakan Tombol Salin di Artikel Blogger

Setelah CSS dan script ditempel dalam postingan, sisanya sangat mudah:

  1. Buat posting baru.
  2. Beralih ke mode HTML.
  3. Tempelkan CSS dan script di bagian bawah posting.
  4. Tulis blok kode dengan format:
<pre><code>
git clone https://github.com/user/repo
cd repo
python main.py
</code></pre>

Begitu artikel dipublikasikan, tombol Salin otomatis muncul di pojok kanan atas setiap blok kode.


Contoh Penggunaan Nyata

Berikut contoh bagaimana fitur ini bekerja dalam artikel tutorial:

<pre><code>
pkg update
pkg install git
git clone https://github.com/yourname/project
</code></pre>

Blok ini nanti tampil dengan tombol Salin modern, lengkap dengan ikon dan animasi.

Script Versi Kedua

Script versi kedua ini lebih rapih dan lebih keren (scrollable + draggable optional).

Cara Menggunakan opsi draggable

Jika kamu mau tombol bisa digeser di satu blok kode tertentu, tambahkan atribut data-draggable="true" pada tag <pre>. Contoh:


<pre data-draggable="true"><code>
<Isi_Script_disini>
</code></pre>
Salin kode berikut di akhir postingan kode html


<style>
/* Wrapper dan pre */
.code-wrapper {
  position: relative;
  margin: 0.8rem 0;
}

/* Pre: scrollable, responsif */
pre {
  position: relative;
  padding: 1rem;
  border-radius: 8px;
  overflow: auto;           /* enable scroll both axis if needed */
  max-height: 320px;        /* maksimal tinggi, ubah sesuai kebutuhan */
  white-space: pre;         /* jaga whitespace dan linebreak */
  background: #0f1724;      /* gelap default agar kontras */
  color: #e6eef6;
}

/* kalau mau horizontal wrap, ubah ke pre { white-space: pre-wrap; } */

/* tombol */
.copy-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  font-size: 13px;
  border-radius: 6px;
  border: 0;
  cursor: pointer;
  user-select: none;
  background: rgba(31,41,55,0.95);
  color: #fff;
  box-shadow: 0 4px 10px rgba(2,6,23,0.35);
  z-index: 20;              /* pastikan tombol di atas pre content */
}

/* state sukses */
.copy-btn.copied { background: #10b981; color: white; }

/* ketika draggable diaktifkan, ubah cursor */
.copy-btn.draggable { cursor: move; }

/* batas minimal agar tombol bisa disentuh nyaman di mobile */
@media (max-width: 640px) {
  .copy-btn { padding: 8px 12px; font-size: 14px; }
}
</style>

<script>
(function () {
  // util copy text dengan fallback
  function fallbackCopy(text) {
    return new Promise(function (resolve, reject) {
      try {
        const ta = document.createElement('textarea');
        ta.value = text;
        ta.style.position = 'fixed';
        ta.style.left = '-9999px';
        document.body.appendChild(ta);
        ta.select();
        const ok = document.execCommand('copy');
        document.body.removeChild(ta);
        ok ? resolve() : reject();
      } catch (e) { reject(e); }
    });
  }
  function copyText(text) {
    if (navigator.clipboard && navigator.clipboard.writeText) {
      return navigator.clipboard.writeText(text);
    }
    return fallbackCopy(text);
  }

  // buat tombol
  function createButton() {
    const btn = document.createElement('button');
    btn.type = 'button';
    btn.className = 'copy-btn';
    btn.innerHTML = `
      <svg viewBox="0 0 24 24" width="16" height="16" aria-hidden="true" focusable="false">
        <path d="M16 21H8a2 2 0 0 1-2-2V7h2v12h8v2z" fill="currentColor" opacity="0.9"></path>
        <path d="M20 5h-8a2 2 0 0 0-2 2v10h2V7h8V5z" fill="currentColor"></path>
      </svg><span class="copy-text">Salin</span>`;
    return btn;
  }

  // attach for all pre
  function attachButtons() {
    const blocks = Array.from(document.querySelectorAll('pre'));
    blocks.forEach(pre => {
      if (pre.parentNode && pre.parentNode.classList.contains('code-wrapper')) return;

      // bungkus pre
      const wrapper = document.createElement('div');
      wrapper.className = 'code-wrapper';
      // default: draggable off; enable with attribute data-draggable="true" on <pre>
      wrapper.setAttribute('data-draggable', pre.getAttribute('data-draggable') || 'false');

      pre.parentNode.insertBefore(wrapper, pre);
      wrapper.appendChild(pre);

      // buat tombol
      const btn = createButton();
      wrapper.appendChild(btn);

      const label = btn.querySelector('.copy-text');

      // klik salin
      btn.addEventListener('click', () => {
        const codeChild = pre.querySelector('code');
        const text = (codeChild ? codeChild.innerText : pre.innerText).replace(/\u00A0/g, ' ');
        copyText(text).then(() => {
          btn.classList.add('copied');
          label.innerText = 'Tersalin!';
          setTimeout(() => { btn.classList.remove('copied'); label.innerText = 'Salin'; }, 1400);
        }).catch(() => {
          label.innerText = 'Gagal';
          setTimeout(() => label.innerText = 'Salin', 1200);
        });
      });

      // ========== Draggable logic (optional) ==========
      // aktifkan jika wrapper.dataset.draggable === 'true'
      if (wrapper.dataset.draggable === 'true') {
        makeDraggable(btn, wrapper, pre);
        btn.classList.add('draggable');
        btn.setAttribute('aria-grabbed', 'false');
      }
      // =================================================
    });
  }

  // fungsi buat draggable dengan batas di dalam wrapper
  function makeDraggable(btn, wrapper, pre) {
    let dragging = false;
    let startX = 0, startY = 0;
    // posisi relatif tombol ke wrapper (px)
    // default: top-right (8px/8px)
    let pos = { left: null, top: 8, right: 8 }; // use either left or right

    // helper: set posisi tombol memakai left/top atau right/top
    function applyPos() {
      if (pos.left !== null) {
        btn.style.left = pos.left + 'px';
        btn.style.right = 'auto';
      } else {
        btn.style.right = pos.right + 'px';
        btn.style.left = 'auto';
      }
      btn.style.top = pos.top + 'px';
    }

    applyPos();

    // support mouse
    function onMouseDown(e) {
      e.preventDefault();
      dragging = true;
      startX = e.clientX;
      startY = e.clientY;
      btn.setAttribute('aria-grabbed', 'true');
      document.addEventListener('mousemove', onMouseMove);
      document.addEventListener('mouseup', onMouseUp);
    }
    function onMouseMove(e) {
      if (!dragging) return;
      const dx = e.clientX - startX;
      const dy = e.clientY - startY;
      startX = e.clientX; startY = e.clientY;

      // compute new left if current uses left, else convert
      const rect = wrapper.getBoundingClientRect();
      const btnRect = btn.getBoundingClientRect();

      // determine current left
      let curLeft = (pos.left !== null) ? pos.left : (rect.width - btnRect.width - pos.right);
      let curTop = pos.top;

      curLeft += dx;
      curTop += dy;

      // clamp within wrapper
      curLeft = Math.max(4, Math.min(curLeft, rect.width - btnRect.width - 4));
      curTop = Math.max(4, Math.min(curTop, rect.height - btnRect.height - 4));

      pos.left = Math.round(curLeft);
      pos.top = Math.round(curTop);
      pos.right = null;

      applyPos();
    }
    function onMouseUp() {
      dragging = false;
      btn.setAttribute('aria-grabbed', 'false');
      document.removeEventListener('mousemove', onMouseMove);
      document.removeEventListener('mouseup', onMouseUp);
    }

    // support touch
    function onTouchStart(e) {
      const t = e.touches[0];
      dragging = true;
      startX = t.clientX;
      startY = t.clientY;
      btn.setAttribute('aria-grabbed', 'true');
      document.addEventListener('touchmove', onTouchMove, {passive:false});
      document.addEventListener('touchend', onTouchEnd);
    }
    function onTouchMove(e) {
      if (!dragging) return;
      e.preventDefault();
      const t = e.touches[0];
      const dx = t.clientX - startX;
      const dy = t.clientY - startY;
      startX = t.clientX; startY = t.clientY;

      const rect = wrapper.getBoundingClientRect();
      const btnRect = btn.getBoundingClientRect();

      let curLeft = (pos.left !== null) ? pos.left : (rect.width - btnRect.width - pos.right);
      let curTop = pos.top;

      curLeft += dx;
      curTop += dy;

      curLeft = Math.max(4, Math.min(curLeft, rect.width - btnRect.width - 4));
      curTop = Math.max(4, Math.min(curTop, rect.height - btnRect.height - 4));

      pos.left = Math.round(curLeft);
      pos.top = Math.round(curTop);
      pos.right = null;

      applyPos();
    }
    function onTouchEnd() {
      dragging = false;
      btn.setAttribute('aria-grabbed', 'false');
      document.removeEventListener('touchmove', onTouchMove);
      document.removeEventListener('touchend', onTouchEnd);
    }

    // attach listeners
    btn.addEventListener('mousedown', onMouseDown);
    btn.addEventListener('touchstart', onTouchStart, {passive:false});

    // double click to reset position to default (top-right)
    btn.addEventListener('dblclick', function () {
      pos.left = null; pos.top = 8; pos.right = 8;
      applyPos();
    });
  }

  // init
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', function () {
      attachButtons();
      setTimeout(attachButtons, 300);
    });
  } else {
    attachButtons();
    setTimeout(attachButtons, 300);
  }

  // expose function so kamu bisa panggil manual jika perlu
  window.__attachBloggerCopyButtons = attachButtons;
})();
</script>


Tabel Keunggulan vs. Cara Manual

Cara Efisiensi Tampilan Kompatibilitas Kekurangan
Script otomatis (tutorial ini) Sangat tinggi Modern & rapi Semua template Harus ditempel tiap posting
Edit template Tinggi Stabil & global Semua template Perlu ubah file HTML theme
Copy manual (tanpa tombol) Rendah Tidak menarik Semua template Tidak ada tombol, tidak profesional

Tips Optimasi Penggunaan Tombol Salin

Agar fitur berjalan maksimal, perhatikan hal berikut:

1. Gunakan Tag <pre><code> Secara Konsisten

Ini memudahkan script mengenali blok kode.

2. Hindari Menempel Script di Editor “Compose”

Selalu gunakan mode HTML.

3. Jangan Letakkan Script di Tengah Teks

Sebaiknya di akhir posting agar tidak mengganggu format paragraf.

4. Uji di Desktop & Mobile

Beberapa template memiliki CSS bawaan yang perlu kamu sesuaikan.


Pertanyaan yang Sering Ditanyakan (FAQ)

1. Apakah tombol salin ini berfungsi di semua template Blogger?

Ya. Script ini bekerja di semua template, dari bawaan sampai premium seperti Median UI, Fletro, dan Templateify.

2. Apakah perlu mengedit template HTML Blogger?

Tidak. Semua script ditempel langsung di dalam posting.

3. Apakah aman untuk SEO?

Aman. Script tidak mempengaruhi struktur halaman, loading, maupun metadata.

4. Apakah tombol salin akan muncul otomatis setiap posting baru?

Tidak, kecuali kamu memasangnya di template.
Jika hanya ditempel di posting, kamu harus memasangnya ulang di setiap artikel.

5. Apakah script ini kompatibel dengan highlight kode pihak ketiga?

Ya. Script tidak mengubah format syntax highlight apapun.

6. Bagaimana jika beberapa template memblok JavaScript di postingan?

Jika itu terjadi, kamu butuh versi inline-safe yang di-encode. Script tersebut juga bisa saya buat.


Kesimpulan

Menambahkan tombol salin kode otomatis ala GitHub ke Blogger adalah cara sederhana namun efektif untuk meningkatkan kenyamanan pembaca dan membuat blog terlihat jauh lebih profesional. Dengan menggunakan CSS dan JavaScript ringan yang ditempel langsung ke postingan, kamu bisa menghadirkan pengalaman modern tanpa perlu mengedit template blog.

Script ini bekerja di semua template, mudah dipasang, aman untuk SEO, dan sangat cocok untuk blog tutorial, coding, Termux, atau panduan teknis lainnya.
Jika kamu ingin tingkat profesionalitas blog meningkat, fitur ini adalah salah satu langkah paling mudah namun berdampak besar.


Posting Komentar untuk "Cara Membuat Tombol Salin Kode Otomatis di Blogger (Ala GitHub) Tanpa Edit Template"