Catégories
Astuces et Design

Passer aux webmentions avec NextJS (ou pas)

Webmention est une recommandation du W3C publiée pour la dernière fois le 12 janvier 2017. Et qu'est-ce qu'un Webmention exactement? Il est décrit comme…

(…) Un moyen simple de notifier n'importe quelle URL lorsque vous la mentionnez sur votre site. Du point de vue du destinataire, c'est un moyen de demander des notifications lorsque d'autres sites le mentionnent.

En un mot, c'est une façon de faire savoir à un site Web qu'il a été mentionné quelque part, par quelqu'un, d'une manière ou d'une autre. La spécification Webmention le décrit également comme un moyen pour un site Web de faire savoir aux autres qu'il les a cités. Ce que cela signifie essentiellement, c'est que votre site Web est un canal de médias sociaux actif, canalisant la communication à partir d'autres canaux (par exemple Twitter, Instagram, Mastodon, Facebook, etc.).

Comment un site met-il en œuvre des Webmentions? Dans certains cas, comme WordPress, c'est aussi trivial que d'installer quelques plugins. D'autres cas ne sont peut-être pas aussi simples, mais c'est quand même assez simple. En fait, faisons-le maintenant!

Voici notre plan

  1. Déclarez un point de terminaison pour recevoir des Webmentions
  2. Traitez les interactions des médias sociaux avec Webmentions
  3. Obtenez ces mentions dans un site Web / une application
  4. Définissez les Webmentions sortantes

Heureusement pour nous, il existe des services qui rendent les choses extrêmement simples. Eh bien, sauf ce troisième point, mais bon, ce n'est pas si mal et je vais vous expliquer comment je l'ai fait sur mon propre site atila.io.

Mon site est un blog côté serveur pré-rendu et écrit avec NextJS. J'ai choisi de faire des demandes Webmention côté client; par conséquent, il fonctionnera facilement dans n'importe quelle autre application React et avec très peu de refactoring dans toute autre application JavaScript.

Étape 1: déclarer un point de terminaison pour recevoir des Webmentions

Afin d'avoir un point de terminaison que nous pouvons utiliser pour accepter les Webmentions, nous devons soit écrire le script et l'ajouter à notre propre serveur, soit utiliser un service tel que Webmention.io (ce que j'ai fait).

Webmention.io est gratuit et il vous suffit de confirmer la propriété du domaine que vous enregistrez. La vérification peut se produire de plusieurs façons. Je l'ai fait en ajoutant un rel="me" attribuer à un lien de mon site Web vers mes profils de médias sociaux. Cela ne prend qu'un seul lien, mais je suis allé de l'avant et l'ai fait pour tous mes comptes.


  @AtilaFassina

En vérifiant de cette façon, nous devons également nous assurer qu'il existe un lien pointant vers notre site Web dans ce profil Twitter. Une fois que nous avons fait cela, nous pouvons retourner sur Webmention.io et ajouter l'URL.

Cela nous donne un point de terminaison pour accepter les Webmentions! Tout ce que nous devons faire maintenant, c'est le câbler balises dans le de nos pages Web afin de recueillir ces mentions.


  
  
  

N'oubliez pas de remplacer {user} avec votre nom d'utilisateur Webmention.io.

Étape 2: Transformez les interactions des médias sociaux en Webmentions

Nous sommes prêts pour que les Webmentions commencent à couler! Mais attendez, nous avons un petit problème: personne ne les utilise réellement. Je veux dire, je le fais, vous le faites, Max Böck Est-ce que, Swyx fait, et… c'est tout. Donc, maintenant, nous devons commencer à convertir toutes ces interactions juteuses des médias sociaux en Webmentions.

Et devine quoi? Il y a un service gratuit génial pour ça. Juste avertissement cependant: vous feriez mieux de commencer à aimer IndieWeb parce que nous sommes sur le point de tout faire.

Bridgy connecte tous nos contenus syndiqués et les convertit en Webmentions appropriées afin que nous puissions les consommer. Avec un SSO, nous pouvons aligner chacun de nos profils, un par un.

Étape 3: Obtenez ces mentions dans un site Web / une application

Maintenant, c'est à notre tour de faire de gros efforts. Bien sûr, les services tiers peuvent gérer toutes nos données, mais c'est à nous de les utiliser et de les afficher.

Nous allons diviser cela en quelques étapes. Tout d'abord, nous obtiendrons le nombre de Webmentions. De là, nous allons chercher les mentions elles-mêmes. Ensuite, nous raccorderons ces données à NextJS (mais ce n'est pas obligatoire) et les afficherons.

