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

Made with Slides.com