Getting seo performance in angular meteor with ngmeta
Advance SEO with Client Side Rendering. Learn basic SEO components that tie into Javascript crawability. Enjoy!
https://atmospherejs.com/mkslt04/ngmeta
2. What Is SEO?
Stands for “Search Engine Optimization”
Why do you care?
Internet Presence Starts on Search
Internet Users Start on Search
3. Internet Search Statistics
93% on online experiences begin on a search engine
70% of links users click on are organic
70-80% of users ignore paid ads
75% of users never scroll past the first page of search results
Search is the #1 driver of traffic to content sites, beating social media by
more than 300%
4. How Do People Search?
1. Experience the need for an answer, solution, or piece of information
2. Formulate that need in a string of words known as “the query”
3. Enter query into search engine
4. Browse through the results for a match
5. Click on result
6. Scan for a solution, or a link to that solution
6. How Are Web Pages Ranked?
2 Factors:
Relevance & Popularity
7. Meta Data & Schema.org
Schema.org is an initiative launched in 2011 by all major search engines to
create and support a common set of schemas for structured data markup
on web pages.
Meta Data is a form of displaying information in HTML in between the <head>
tags on your website that provides information about a web page to aid in
the indexing and categorization for Search Engines.
8. Example of Schema Tags
<div itemscope itemtype="http://schema.org/Organization">
<a itemprop="url" href="http://checkmatecreations.com/"><div
itemprop="name"><strong>Checkmate Creations</strong></div>
</a>
<div itemprop="description">Mobile App Development & Digital Media Agency</div>
<div itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">
<span itemprop="streetAddress">1253 WHITNEY AVE</span><br>
<span itemprop="addressLocality">Hamden</span><br>
<span itemprop="addressRegion">Connecticut</span><br>
<span itemprop="postalCode">06518</span><br>
<span itemprop="addressCountry">United States</span><br>
</div>
</div>
9. Example of Meta Data
<HEAD>
<title>Top Mobile App Development Agency in Connecticut</title>
<Meta http-equiv=”content-type” content=”text/html; charset=utf-8”>
<Meta name="Description" content="Checkmate is Connecticut’s leading mobile app development & marketing agency. ">
<Meta name="Keywords" content="Mobile App Development Connecticut, Digital Marketing Agency, Mobile Solutions">
<Meta name=”subject” content=”Top Mobile App Development Agency in CT”>
<Meta name=”author” content=”Checkmate Creations”>
<Meta name=”googlebot” content=”index, follow”>
<Meta http-equiv=”Content-Language” Content=”EN-US”>
<Meta name=”revisit-after Content=”7 Days”>
<Meta name=”city” content=”Hamden”>
<Meta name=”state” content=”CT”>
<Meta name=”zipcode” content=”06518”>
<Meta name=”copyright” content=”Checkmate Creations”>
</head>
<Body>
This is where the visible portion of your website is configured.
</Body>
</div>
10. PageRank & Popularity
“It turns out, people who win the Nobel Prize have citations
from 10,000 different papers. A large number of citations in
scientific literature, he said, means our work was important,
because other people thought it was worth mentioning” The
Google Story by David Vise
12. Server Rendering Vs. Client-Only Rendering
If the website owner doesn’t care about achieving top ranking, and the
only goal is to get indexed by Google and not any other search engine,
then it is ok to do Client only rendering with angular
13. Client Only Rendered HTML
Requires the following:
• Enable push state in Angular so you get pretty URLs without the hash.
• Implement UI Router or the new Component Router in Angular so you can map URLs
to pages.
• Follow all normal SEO best practices for page titles, URLs, content, etc. Nothing
changes here.
• Optimize the heck out of the initial page load—a major mistake many make is
thinking initial page load time for client-rendered apps doesn’t matter, but it does!
14. Server Rendering Performs Better For SEO
Reasons:
• Google is good at client rendering, but not perfect.
• Other search engines are really not good at it.
• Things like Facebook or Twitter link previews will not work.
• It is much easier to make server rendering fast than it is to make the
initial load for client rendering fast—and that makes a big difference.
15. Options for Server Rendering
• Implement in PHP or another language. This will work but requires that you
duplicate all pages, which is generally not feasible unless you have a
small/simple site.
• Use Prerender.io or a similar service. This works but can get expensive for
larger sites, can be tricky to set up, and you need to be OK with long page
cache times (i.e., server pages are one day old).
• Build a custom solution off the Jangular library. Although this works, it does
require a lot of heavy lifting.
• Wait for Angular 2.0 (possibly to be released end of 2015)
16. Free Tools!
• Google Structured Data Tool
• SEO Power Suite
• Screaming Frog SEO Spider
• SEMrush.com
• Moz.com
17. So What’s The Problem?
JavaScript…
It is getting better…?
SEO stands for “search engine optimization.”
Why do you care? You might not… But you should!
The way people learn, work, share, play, shop, research, socialize and interact online starts with search
Simply put organizations, causes, brands, charities, individuals - almost all other entities - need to have an internet presence of some kind.
They need search engines and search functionality within all platforms to generate exposure and facilitate engagement.
Lets look at some stats!
How people use search, and with the integration of Google’s Knowledge Graph and Vault have changed how Search Engine Results Pages (SERP) display information, but the primary principles of search remain unchanged, and conducting a search remains unchanged.
Search engines crawl the entire internet analyzing unique documents which are web pages, PDFs, or other files.
The search engine uses links to navigate the billions and billions of interconnected documents on the web.
The pages are quickly deciphered and indexed based on the information found on said web page
Relevance and popularity are determined by mathematically through algorithms to sort the information for relevancy and then rank the content in order to establish quality SERPs.
Relevance is established by the content of the page being crawled. By incorporating structured data i.e. information on your website that incorporates keywords naturally in a pages URL, Title, Anchor Text and Content in order to index a page properly. Meta Info & Schema.org as well as having a sitemap & robots.txt file markup help search engines index and navigate your web pages
Popularity is determined based on PageRank. A formula named after the founder of Google Larry Page.
Schema.org - Wouldn’t it be nice if The purpose of using the vocabulary along with the micordata, RDFa, or JSON-LD formats to mark up website content with metatdata about itself. Such markups are recognized by search engine spiders and other parsers, thus gaining access to the meaning of website. Schema data can be used for creative work, events, organization, place, person & product.
Metadata is a form of structured data and acts as a system of pairing a name with a value that helps that helps search engines categorize and index your website.
Larry Page felt the same principle could be applied to the web to find the best and most influential content. To measure how much a particular link mattered, you could look at the number of other links pointing at the page it was on. This ranking is called PageRank, named after Larry Page and not a more literal meaning
Essentially PageRank utilizes the democratic nature of the web, and uses the opinions of webmasters to determine the relative importance of a given page.
This is how Google was able to deliver more relevant and accurate search, and there are over 200 components that are used to determine popularity of a Web Page
While the above approach will work for Google indexing, you will perform better in organic search with server rendering.
In most JavaScript frontend frameworks, having dynamic meta data dependent on routes can be tricky. In most cases Google (as well as other search engines) will run an AJAX Crawl. Problem is more often than not your JavaScript updating your data will not run!
Well it is getting better...
In most JavaScript frontend frameworks, having dynamic meta data dependent on routes can be tricky. In most cases Google (as well as other search engines) will run an AJAX Crawl. Problem is more often than not your JavaScript updating your data will not run!
Well it is getting better…
Google as of October 2015 has deprecated AJAX crawls, allowing some JS to run, but you still need to make sure it is running in time. If it doesn’t run in X amount of time, it will not render.
BING does use AJAX……… (But It’s Not Google)
We work on a lovely framework called Meteor, which allows us flexibility for different front end frameworks. The ones officially supported are Angular, Blaz, as well as React.
Well, we all are aware there is a bit of shift in the community from Blaze. At some point Blaze will not be receiving first class support like Angular and React. Also there are some performance issues with Blaze, an odd lifecycle, and, well, there’s better options out there.
React, Facebook’s baby, it’s where the community at large is moving to. Galaxy is actually written with React! But that’s not why we’re here…
Angular. Well, this is Google’s baby; and if any of you are unsure as to why Angular and Meteor aren’t a dream pairing, please talk to my home boy Urigo. He’s actually not my home boy, but he’s really charming, and we constantly reference him for our projects because he pushes out to most Angular Meteor content.
If you’re interested in using Angular on your Meteor apps, visit the Angular Meteor website!
I’m not here to sell you on Angular, but I will admit it’s powerful, backed by second most valuable tech company in the world.
Angular 2 is also coming soon, it entered RC this past May. Which, fun fact, you can already start writing in Meteor! That’s right, Meteor has official support for Angular 2. MEAN IO doesn’t, and from what I last recall, Express.JS doesn’t have official Angular 2 support either (or an upgrade plan to support it). Moral of the story, Meteor IS the platform for Angular 2 developers.
We’re sticking to Angular 1.5.x though just because we have a stable platform, and 1.5 is designed for easier upgrading to 2.
NPM package
Let’s use a NPM package!
Uhm, maybe not….
Many of the packages on NPM involve special directives or binding an object with all of your meta data to the <head> of your application. However if you’ve done any Angular Meteor work you know that the <head> is not really part of the
Some NPM packages include…
angular-update-meta
angular-metas
Just some JavaScript
We want an easy way to update our meta tags for every route. I mean, you could use JQuery, pure JavaScript, or Angular’s implementation of jqLite. In every controller for every route you can write a bunch of function to manipulate the DOM. Not really reusable, I mean, arguable yes, but not efficient at all!
Angular Service
Ooooh!!!! Now we’re getting close!!!!
In Angular, a service is a function, or object, that is available for your AngularJS application from virtually anywhere.
You can use this to take that code you wrote in JS to update the <head> and have it anywhere
But… I already did this for you though.
We’re actually expediting the Angular 1 tutorial from angular-meteor.com, to get a quick Angular app, and then implement some ngmeta!!!! I invite and recommend that if you get the chance to take a tinker with it.
Also we’re only getting to Step 3, so we’re not worrying about autopublish or insecure. Keep in mind that may change this.
Meteor scans all the HTML files in your client and concatenates them together. Concatenation means merging the content of all HEAD and BODY tags found inside these HTML files together. So in our case, Meteor found our index.html file, found the HEAD and BODY tag inside and added it's content to the HEAD and BODY tag of the main generated file.
-(index.html)-
<body ng-app="socially" ng-strict-di=""> <socially></socially></body>
---
Angular 1 apps are actually individual modules. So let’s make sure we are able to have our module in our client, and then we’ll create the module.
-(main.js)-
import angular from 'angular';import angularMeteor from 'angular-meteor';import { name as Socially } from '../imports/ui/components/socially/socially';
---
Note that the Mongo.Collection has been used in a file that is outside /client or /server folders. This is because we want this file to be loaded in both client and server, and AngularJS files are loaded in the client side only. That means that this collection and the actions on it will run both on the client (minimongo) and the server (Mongo), you only have to write it once, and Meteor will take care of syncing both of them.
If you however continued the tutorial you’ll adjust how you define the collection (when you remove autopublish and insecure).
-(parties.js)-
Parties = new Mongo.Collection('parties');
---
-(socially.html)-
<parties-list></parties-list>
---
-(socially.js)-
import angular from 'angular';import angularMeteor from 'angular-meteor';import template from './socially.html';import { name as PartiesList } from '../partiesList/partiesList';class Socially {}const name = 'socially';// create a moduleexport default angular.module(name, [ angularMeteor, PartiesList]).component(name, { template, controllerAs: name, controller: Socially});
---
-(partiesList.html)-
<ul> <li ng-repeat="party in partiesList.parties"> {{party.name}} <p>{{party.description}}</p> </li></ul>
---
-(partiesList.js)-
import angular from 'angular';import angularMeteor from 'angular-meteor';import template from './partiesList.html';class PartiesList { constructor($scope, $reactive) { 'ngInject'; $reactive(this).attach($scope); this.helpers({ parties() { return Parties.find({}); } }); }}const name = 'partiesList';// create a moduleexport default angular.module(name, [ angularMeteor]).component(name, { template, controllerAs: name, controller: PartiesList});
---
-(startup.js)-
Meteor.startup(() => { if (Parties.find().count() === 0) { const parties = [{ 'name': 'Dubstep-Free Zone', 'description': 'Fast just got faster with Nexus S.' }, { 'name': 'All dubstep all the time', 'description': 'Get it on!' }, { 'name': 'Savage lounging', 'description': 'Leisure suit required. And only fiercest manners.' }]; parties.forEach((party) => { Parties.insert(party) }); }});
---
in main app module
import {ngmeta as ngmeta} from 'meteor/mkslt04:ngmeta';
attach as service
.service('ngmeta', ngmeta);
To dynamically edit this data whenever a page is loaded. Inside of your (PartiesList) constructor function pass in ngmeta as an argument. Then in the function we can call our ngmeta function ngmeta.setMetaTags(). This takes an object of the new values for the tags you want.
ngmeta.setMetaTags({
title: 'Parties List'
});