Obtenez le nombre de mentions

type TMentionsCountResponse = {
  count: number
  type: {
    like: number
    mention: number
    reply: number
    repost: number
  }
}

C'est un exemple d'un objet que nous récupérons du point de terminaison Webmention.io. J'ai formaté un peu la réponse pour mieux répondre à nos besoins. Je vais vous expliquer comment je l'ai fait dans quelques instants, mais voici l'objet que nous obtiendrons:

type TMentionsCount = {
  mentions: number
  likes: number
  total: number
}

Le point final est situé à:

https://webmention.io/api/count.json?target=${post_url}

La requête ne pourra pas échouer sans elle, mais les données ne viendront pas non plus. Tous les deux Max Böck et Swyx combinez les likes avec les reposts et les mentions avec les réponses. Sur Twitter, ils sont analogues.

const getMentionsCount = async (postURL: string): TMentionsCount => {
  const resp = await fetch(
    `https://webmention.io/api/count.json?target=${postURL}/`
  )
  const { type, count } = await resp.json()


  return {
    likes: type.like + type.repost,
    mentions: type.mention + type.reply,
    total: count,
  }
}

Obtenez les mentions réelles

Avant d'accéder à la réponse, veuillez noter que la réponse est paginée, où le point de terminaison accepte trois paramètres dans la requête:

  • page: la page demandée
  • per-page: le nombre de mentions à afficher sur la page
  • target: l'URL où les Webmentions sont récupérées

Une fois que nous avons frappé https://webmention.io/api/mentions et passer ces paramètres, la réponse réussie sera un objet avec une seule clé links qui est un array des mentions correspondant au type ci-dessous:

type TMention = {
  source: string
  verified: boolean
  verified_date: string // date string
  id: number
  private: boolean
  data: {
    author: {
      name: string
      url: string
      photo: string // url, hosted in webmention.io
    }
    url: string
    name: string
    content: string // encoded HTML
    published: string // date string
    published_ts: number // ms
  }
  activity: {
    type: 'link' | 'reply' | 'repost' | 'like'
    sentence: string // pure text, shortened
    sentence_html: string // encoded html
  }
  target: string
}

Les données ci-dessus sont plus que suffisantes pour montrer un commentaire-comme liste des sections sur notre site. Voici à quoi ressemble la demande de récupération dans TypeScript:

const getMentions = async (
  page: string,
  postsPerPage: number,
  postURL: string
): { links: TWebMention() } => {
  const resp = await fetch(
    `https://webmention.io/api/mentions?page=${page}&per-page=${postsPerPage}&target=${postURL}`
  )
  const list = await resp.json()
  return list.links
}

Accrochez le tout dans NextJS

Nous allons travailler dans NextJS pendant un moment. Tout va bien si vous n'utilisez pas NextJS ou même si vous avez une application Web. Nous avons déjà toutes les données, donc ceux d'entre vous qui ne travaillent pas dans NextJS peuvent simplement passer à l'étape 4. Le reste d'entre nous vous y rencontrera.

Depuis la version 9.3.0, NextJS dispose de trois méthodes différentes pour récupérer les données:

  1. getStaticProps: récupère les données sur le temps de construction
  2. getStaticPaths: spécifie les itinéraires dynamiques à pré-rendre en fonction des données extraites
  3. getServerSideProps: récupère les données sur chaque demande

Le moment est venu de décider à quel moment nous ferons la première demande de recherche de mentions. Nous pouvons pré-rendre les données sur le serveur avec le premier lot de mentions, ou nous pouvons faire le tout côté client. J'ai opté pour le côté client.

Si vous optez également pour le côté client, je vous recommande d'utiliser SWR. Il s'agit d'un crochet personnalisé construit par l'équipe Vercel qui fournit de bons états de mise en cache, d'erreur et de chargement – il prend même en charge React.Suspense.

Afficher le nombre de Webmentions

De nombreux blogs affichent le nombre de commentaires sur un article à deux endroits: en haut d'un article de blog (comme celui-ci) et en bas, juste au-dessus d'une liste de commentaires. Suivons le même schéma pour les Webmentions.

Tout d'abord, créons un composant pour le décompte:

