The Progressive

S.E.O. guide

for PWA’s

Wilson Mendes

@willmendesneto

Google Developer Expert Web Technologies

DURING THE FREE TIME...

1. Access https://goo.gl/PibUcQ

2. Decrease the price to $0,00

3. Enjoy

Nodebots book free!

So, let's start?

<webapps/>                    are evolving

and we need to be up-to-date

<page-container>
</page-container>
<component1 />
<component2>
</component2>
<component3 />

Layout container

small scope

boundaries

plug-and-play

Everything is a component

bundle
test
publish
lint

Opinions ?

reporter
dev server
types
coverage

npm install -g @angular/cli
// Installing Angular CLI
ng new my-app
// Creating a new Angular App
ng serve
// Starting local server

Schematics 

...will always help you

# Adding inline style and inline template

{
  ...
  "defaultProject": "my-app",
  "schematics": {
    "@schematics/angular": {
      "component": {
        "inlineStyle": true,
        "inlineTemplate": true
      }
    }
  }
  ...
}

Schematics

Retrieve data         using resolver

it's a fight to be continued...

// create a resolver

export class ListingItemResolver implements Resolve<ListingItem> {
  constructor(
    private service: ListingItemService
  ) {}

  resolve(route: ActivatedRouteSnapshot) {
    const id = route.paramMap.get('id');

    return this.service
        .getListingItem(id);
  }
}

Item resolver

// Adding `ListingItemResolver` 
// resolver in your route

const routes: Routes = [{
  path: ':id',
  component: ListingItemDetailContainerComponent,
  resolve: { item: ListingItemResolver },
}];

Angular Universal

or: Server-Side Render with style 😎

ng g universal 
  --clientProject my-app
// Configuring Angular universal
ng build my-app --prod
// Build app in prod mode
ng run my-app:server:production
// Run server in prod mode

tsconfig.server.json

main.server.ts

app.server.module.ts

// Create a service to handle
// all the changes in the main tags
// `metatags`, `title`, etc

export class LayoutService {

  constructor(private meta: Meta, private title: Title) { }

  public setMetaData(config) {
    this.title.setTitle('Page Title');

    const tags = [
      { name: 'description', content: 'Description' },
      { name: 'theme-color', content: '#333' },
      { property: 'og:title', content: title },
      { property: 'og:description', content: 'Description' },
      { property: 'og:image', content: '/image.png' },
    ];

    tags.forEach(tag => this.meta.updateTag(tag));
  }
}

Server-side

or

Client-side

🥊 🥊 🥊

Service Workers

PWA in the right way ✅

ng add @angular/pwa
// PWA support out of the box

manifest.json

ngsw-config.json

<noscript> info

<!-- Add it in your `src/index.html` -->

<noscript>
  <p>This page is best viewed using JavaScript.</p>
</noscript>

<noscript>

// Caching external resources
// in your service worker
{
  ...
  {
    "name": "externals",
    "installMode": "prefetch",
    "updateMode": "prefetch",
    "resources": {
      "urls": [
        "https://ajax.googleapis.com/**",
        "https://fonts.googleapis.com/**",
        "https://fonts.gstatic.com/**",
        "<your-cdn-url>"
      ]
    }
  }
}
// Storing your API responses
// using Service Workers
{
  ...
  "dataGroups": [{
    "name": "rest-api",
    "urls": [
      "<your-api-url>/**"
    ],
    "cacheConfig": {
      "strategy": "freshness",
      "maxSize": 100,
      "maxAge": "1h", // how long it should be stored?
      "timeout": "5s"
    }
  }]

Schemas, schemas and more schemas

share information is the key 🎩

<!DOCTYPE html>
<html
  itemtype="http://schema.org/Product"
  lang="en"
>
<head>
  ...
</head>
<body>
  <h1 itemprop="name">Title goes here ...</h1>
  <time
    datetime="2018-10-08 15:49:40 -0300"
    itemprop="datePublished"
  >
    October 8th, 2018
  </time>
  ...
</body>
</html>
<script type="application/ld+json">
{
  "@context": {
    "name": "http://xmlns.com/foaf/0.1/name",
    "homepage": {
      "@id": "http://xmlns.com/foaf/0.1/workplaceHomepage",
      "@type": "@id"
    },
    "Person": "http://xmlns.com/foaf/0.1/Person"
  },
  "@id": "https://me.example.com",
  "@type": "Person",
  "name": "John Smith",
  "homepage": "https://www.example.com/"
}
</script>

JSON-LD

json-ld.org

Schema.org

Lighthouse

Other resources

https://github.com/willmendesneto/ngx-universal

<ngx-recap/>

Zero-config ...always!

Resolver ...lazily

*** Angular universal

Check your metrics

Thank you

Wilson Mendes

@willmendesneto

Google Developer Expert Web technologies

The Progressive S.E.O. guide for PWA’s

By willmendesneto

The Progressive S.E.O. guide for PWA’s

Having you ever had any S.E.O. in your project? How to make the crawlers happy and don’t be punished in your PWA? Server-side rendering? JSON-LD? Lazy loading? Metadata? How all these things can help you in your journey? In this talk, I will share my experience and decisions improving some S.E.O. aspects in several frontend applications, how to do checks based in some data, best practices in your NG-App and more that make your product rock on Google Searches.

  • 2,932