Salut. SEO technique ici. J'ai commencé à travailler avec Angular en 2015 avec une refonte du site de commerce électronique. J'ai beaucoup cassé mais réparé plus.

Si vous débutez dans le référencement SEO pour JavaScript ou si vous avez besoin d’informations supplémentaires sur les concepts référencés ici, le logiciel de Rachel Costello Comprendre les bases de JavaScript: votre feuille de triche est une excellente ressource à avoir sous la main.

Le plus important: ne paniquez pas. Vous n’avez pas besoin d’être un expert pour chaque technologie mentionnée.

Votre capacité à obtenir l'adhésion des parties prenantes et à communiquer avec les développeurs sera probablement votre plus grande force. Nous fournirons des ressources supplémentaires pour vous aider.

Commençons par les bases

Les sites Web sont faits de code. Le code est écrit en langues. Trois langues constituent la majorité des sites Web.

Guide SEO pour Angular: Tout ce que vous devez savoir

HTML crée du contenu. CSS crée la mise en page, la conception et les effets visuels.

Ces deux langues peuvent créer des pages plates esthétiques, fonctionnelles et fonctionnelles, mais elles sont surtout ennuyeuses.

Entrez JavaScript (JS), une version Web du code de programmation.

Avec JavaScript, les sites Web peuvent personnaliser les expériences utilisateur interactives. Les gens vont sur des sites intéressants. JS crée des sites attrayants.

Angular est une évolution de JavaScript

Angular est un moyen de développer JS pour construire des sites. Avec Angular, une douzaine de lignes de HTML à plat envoyées par votre serveur déploient et exécutent des expériences utilisateur interactives personnalisées.

Guide SEO pour Angular: Tout ce que vous devez savoir

Près de 1 million de sites sont construits avec elle. Les taux d'adoption augmentent rapidement.

Si vous n’avez pas travaillé sur un framework JavaScript angulaire ou autre, vous aurez probablement bientôt.

Pour qu'un moteur de recherche comprenne les sites angulaires, ils doivent rendre JavaScript

Pour que les moteurs de recherche puissent expérimenter le contenu angulaire, ils doivent exécuter JavaScript. De nombreux moteurs de recherche ne peuvent pas rendre JavaScript.

Ne paniquez pas.

Si votre marché est principalement dominé par Baidu, Yandex, Naver ou un autre moteur de recherche sans rendu, passez à la section du rendu.

Guide SEO pour Angular: Tout ce que vous devez savoir

Googlebot <3s JavaScript

Pas vraiment. Ils adorent ça parce que les humains adorent les expériences interactives riches!

… et parce que 95% des sites l'utilisent.

L'indexation du contenu généré par JS est une bonne affaire lorsque votre modèle repose sur l'index de contenu Web le plus fiable.

Cela ne veut pas dire que c’était une relation historiquement parfaite. Les professionnels du référencement ont croupi devant les capacités de Googlebot et son engagement à explorer JS.

Le manque de clarté a conduit à des avertissements selon lesquels Angular pourrait tuer votre référencement.

À I / O 2018, l’équipe Webmaster a parlé ouvertement des problèmes rencontrés par Google lors de l’indexation du contenu Angular et d’autres contenus JS. Certains pros de la SEO étaient en colère, d'autres en colère, d'autres… excessivement excités?

Guide SEO pour Angular: Tout ce que vous devez savoir

Je maintiens cette excitation. La recherche était représentée. (L’année précédente, j’ai rencontré quelques réponses confuses quant à la présence de personnes travaillant dans le domaine du référencement lors d’une conférence de développeurs. Arrow au cœur du cœur technique du référencement.)

Les développeurs étaient excité.

Ensuite, John Mueller et Tom Greenaway ont pris la parole pour s'attaquer à une idée fausse majeure de la communauté de la recherche: comment fonctionne la recherche.

Crawl, Index, Rank – Facile comme un, trois, quatre!

Jusqu'à la conférence des développeurs de Google 2018, les professionnels du référencement travaillaient sur le principe de base selon lequel le processus de Googlebot fonctionnait en trois étapes: analyse, index et classement.

Même jusqu'en avril 2019, les ressources propres de Google reflétaient un processus simple en trois étapes.

Guide SEO pour Angular: Tout ce que vous devez savoir

