Aller au contenu

Comment créer un plugin Rehype qui transforme les liens GitHub en badges attrayants

Cette traduction a été générée par une IA générative à l'aide de la traduction continue Action. →

A beautiful cover image with the text "Badge Links"

Récemment, j’ai ajouté une petite fonctionnalité sympa à ce blog, que vous avez peut-être remarquée en tant que lecteur régulier. Ce n’est rien de gigantesque, mais cela donne à chaque blog cette petite touche charmante que j’ai recherchée pendant longtemps. Je parle (ou plutôt j’écris) de tous ces badges verts avec des photos de profil que vous pouvez également voir dans ce blog.

L’inspiration pour les créer vient de nul autre qu’antfuAntfu lui-même, puisqu’il affiche ces badges partout sur son site web (au moment de cette rédaction).

Au départ, je pensais qu’il faudrait une longue et fastidieuse session de programmation pour atteindre la même beauté visuelle. Cependant, après quelques sessions de Vibe Coding - comme Andrej Karpathy a inventé le terme - j’ai rapidement réalisé que ces badges n’étaient qu’à un petit rehypejsplugin rehype d’existence.

Voici tout le code derrière le plugin rehype :

src/lib/rehype-github-badge-links.ts
import { h } from "hastscript";
import { visit } from "unist-util-visit";
export default function rehypeGitHubBadgeLinks() {
return (tree) => {
visit(tree, "element", (node) => {
if (
node.tagName === "a" &&
typeof node.properties?.href === "string" &&
node.properties.href.startsWith("https://github.com/")
) {
const match = node.properties.href.match(
/^https:\/\/github\.com\/([\w-]+)\/?$/
);
if (match) {
const username = match[1];
// Add GitHub badge class
node.properties.className = (node.properties.className || []).concat(
"gh-badge"
);
// Build avatar image
const avatarImg = h("img", {
src: `https://github.com/${username}.png`,
alt: username,
});
// Prepend avatar image to original children
node.children.unshift(avatarImg);
}
}
});
};
}

En gros, tout ce que fait ce plugin, c’est parcourir le HTML à la recherche de liens qui font référence à un profil GitHub. Si l’un d’eux est trouvé, il ajoute une balise <img> avant le contenu texte avec la photo de profil de l’utilisateur ou de l’organisation GitHub. Cela est possible de manière très cohérente grâce à la fonctionnalité de GitHub qui permet d’obtenir la photo comme ressource derrière le lien du profil suivi de .png. Lisez-en plus à ce sujet dans cet article génial sur dev.to.

Avec un peu de style supplémentaire, cela a un rendu vraiment mignon à mon avis. Veuillez noter que comme ceci est une page Starlight Starlight , j’utilise des variables CSS disponibles, comme dans la ligne quatre :

src/styles/custom.css
.gh-badge {
display: inline-flex;
align-items: center;
background-color: var(--sl-color-accent-low);
border-radius: 9999px;
padding: 0em 0.5em 0 0.3em;
font-size: 0.9em;
text-decoration: none;
color: inherit;
font-weight: 500;
transition: background-color 0.2s ease;
transform: translateY(0.29rem);
border: 1px solid var(--sl-color-accent);
}
.gh-badge:hover {
background-color: var(--sl-color-accent);
}
.gh-badge img {
border-radius: 9999px;
width: 1.3em;
height: 1.3em;
}

Pour tout assembler, disons, par exemple, dans un site Astro, vous devez simplement ajouter le plugin rehype à la configuration comme ceci :

astro.config.mjs
import { defineConfig } from 'astro/config';
import rehypeGitHubBadgeLinks from "./src/lib/rehype-github-badge-links";
export default defineConfig({
markdown: {
rehypePlugins: [rehypeGitHubBadgeLinks]
}
})

Lisez-en davantage sur l’injection des plugins rehype dans Astro dans leur référence de configuration.

N’oubliez pas d’ajouter le CSS de manière similaire, en fonction de votre framework - dans Starlight, vous pouvez configurer des styles CSS globaux personnalisés en suivant ces instructions - et vous pouvez également admirer vos propres liens en badge. N’hésitez pas à partager cet article avec toute personne que vous souhaitez convaincre d’utiliser ces fonctionnalités.

✨ Point bonus

Si vous souhaitez utiliser un tel badge pour d’autres liens également, je vous recommande de créer un petit composant Astro comme celui-ci :

src/components/BadgeLink.astro
---
const { href, src, text, className = "gh-badge" } = Astro.props;
---
<a href={href} class={className}>
<img src={src} alt={text} />
{text}
</a>

Assurez-vous simplement que le CSS est global (ou scopé dans le composant ci-dessus) et il est prêt à être utilisé :

import BadgeLink from "../components/BadgeLink.astro";
<BadgeLink
href="https://github.com/withastro/starlight"
src="/starlight.png"
text="Starlight"
/>