/ Blog/ #astro

Cara Menerapkan rehype-external-link di Astro

Tayang pada 14 Desember 2024

Dapat dibaca selama 4 menit

Kalian sedang ingin menerapkan attribut tambahan ke tag <a> dan mengikuti panduan dari astro berikut?

https://docs.astro.build/en/recipes/external-links/

Karena yang diharapkan adalah dengan menuliskan:

[Link ini harusnya buka tab baru](https://examples.com)

Pada markdown, teks pada bagian akhir harusnya terdapat simbol 🔗, sesuai dengan maksud instruksi diatas.

Sekedar cerita, penulis mengikuti instruksinya, tidak berhasil. Sempat mengulik Discord, membaca ulang dokumentasi, bahkan sampai tanya ChatGPT (Sudah pesimis, jawaban tidak akan diperoleh) tetap saja nihil, sehingga membuat instruksi pada dokumentasi diatas terlihat konyol dan tidak berguna dimata penulis.

Tetapi ada sesuatu yang menarik dari dokumentasi Astro, ia menampilkan informasi tentang MDX integration, dari kalimat yang penulis baca terlihat seperti mendorong penggunaan mdx.

MDX sendiri adalah format file markdown yang dapat memungkinkan kita menuliskan sintak javascript, variable, dan kemampuan JSX lainnya (maka dari itu akhirannya X, entahlah… semacam Xtra mungkin?), sangat populer dan powerful, cek dokumentasi untuk melihat apa saja yang bisa dilakukan mdx di Astro.

Penulis jujur sering menggunakan .md, karena dengannya penulis bisa menampilkan konten yang diinginkan, tidak ingin macam-macam, tetapi karena penulis ingin menerapkan tag a yang bisa ada simbol 🔗 dibelakang teksnya (bahkan ingin semuanya membuka tab baru ketika diklik), maka penulis ubah format file dari yang awalnya .md menjadi .mdx, voila! ternyata work.

Sebelum mengubah formatnya, lakukan integrasi MDX terlebih dahulu ke project Astro, cek petunjuk integrasinya disini dan selanjutnya kamu dapat menerapkan fitur-fitur markdown keren lainnya.

Setelahnya, penulis bisa menerapkan rehype-external-plugin dengan konfigurasi berikut pada astro.config.mjs:

export default defineConfig({
  //... code lainnya
  integrations: [vue(), mdx()], //pastikan ada mdx() disini
  markdown: {
    // ...
    rehypePlugins: [
      [
        rehypeExternalLinks,
        {
          target: '_blank',
          rel: ['nofollow', 'noreferer', 'noopener'],
          content: { type: 'text', value: ' 🔗' },
        },
      ]
    ]
  }
  //... code lainnya? mungkin
});

Dengan begini, penulis bisa menerapkan fungsi buka tab baru ketika link tersebut diawali dengan “http” atau “https” pada awalan href nya (default dari properti protocols adalah ["http", "https"], kalian bisa aplikasikan perilaku tag a berdasarkan definisi protokol yang disebutkan di atribut hrefnya dengan properti tersebut).

Sehingga jika mengetik:

[Harusnya buka tab baru]('https://example.com')

otomatis hasil parsenya menjadi:

<a href="https://example.com" rel="nofollow noreferer noopener" target="_blank">Harusnya buka tab baru</a>

Cek dengan menggunakan inspect tools.

Tunggu…

Tetapi bagaimana jika ingin semua <a> tag mempunyai atribut dan nilai yang diatas?

Praktik terbaiknya adalah penerapan diatas tidak dilakukan jika nilai href berawalan / karena dipastikan mengakses path origin website tersebut, jika terdapat awalan http atau https dipastikan adalah membuka halaman web lain dan penerapan diatas diperlukan, alasan penerapan attribut dan kaitannya terhadap nilai href sebenarnya terkait dengan keamanan, kamu dapat kamu baca-baca diskusi ini.

Baik, jika kamu ingin menerapkannya ke semua tag <a>, kamu bisa memanfaatkan function visit() yang dapat diperoleh dari package unist-util-visit, install package nya di project Astro kamu.

Setelah itu, terapkan code berikut ke astro.config.mjs nya, contoh berikut adalah menerapkan konfigurasi yang sama dengan diatas, tapi dengan cara berbeda:

export default defineConfig({
  //... code lainnya
  integrations: [vue(), mdx()], //pastikan ada mdx() disini
  markdown: {
    // ...
    rehypePlugins: [
      () => (tree) => {
        visit(tree, 'element', (node) => {
          if (node.tagName === 'a' && node.properties) {
            node.properties.target = '_blank';
            node.properties.rel = ['nofollow', 'noreferer', 'noopener'];
            if (Array.isArray(node.children)) {
              node.children.push({
                type: 'text',
                value: ' 🔗',
              });
            }
          }
        })
      }
    ]
  }
  //... code lainnya? mungkin
});

Kamu bisa lihat, kita memanfaatkan function visit untuk menelusuri ‘element’ yang ada pada tree (tree ini adalah seisi konten markdown yang sudah diparse ke DOM), dan mengecek apakah node yang ditelusuri adalah tag <a> dan memiliki properti-properti (maksudnya adalah atribut), jika iya, maka terapkan atribut dan nilai kepadanya dengan object literal.

silahkan kamu atur-atur di dalam block conditional pertama agar menyesuaikan dengan yang kamu inginkan.

Pada dokumentasi Astro tidak menjelaskan secara gamblang apakah ada syarat khusus, tapi tetap saja, mandiri untuk mencari tahu, mereka sudah memberikan banyak informasi, terkadang ada hal yang secara aneh tidak disadari, mungkin butuh istirahat sejenak.

Semoga membantu 🔥.