Ce processus simplifié cache un mélange hétéroclite d’hypothèses cachées:

  • Googlebot rend JS au fur et à mesure de son exploration.
  • L'indexation est basée sur le contenu rendu.
  • Ces actions se produisent simultanément dans une seule séquence.
  • Googlebot est magique et fait toutes les choses instantanément!

Voici le problème. Nous avons négligé le rendu.

Le rendu est le processus par lequel les scripts appelés dans l'analyse HTML initiale sont récupérés et exécutés.

Nous appelons la sortie de l'analyse HTML initiale et JavaScript le DOM (modèle d'objet document).

Guide SEO pour Angular: Tout ce que vous devez savoir

Si un site utilise JavaScript, le code HTML sera différent du DOM.

HTML initial (avant l'exécution de JavaScript)

Guide SEO pour Angular: Tout ce que vous devez savoir

DOM (après l'exécution de JavaScript)

Guide SEO pour Angular: Tout ce que vous devez savoir

Les deux vues d'une même page peuvent être très différentes. Le code HTML initial ne comptait que 16 lignes. Après l'exécution de JavaScript, le DOM est plein de contenu riche.

Vous pouvez voir l'analyse HTML initiale en affichant une source de page. Pour voir le DOM, ouvrez Outils de développement dans votre navigateur et cliquez sur Inspecter. Vous pouvez également utiliser le raccourci clavier Cmd + shift + I.

Deux vagues d'indexation

En raison des hypothèses de processus en trois étapes et de leur impact sur les performances organiques, l’équipe Webmaster de Google a expliqué qu’il existait deux phases d’indexation.

La première vague indexe une page basée uniquement sur le code HTML initial (a.k.a., view page source).

Les seconds index basés sur le DOM.

Guide SEO pour Angular: Tout ce que vous devez savoir

Googlebot veut aimer JavaScript, mais il a parfois besoin de votre aide pour le comprendre

JavaScript est le ressource la plus chère sur votre site.

1 Mo de script peut prendre 5 secondes avec une connexion 3G. 1,5 Mo de page peuvent coûter 0,19 USD à charger. (Non, vraiment. Testez vos pages à Combien coûte mon site?)

Pour Googlebot, ce coût vient en tant que CPU pour exécuter le script. Avec autant de JavaScript sur le Web, une file d’attente littérale s’est formée pour le moteur de rendu de Googlebot.

Cela signifie que le contenu généré par JavaScript est découvert par Googlebot uniquement lorsque les ressources sont disponibles.

Guide SEO pour Angular: Tout ce que vous devez savoir

La dette technique de Googlebot pour le référencement angulaire difficile

Une partie de la vie numérique consiste à travailler avec ce que vous avez. Nous prenons souvent des solutions faciles sur lesquelles nous pouvons agir maintenant au lieu de la meilleure approche qui prendrait plus de temps.

Le point culminant de ces raccourcis est la dette technologique. Souvent, la dette technologique doit être épurée avant que de grands changements ne puissent être mis en œuvre.

L’un des gros obstacles à la compréhension par Google du contenu riche du Web réside en grande partie dans son service de rendu Web (WRS). L’un des composants principaux du robot Web utilisait une version de Chrome publiée en 2015. (Si vous pensez que ce n’est pas cette grosse affaire, trouvez votre ancien téléphone – celui que vous avez mis à niveau il y a six mois – et utilisez-le pendant une heure.)

Pour les professionnels du référencement et les développeurs, cela signifiait repousser les bases de codes pleines de polyfill ES6 fonctionnalités à ES5. Si vous ne les connaissez pas, félicitations! Vous avez choisi un âge d’or pour commencer à optimiser les sites angulaires!

Nouveau moteur de rendu révolutionnaire de Googlebot

Le développeur, développeur de la console de recherche, Martin Splitt a pris la parole avec l’ingénieur Rendering Zoe Clifford au début du mois chez Google I / O pour annoncer que Googlebot est à feuilles persistantes.

Le robot d'indexation utilise V8 en tant que moteur de rendu et WebAssembly. À compter de mai 2019, il exécutera Chrome 74 et continuera à mettre à jour environ une semaine après la publication des nouvelles versions.

La mise à niveau massive de notre crawler Web bien-aimé peut désormais générer plus de 1 000 nouvelles fonctionnalités. Vous pouvez tester la compatibilité de vos fonctionnalités avec Puis-je utiliser.

Attendez-vous à un délai pour l'indexation du contenu rendu

Les googleurs ont laissé entendre que l'avenir de Googlebot combinera exploration et rendu. Nous n’y sommes pas encore. L'analyse et le rendu sont toujours des processus séparés.

Maintenant que Googlebot peut mieux gérer Angular, voyons comment vous pouvez le vaincre.

Optimisation de Crawling for Angular

Connaissez votre version

La version de Angular sur laquelle vous travaillez aura un impact majeur sur votre capacité à optimiser – ou du moins à définir vos attentes.

La version 1 est appelée AngularJS.

Pour v2, le framework a été entièrement ré-écrit. C’est pourquoi tout ce qui suit v1 est désigné par le terme générique angulaire (c’est-à-dire que le JS a été coupé).

La version compte (étant donné que les programmes angulaires ne sont pas compatibles avec les versions antérieures), demandez donc à l’équipe avec laquelle vous travaillez quelle version est utilisée.

Donner à chaque actif une URL unique

Angular est fréquemment utilisé dans le cadre d’une application à une seule page (SPA).

Les applications à page unique permettent de mettre à jour le contenu de la page sans effectuer de demande de page au serveur.

Les demandes de nouveau contenu sont renseignées à l'aide d'appels JavaScript asynchrone et XML (AJAX). Aucun nouveau chargement de page ne signifie que l’URL visible dans le navigateur ne représente pas le contenu à l’écran.

C’est un problème de référencement car les moteurs de recherche veulent indexer du contenu qui régulièrement existe à une adresse connue. Si votre contenu seulement tend à exister à l'URI, il a également tendance à ne pas se classer.

Un petit morceau de code appelé pushState () met à jour l'URL lorsqu'un nouveau contenu est demandé.

Guide SEO pour Angular: Tout ce que vous devez savoir

Google propose un Codelab pour optimisation des applications à page unique (SPA) dans la recherche.

Suivre les analyses pour les applications à page unique avec des pages vues virtuelles

Si votre site Web charge le contenu de la page de manière dynamique et met à jour l'URL du document, vous souhaiterez envoyer des consultations de page supplémentaires pour suivre ces «consultations de page virtuelles».

Lorsque votre application charge le contenu de manière dynamique et met à jour l'URL dans la barre d'adresse, les données stockées sur votre suivi doivent également être mises à jour.

L’équipe de Google Analytics dispose d’une documentation complète sur Visites virtuelles de pages pour SPA, qui implique l’ajout d’une balise manuelle pour l’envoi d’informations à votre serveur de suivi lors du chargement du nouveau contenu.

Obtenez votre contenu découvert lors de la première indexation côté serveur, rendant les éléments de votre héros

Les moteurs de recherche cherchent à faire correspondre les pages à une intention.

Cette page est-elle utile pour répondre à une intention transactionnelle, d'information ou locale?

Si ma requête a une intention transactionnelle, des éléments tels que le nom du produit, le prix et la disponibilité sont essentiels pour répondre à cette intention.

Ce contenu est appelé vos éléments de héros.

Guide SEO pour Angular: Tout ce que vous devez savoir

En effectuant un rendu côté serveur, vous pouvez indiquer à Google les intentions de votre page lors de la première vague d'indexation, sans attendre le rendu de JavaScript.

En plus de ces éléments sur les héros, utilisez SSR pour:

  • Données structurées (Sam Vloeberghs crée un tutoriel utile)
  • Titre de la page
  • Meta Description
  • Balise HTML, y compris:
  • Date annotations

Ne vous opposez pas entre HTML et DOM

Les bases du référencement nous apprennent la simplicité.

Les pages ont un titre. Une méta description. Un ensemble de directives de robots.

Avec Angular, vous pouvez envoyer différentes métadonnées et directives dans le code HTML que DOM.

Nos amis bot utilisent du code pour faire les choses dans un ordre défini. Si vous placez une directive noindex dans le code HTML, Googlebot n’exécutera pas le script pour rechercher la indice balise dans le DOM parce que vous lui avez dit de ne pas rendre le DOM.

Ne divisez pas le balisage de données structurées entre HTML et DOM

Avec Angular, vous pouvez rendre le balisage Schema.org au format HTML (préférable) ou DOM.

Cela fonctionnera dans les deux cas, mais il est très important que le balisage complet se trouve dans un seul emplacement, HTML ou DOM.

Si vous scindez les deux en rendant une partie du balisage en HTML et en remplissant les attributs DOM, les composants distincts sont considérés comme des ensembles différents de balisages.

Aucun d'eux ne sera complet. Le balisage de données structuré est valide ou non. Il n’ya pas de «partiel». Effort maximum.

Des ressources lentes ou bloquées peuvent rendre le contenu impossible à découvrir

Les ressources lentes ou bloquées ne seront pas prises en compte dans la découverte de votre contenu. Les ressources lentes montreront comme temporairement indisponible.

Une demande de script doit être complétée dans environ 4 secondes. Les ressources bloquées seront désignées comme telles dans la sortie de l'outil.

Support du chargement paginé pour Infinite Scroll

La pagination sur mobile peut être frustrante.

Vous n’avez pas à choisir entre la facilité d’utilisation et l’exploration Googlebot. Utilisez plutôt les points de contrôle de l'API d'historique, des URL qui permettraient à un utilisateur (ou à un bot) de revenir au même endroit.

Selon Google:

Si vous implémentez une expérience de défilement infini, assurez-vous de prendre en charge le chargement paginé. Le chargement paginé est important pour les utilisateurs car il leur permet de partager et de reprendre contact avec votre contenu. Cela permet également à Google d'afficher un lien vers un point spécifique du contenu, plutôt que vers le haut d'une page à défilement infini.

Pour prendre en charge le chargement paginé, fournissez un lien unique vers chaque section que les utilisateurs peuvent partager et charger directement. Nous vous recommandons d'utiliser l'API d'historique pour mettre à jour l'URL lorsque le contenu est chargé de manière dynamique.

En savoir plus avec Google Lazy Loading documentation pour les développeurs.

Ne pas attendre les autorisations, les événements ou les interactions pour afficher le contenu

Interaction Observer> Evénements Onscroll

Utiliser les événements onscroll pour charger paresseux?

Googlebot ne le verra pas. Au lieu de cela, utilisez Googlebot-friendly Observateur d'intersection pour savoir quand un composant est dans la fenêtre.

Utiliser CSS Basculer la visibilité pour Tap to Load

Si votre site comporte un contexte précieux derrière des accordéons, des onglets ou d’autres interactions tap-to-load, n’attendez pas que la zone soit exposée pour le charger.

Chargez le contenu dans le HTML ou le DOM et exposez-le à l'aide des fonctionnalités CSS.

Vous n'obtenez jamais cette permission

Si votre site demande des autorisations, Googlebot refusera. Celles-ci incluent la géolocalisation, les notifications, le push et bien d’autres répertoriées sur Registre de permission du W3C.

Guide SEO pour Angular: Tout ce que vous devez savoir

Les liens explorables ont des balises d'ancrage avec les attributs Href

Le concept des robots Web est basé sur la découverte de contenu en suivant des liens. Votre contenu angulaire a besoin de liens avec un href attributs à découvrir.

Sera rampé
Pas rampé
Pas rampé
Pas rampé

Google ne sélectionne pas les images incorporées avec des styles CSS.

Les options avancées d’incorporation d’images incluent l’utilisation de <photo> et srcset pour des images sensibles.

Google recommandation est:

… Que vous fournissiez toujours un élément img comme solution de secours avec un attribut src lorsque vous utilisez la balise picture au format suivant:


grande image PNG ...

Utiliser des styles en ligne pour le contenu au-dessus du pli

Les dépendances de script pour un contenu supérieur au pli mettent votre capacité de recherche en péril. Si votre contenu ne peut pas être rendu sans attendre le chargement des ressources de script, les moteurs de recherche et les utilisateurs subiront probablement un retard.

Optimiser le chemin de rendu critique en insérant des CSS critiques dans le , ce qui permet au contenu au-dessus du pli de s'afficher dans le navigateur sans attendre le chargement du reste du code CSS.

En savoir plus sur la façon de minimiser le rendu en bloquant CSS à Fondamentaux Web.

Optimisation du rendu

Googlebot n'aime pas savoir si un site utilise JavaScript. C’est la façon dont le code JavaScript est rendu.

Les options de rendu et les technologies sont aussi généreuses que déroutantes.

Voici un aperçu de haut niveau des options de rendu angulaire. Prenez une tasse de café et asseyez-vous avec vos développeurs pour examiner la documentation détaillée sur les options de rendu. Comme toujours, le diable réside dans la mise en œuvre et votre expérience peut varier.

Rendu côté client (CSR)

CSR construit la page dans le navigateur de l'utilisateur. Le code HTML initial est un shell anémique. L'utilisateur ne peut voir et interagir qu'après que le bundle JavaScript principal a été récupéré et rendu.

Indice de découvrabilité: 👾

Cote de performance:

Rendu côté serveur (SSR)

HTML si bon, vous serez la preuve Bing!

Également appelé Universel, SSR construit la page sur le serveur et expédie le code HTML. Cette méthode nécessite de nombreuses ressources serveur et un compromis important entre le délai jusqu'au premier octet et vous devez donc être proactif dans la surveillance de la santé du serveur.

Indice de découvrabilité: 👾👾👾

Cote de performance:

Réalisation remarquable: Idéal pour les moteurs de recherche sans rendu

Rendu dynamique

Solution de contournement à court terme très déconcertante (mais pas dissimulée) pour les robots des moteurs de recherche. Cette technique nécessite d'avoir à la fois des rendus CSR et SSR et de décider lequel servir en fonction de l'agent utilisateur.

Des technologies telles que l'outil de pré-rendu open source Rendertron peut encore être très utile pour votre entreprise.

Indice d'expansibilité:

Cote de performance:

Note de durabilité:

Si vous n’avez pas déjà implémenté le rendu dynamique, cette option a probablement dépassé sa date de péremption.

Pré-rendu

Indice d'expansibilité:

Cote de performance:

Crée du HTML au moment de la construction et le stocke pour le servir sur demande. FCP amélioré et pas de surcharge SSR.

Ne fonctionne que pour le contenu statique – pas pour le contenu censé changer (pensez à la personnalisation et aux tests A / B).

N'oubliez pas les enfants, votre service de pré-rendu payant vous appartient.

Rendu hybride (rendu côté serveur avec hydratation)

Nous voulons la vitesse de la RSS, mais l’interactivité de la RSE. Solution: SSR + Hydratation.

Le rendu d'hydratation progressive semble être la voie de l'avenir. Il permet le fractionnement du code au niveau composant.

Les sites peuvent différer le rendu des composants jusqu'à ce qu'ils soient visibles par l'utilisateur ou nécessitent une interaction. Angular Universal possède une solution d'hydratation intégrée: ngExpressEngine.

Indice d'expansibilité:

Cote de performance:

Guide SEO pour Angular: Tout ce que vous devez savoir

Optimisation de la couverture d'index

Test avec des outils de première partie

Un cauchemar technique en matière de référencement consiste à obtenir un code à publier et à réaliser il ne rend pas. Les mises à niveau de Googlebot devraient atténuer les problèmes de remplissage et autres problèmes encombrants.

La meilleure façon de le savoir est d'utiliser les outils de Google pour tester. L'inspecteur d'URL de la console de recherche fournit un rendu complet avec défilement de capture d'écran.

Mobile Friendly Test et Rich Results renvoient également le DOM mais ne disposent pas de défilement de capture d’écran. Vous pouvez même tester les versions protégées par un pare-feu et hébergées localement.

Bientôt: Mises à jour de Googlebot User-Agent

L'agent utilisateur de Googlebot restera le même – pour le moment.

Nous pouvons nous attendre à ce que les outils de la console de recherche migrent vers le rendu v8.

Nous pouvons nous attendre à voir les agents utilisateurs Googlebot changer une fois la migration terminée.

Cela nous donnera une meilleure idée de la version de Chrome utilisée par Googlebot.

Cache les scripts efficacement

Les appels aux scripts comptent pour votre budget d'analyse.

Si vous utilisez les mêmes scripts sur plusieurs pages, les paramètres d’expiration du cache permettent à Googlebot de le demander une fois et de l’utiliser sur des pages pertinentes. Une fois le cache expiré, Google demandera à nouveau le script.

Tirez le meilleur parti de vos scripts en utilisant le versioning. Avec la gestion des versions, vous pouvez définir une longue date d'expiration pour votre script. Coucou Google, vous pouvez utiliser /myscript.js?v=1 pour la prochaine année!

Quand une version de code inclut une modification de cette série de scripts, mon site Web met à jour la série JavaScript à laquelle elle fait référence. Salut Google, utilisez /myscript.js?v=2 pour rendre cette page!

La gestion des versions en lot peut atténuer les problèmes de rendu après la publication

Si un robot d'indexation Web tente de restituer votre page mais utilise un script obsolète, la page risque d'être mal rendue.

Si votre page fait référence aux versions numérotées à utiliser, le moteur de recherche vérifiera s'il s'agit de la version actuelle du cache. Si les versions ne correspondent pas, le moteur de recherche demandera le bon paquet.

Guide SEO pour Angular: Tout ce que vous devez savoir

Si les appels asynchrones ont un uris unique, utilisez les directives No-Index de X-Robots

J'ai une page Web qui charge 3 éléments de contenu de manière asynchrone. Chacun de ces appels AJAX a un URI unique:

https://example.com/ajax/meet-my-cat-cta

https://example.com/ajax/random-cat-picture-generator

https://example.com/ajax/featured-bean-toes

Chaque fois que Googlebot me demande ma page Web, elle renvoie 4 URL. Ce n’est pas très efficace en ressources.

Cela se produit généralement lors de la personnalisation ou des composants qui doivent effectuer une vérification logique avant de décider du contenu à restituer.

Les résultats peuvent être très efficaces. https://example.com/ajax/random-cat-picture-generator?cat=tank&&pose=bellyrubs fait clairement partie d'une expérience personnalisée fantastique pour vous, l'utilisateur.

Guide SEO pour Angular: Tout ce que vous devez savoir

Every parameter combination is a unique URL. Googlebot treats unique URLs as unique pages (unless told otherwise).

One AJAX call unchecked could lead to thousands of confusing, low-value pages for search engines to sort through. That picture of Tank, the most handsome cat in the world, really adds to user experience but it’s about le contexte.

AJAX Calls & Index Inflation

These URIs by themselves can muck up your index. A simple pair of parameters on an AJAX URI will breed like bunnies. Each can be unique and indexable.

Your index status will looks like a roller coaster – a stark climbing rise in the number of pages – followed by a gut-churning drop as Googlebot purges pages from their index.

SEO Guide to Angular: Everything You Need to Know

To avoid this, add X-Robots noindex directives to URIs that load content asynchronously to the page. This will create cleaner technical signals and make Googlebot resources spent on understanding my site more effective.

Make a New Developer Ally

Developers are some of the best allies an SEO can have. Google Webmasters recognize this and have created a new web series focused on the code changes needed to make a discoverable site.

Looking for a place to start? Check-out Make your Angular web apps discoverable et SEO codelab for developers.

Tuck & Roll, My Friends

In summary, the keys to SEO for Angular are:

  • Knowing the difference between HTML and DOM.
  • Delivering content at the right time and place.
  • Consistent, unique, and crawlable URLs.
  • Being aware of your script resources’ indexability, size, response time, and caching policies.

This is the part where we work together to get everybody’s site out there alive and well.

The best way to learn Angular is hands-on so if you’re reading this, keep calm and remember the ancient digital proverb:

It’s not yours until you break it.

More Resources:


Image Credits

In-Post Image #1: Created by author, May 2019
In-Post Image #2: Screenshot taken by author, April 2019
In-Post Image #3: Bartosz Góralewicz via Moz
In-Post Image #4: Taken by Jennifer Holzman at i/o 2018
In-Post Image #5: Screenshot from Archive.org, 3 April 2019
In-Post Image #6: Created by author, May 2019
In-Post Image #7: Screenshot taken by author, March 2019
In-Post Image #8: Screenshot taken by author, March 2019
In-Post Image #9: Created by author, April 2019
In-Post Image #10: Screencap from Google Search and JavaScript Sites (Google I/O’19)

In-Post Image #11: Screenshot of MDN Web Docs
In-Post Image #12: User-centric Performance Metrics, Google Web Fundamentals
In-Post Image #13: Screencap from Google Search and JavaScript Sites (Google I/O’19)
In-Post Image #14: Screencap from Rendering on the Web: Performance Implications of Application Architecture (Google I/O ’19)
In-Post Image #15: Screenshot taken by author, March 2018
In-Post Image #16: Glamorshot of incredibly handsome cat by author
In-Post Image #17: Screenshot and chart creation by author, April 2018



Source link