const MentionsCounter = ({ postUrl }) => {
  const { t } = useTranslation()
  // Setting a default value for `data` because I don't want a loading state
  // otherwise you could set: if(!data) return 
loading...
  const { data = {}, error } = useSWR(postUrl, getMentionsCount) 
   if (error) {     return {t('common:errorWebmentions')}   } 
   // The default values cover the loading state   const { likes = '-', mentions = '-' } = data 
   return (          
  •                 {Number.isNaN(likes) ? 0 : likes}      
  •      
  •         {' '}         {Number.isNaN(mentions) ? 0 : mentions}      
  •    
      ) }

    Grâce à SWR, même si nous utilisons deux instances de la WebmentionsCounter composant, une seule demande est faite et ils bénéficient tous les deux du même cache.

    N'hésitez pas à jeter un œil à mon code source pour voir ce qui se passe:

    Afficher les mentions

    Maintenant que nous avons placé le composant, il est temps de faire couler tout ce jus social!

    Au moment de la rédaction de cet article, useSWRpages n'est pas documenté. Ajoutez à cela le fait que le point de terminaison webmention.io n'offre pas d'informations de collecte sur une réponse (c'est-à-dire pas de décalage ou de nombre total de pages), je n'ai pas pu trouver de moyen d'utiliser SWR ici.

    Donc, mon implémentation actuelle utilise un état pour conserver la page actuelle stockée, un autre état pour gérer les mentions array, et useEffect pour traiter la demande. Le bouton «Charger plus» est désactivé une fois que la dernière demande ramène un tableau vide.

    const Webmentions = ({ postUrl }) => {
      const { t } = useTranslation()
      const (page, setPage) = useState(0)
      const (mentions, addMentions) = useState(())
    

      useEffect(() => {
        const fetchMentions = async () => {
          const olderMentions = await getMentions(page, 50, postUrl)
          addMentions((mentions) => (...mentions, ...olderMentions))
        }
        fetchMentions()
      }, (page))
    

      return (
        <>
          {mentions.map((mention, index) => (
            
              
              
                
              
            
          ))}
          
          {mentions.length > 0 && (
             {
              setPage(page + 1)
            }}
            >
            {t('common:more')}
          
        )}
        
      )
    }

    Le code est simplifié pour permettre de se concentrer sur le sujet de cet article. Encore une fois, n'hésitez pas à jeter un œil à la mise en œuvre complète:

    Étape 4: Gestion des mentions sortantes

    Grâce à Remy Sharp, la gestion des mentions sortantes d'un site Web à d'autres est assez simple et offre une option pour chaque cas d'utilisation ou préférence possible.

    Le moyen le plus rapide et le plus simple consiste à se rendre sur Webmention.app, à obtenir un jeton d'API et à configurer un hook Web. Maintenant, si vous avez un flux RSS en place, la même chose est tout aussi simple avec une applet IFTT, ou même un crochet de déploiement.

    Si vous préférez éviter d'utiliser encore un autre service tiers pour cette fonctionnalité (que j'ai totalement), Remy a open source un package CLI appelé wm qui peut être exécuté comme un script de post-construction.

    Mais cela ne suffit pas pour gérer les mentions sortantes. Pour que nos mentions incluent plus que l'URL d'origine, nous devons ajouter des microformats à nos informations. Les microformats sont essentiels, car il s'agit d'un moyen normalisé pour les sites de distribuer le contenu d'une manière que les sites Webmention peuvent utiliser.

    À leur base, les microformats sont une sorte de basé sur la classe des annotations dans le balisage qui donnent une signification sémantique supplémentaire à chaque pièce. Dans le cas d'un article de blog, nous utiliserons deux types de microformats:

    • h-entry: l'entrée de poste
    • h-card: l'auteur de l'article

    La plupart des informations requises pour h-entry est généralement dans l'en-tête de la page, donc le composant d'en-tête peut finir par ressembler à ceci:

           

        Webmentions with NextJS  

    Et c'est tout. Si vous écrivez en JSX, pensez à remplacer class avec className, cette datetime est camelCase (dateTime), et que vous pouvez utiliser le nouveau Date('2020-04-22').toISOString() une fonction.

    C'est assez similaire pour h-card. Dans la plupart des cas (comme le mien), les informations sur l'auteur se trouvent sous l'article. Voici à quoi ressemble le pied de page de ma page:

    Atila Fassina Photographie de l'auteur: Atila Fassina

    Maintenant, chaque fois que nous envoyons une mention sortante de ce billet de blog, il affichera toutes les informations à quiconque les recevra.

    Emballer

    J'espère que ce message vous a aidé à en savoir plus sur Webmentions (ou même sur IndieWeb dans son ensemble), et peut-être même vous a aidé à ajouter cette fonctionnalité à votre propre site Web ou application. Si c'est le cas, pensez à partager ce message avec votre réseau. Je serai super reconnaissant! 😉

    Références

    Lectures complémentaires

    Laisser un commentaire

    Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *