ganatan / angular-app

Angular 18 Fullstack Application: SSR, PWA, SEO, and Scalable Node.js Typescript & Javascript Backend with MySQL, PostgreSQL, MongoDB
712 stars 340 forks source link

I can't get the SSR project live #2

Open MehmetSert opened 4 years ago

MehmetSert commented 4 years ago

Hello,

I want to start by thanking you for your sharing. I cannot publish the project after the SSR compilation process. I did not have such a problem in the Angular 8 version. I can't publish after updating to 9.

I can compile the project. My "browser" and "server" folders are created in the "dist" folder. I am loading this to the server from the plesk panel and setting it to read the server / main.js file with node.js. However, the project does not open. Timed out.

Could you help?

server.ts

import 'zone.js/dist/zone-node';

import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';

import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF } from '@angular/common';
import { existsSync } from 'fs';

const domino = require('domino'); // kb
const fs = require('fs'); // kb
const template = fs.readFileSync('dist/browser/index.html').toString(); // kb
const win = domino.createWindow(template); // kb
global['window'] = win;
global['document'] = win.document;
global["branch"] = null;
global["object"] = win.object;
global['DOMTokenList'] = win.DOMTokenList;
global['Node'] = win.Node;
global['Text'] = win.Text;
global['HTMLElement'] = win.HTMLElement;
global['navigator'] = win.navigator;

// The Express app is exported so that it can be used by serverless Functions.
export function app() {
  const server = express();
  const distFolder = join(process.cwd(), 'dist/browser');
  const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';

  // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
  server.engine('html', ngExpressEngine({
    bootstrap: AppServerModule,
  }));

  server.set('view engine', 'html');
  server.set('views', distFolder);

  // Example Express Rest API endpoints
  // app.get('/api/**', (req, res) => { });
  // Serve static files from /browser
  server.get('*.*', express.static(distFolder, {
    maxAge: '1y'
  }));

  // All regular routes use the Universal engine
  server.get('*', (req, res) => {
    res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
  });

  return server;
}

function run() {
  const port = process.env.PORT || 4000;

  // Start up the Node server
  const server = app();
  server.listen(port, () => {
    console.log(`Node Express server listening on http://localhost:${port}`);
  });
}

// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
  run();
}

export * from './src/main.server';

main.server.ts

import { enableProdMode } from '@angular/core';

import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

export { AppServerModule } from './app/app.server.module';
export {ngExpressEngine} from '@nguniversal/express-engine';

export { renderModule, renderModuleFactory } from '@angular/platform-server';

tsconfig.app.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": []
  },
  "files": [
    "src/main.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

tsconfig.server.json

{
  "extends": "./tsconfig.app.json",
  "compilerOptions": {
    "module": "commonjs",
    "outDir": "./out-tsc/app-server",
    "baseUrl": ".",
    "types": [
      "node"
    ]
  },
  "angularCompilerOptions": {
    "entryModule": "./src/app/app.server.module#AppServerModule"
  },
  "files": [
    "src/main.server.ts",
    "server.ts"
  ]
}

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "esnext",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ]
  }
}

package.json

{
  "name": "kodumunblogu",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "compile:server_bak": "webpack --config webpack.server.config.js --progress --colors",
    "build:ssr_bak": "npm run build:client-and-server-bundles && npm run compile:server",
    "serve:ssr_bak": "node dist/server",
    "build:client-and-server-bundles_bak": "ng build --prod --aot && ng run kodumunblogu:server:production --bundleDependencies all",
    "dev:ssr": "ng run kodumunblogu:serve-ssr",
    "serve:ssr": "node dist/server/main.js",
    "build:ssr": "ng build --prod && ng run kodumunblogu:server:production",
    "prerender": "ng run kodumunblogu:prerender",
    "postinstall": "ngcc"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^9.0.0",
    "@angular/cdk": "^9.0.0",
    "@angular/common": "~9.0.0",
    "@angular/compiler": "~9.0.0",
    "@angular/core": "~9.0.0",
    "@angular/forms": "~9.0.0",
    "@angular/material": "^9.0.0",
    "@angular/platform-browser": "~9.0.0",
    "@angular/platform-browser-dynamic": "~9.0.0",
    "@angular/platform-server": "^9.0.0",
    "@angular/router": "~9.0.0",
    "@fortawesome/angular-fontawesome": "^0.6.0",
    "@fortawesome/fontawesome-svg-core": "^1.2.15",
    "@fortawesome/free-brands-svg-icons": "^5.7.2",
    "@fortawesome/free-solid-svg-icons": "^5.7.2",
    "@fullcalendar/core": "^4.3.1",
    "@nguniversal/express-engine": "^9.0.0",
    "@ngx-share/button": "^7.1.2",
    "@ngx-share/buttons": "^7.1.2",
    "@ngx-share/core": "^7.1.2",
    "bootstrap": "^4.3.1",
    "chart.js": "^2.9.3",
    "core-js": "^2.6.5",
    "express": "^4.17.1",
    "jquery": "^3.3.1",
    "primeicons": "^2.0.0",
    "primeng": "^9.0.0-rc.4",
    "quill": "^1.3.6",
    "rxjs": "~6.5.4",
    "tslib": "^1.10.0",
    "webpack-node-externals": "^1.7.2",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.900.1",
    "@angular/cli": "~9.0.1",
    "@angular/compiler-cli": "~9.0.0",
    "@angular/language-service": "~9.0.0",
    "@nguniversal/builders": "^9.0.0",
    "@types/express": "^4.17.0",
    "@types/jasmine": "~3.3.10",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^12.11.1",
    "codelyzer": "^5.1.2",
    "jasmine-core": "~3.3.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.0.1",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.5",
    "karma-jasmine": "~2.0.1",
    "karma-jasmine-html-reporter": "^1.4.0",
    "protractor": "~5.4.0",
    "ts-loader": "^4.0.0",
    "ts-node": "~8.0.3",
    "tslint": "~5.14.0",
    "typescript": "~3.7.5",
    "webpack-cli": "^3.1.0"
  }
}
ganatan commented 4 years ago

Hi Mehmet,

I did some tests with the angular9-app.git repository and your modifications.

1/ git clone https://github.com/ganatan/angular9-app.git

2/ Your files without modifications

3/ Three files with modifications

4/ Solution I think your angular.json had a wrong configuration.

5/ Note With Angular version 9 google use a directory for each project. Like the nrwl team (https://nrwl.io/). It would be more effective with mono repos In your project I would rather use dist/kodumunblogu/browser

Tell me if it works.

main.server.ts

import { enableProdMode } from '@angular/core';

import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

export { AppServerModule } from './app/app.server.module';
export { renderModule, renderModuleFactory } from '@angular/platform-server';

angular.json

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "kodumunblogu": {
      "projectType": "application",
      "schematics": {},
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/browser",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "aot": true,
            "assets": [
              "src/favicon.ico",
              "src/assets",
              "src/manifest.webmanifest",
              "src/sitemap.xml",
              "src/robots.txt"
            ],
            "styles": [
              "src/styles.css",
              "node_modules/@fortawesome/fontawesome-free/css/all.min.css",
              "node_modules/bootstrap/dist/css/bootstrap.min.css",
              "src/assets/params/css/index.css"
            ],
            "scripts": [
              "node_modules/jquery/dist/jquery.min.js",
              "node_modules/bootstrap/dist/js/bootstrap.min.js",
              "src/assets/params/js/index.js"
            ]
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "6kb",
                  "maximumError": "10kb"
                }
              ],
              "serviceWorker": true,
              "ngswConfigPath": "ngsw-config.json"
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "kodumunblogu:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "kodumunblogu:build:production"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "kodumunblogu:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js",
            "assets": [
              "src/favicon.ico",
              "src/assets",
              "src/manifest.webmanifest"
            ],
            "styles": ["src/styles.css"],
            "scripts": []
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "tsconfig.app.json",
              "tsconfig.spec.json",
              "e2e/tsconfig.json"
            ],
            "exclude": ["**/node_modules/**"]
          }
        },
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "kodumunblogu:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "kodumunblogu:serve:production"
            }
          }
        },
        "server": {
          "builder": "@angular-devkit/build-angular:server",
          "options": {
            "outputPath": "dist/server",
            "main": "server.ts",
            "tsConfig": "tsconfig.server.json"
          },
          "configurations": {
            "production": {
              "outputHashing": "media",
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "sourceMap": false,
              "optimization": true
            }
          }
        },
        "serve-ssr": {
          "builder": "@nguniversal/builders:ssr-dev-server",
          "options": {
            "browserTarget": "kodumunblogu:build",
            "serverTarget": "kodumunblogu:server"
          },
          "configurations": {
            "production": {
              "browserTarget": "kodumunblogu:build:production",
              "serverTarget": "kodumunblogu:server:production"
            }
          }
        },
        "prerender": {
          "builder": "@nguniversal/builders:prerender",
          "options": {
            "browserTarget": "kodumunblogu:build:production",
            "serverTarget": "kodumunblogu:server:production",
            "routes": ["/"]
          },
          "configurations": {
            "production": {}
          }
        }
      }
    }
  },
  "defaultProject": "kodumunblogu"
}

package.json

{
  "name": "kodumunblogu",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "compile:server_bak": "webpack --config webpack.server.config.js --progress --colors",
    "build:ssr_bak": "npm run build:client-and-server-bundles && npm run compile:server",
    "serve:ssr_bak": "node dist/server",
    "build:client-and-server-bundles_bak": "ng build --prod --aot && ng run kodumunblogu:server:production --bundleDependencies all",
    "dev:ssr": "ng run kodumunblogu:serve-ssr",
    "serve:ssr": "node dist/server/main.js",
    "build:ssr": "ng build --prod && ng run kodumunblogu:server:production",
    "prerender": "ng run kodumunblogu:prerender",
    "postinstall": "ngcc"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^9.0.0",
    "@angular/cdk": "^9.0.0",
    "@angular/common": "~9.0.0",
    "@angular/compiler": "~9.0.0",
    "@angular/core": "~9.0.0",
    "@angular/forms": "~9.0.0",
    "@angular/material": "^9.0.0",
    "@angular/platform-browser": "~9.0.0",
    "@angular/platform-browser-dynamic": "~9.0.0",
    "@angular/platform-server": "^9.0.0",
    "@angular/router": "~9.0.0",
    "@angular/service-worker": "9.0.1",
    "@asymmetrik/ngx-leaflet": "6.0.1",
    "@fortawesome/fontawesome-free": "5.12.1",
    "@fortawesome/angular-fontawesome": "^0.6.0",
    "@fortawesome/fontawesome-svg-core": "^1.2.15",
    "@fortawesome/free-brands-svg-icons": "^5.7.2",
    "@fortawesome/free-solid-svg-icons": "^5.7.2",
    "@fullcalendar/core": "^4.3.1",
    "@nguniversal/express-engine": "^9.0.0",
    "@ngx-share/button": "^7.1.2",
    "@ngx-share/buttons": "^7.1.2",
    "@ngx-share/core": "^7.1.2",
    "bootstrap": "^4.3.1",
    "chart.js": "^2.9.3",
    "core-js": "^2.6.5",
    "express": "^4.17.1",
    "jquery": "^3.3.1",
    "leaflet": "1.6.0",
    "ng2-charts": "2.3.0",
    "primeicons": "^2.0.0",
    "primeng": "^9.0.0-rc.4",
    "quill": "^1.3.6",
    "rxjs": "~6.5.4",
    "tslib": "^1.10.0",
    "webpack-node-externals": "^1.7.2",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.900.1",
    "@angular/cli": "~9.0.1",
    "@angular/compiler-cli": "~9.0.0",
    "@angular/language-service": "~9.0.0",
    "@nguniversal/builders": "^9.0.0",
    "@types/express": "^4.17.0",
    "@types/jasmine": "~3.3.10",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^12.11.1",
    "codelyzer": "^5.1.2",
    "jasmine-core": "~3.3.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.0.1",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.5",
    "karma-jasmine": "~2.0.1",
    "karma-jasmine-html-reporter": "^1.4.0",
    "protractor": "~5.4.0",
    "ts-loader": "^4.0.0",
    "ts-node": "~8.0.3",
    "tslint": "~5.14.0",
    "typescript": "~3.7.5",
    "webpack-cli": "^3.1.0"
  }
}
MehmetSert commented 4 years ago

Thank you.

I checked it the way you said and corrected what needed to be fixed. I added "angular / service-worker".

My "npm run build: ssr" and "npm run serve: ssr" commands work fine. There is no problem with these.

When I look at the "localhost: 4000" page source in the hidden tab, the page source occurs. There's no problem with that.

But it doesn't work when I want to get the project live on the server. I think there is a problem with the server, but when I compile Angular 8 it works without problems.

When I run the project with "serve: ssr" I get a warning like this. Is this the problem? https://prnt.sc/r38s4c The project is working, even if this warning is given. It just doesn't work on the server.

On the server, my settings are as follows: https://prnt.sc/r38o0b The site opens while it is set in this way. But when I open the source code, "ssr" doesn't work. It also doesn't work when I open the page source in the hidden tab.

My current settings and my package.json file are like this: https://gist.github.com/MehmetSert/d8eb11b1e5ad59b4be6a75eaf50d57fe angular.json: https://gist.github.com/MehmetSert/2b9a26f3cfa386e5d960c6145068c9cf

Maybe I'm doing the Node.js setting wrong in Plesk Panel. But when Angular is 8 it works with the same adjustment. I really did not understand the problem. I think Angular 9 doesn't work on the server.

MehmetSert commented 4 years ago

I made ssh access to the server. I ran "main.js" with "node". It worked on "ipAdress: 4000" without any problems. I think I am making errors in the Node.js definitions in Plesk Panel. I will try to solve it.

isaklavci commented 4 years ago

Hi, Your work is good. Thanks for that, but I have same issue. Were you able to find a solution? Everything seems correct but no SSR.

I'm desperate for Universal. The sample project in Angular.io is also problematic. I've been trying for a long time but there is always a problem.

Do you think we should give up this love?

ganatan commented 4 years ago

@isaklavci

Deployment with a simple VPS works. All the stuff here

https://github.com/ganatan/angular9-app/issues/1

MehmetSert commented 4 years ago

Hi, Your work is good. Thanks for that, but I have same issue. Were you able to find a solution? Everything seems correct but no SSR.

I'm desperate for Universal. The sample project in Angular.io is also problematic. I've been trying for a long time but there is always a problem.

Do you think we should give up this love?

Unfortunately. I think we are having a server related problem. When I compile the same project with Angular 8, ssr works. When I update and compile to Angular 9, ssr does not work.

Thomasfds commented 4 years ago

SSR Not work on angular 9.. why ? I dont know.

ganatan commented 4 years ago

@Thomasfds

Following the angular documentation it works.

I have made this tuto https://www.ganatan.com/tutorials/server-side-rendering-with-angular-universal

Thomasfds commented 4 years ago

I have already following this tutorial all work. But the code source is not SSR.

SEO dont work, html is same of non SSR rendering.. @ganatan

MehmetSert commented 4 years ago

I have already following this tutorial all work. But the code source is not SSR.

SEO dont work, html is same of non SSR rendering.. @ganatan

It will probably work if you open the page source link in the hidden tab.

I wish this was my problem :)

SSR does not work for me, it does not work on localhost and does not work on the server.

Thomasfds commented 4 years ago

It will probably work if you open the page source link in the hidden tab.

No.. Nothing work in local and on Live server ! :/

ganatan commented 4 years ago

@MehmetSert @Thomasfds

I agree with you Actually you can't see the ssr results on your browser (chrome for example) Perhaps because of angular 9 and the browser side

But SSR works on the server side with google robots

Use curl to verify if for example on localhost curl http://localhost:4000/ > ssr-results.txt

With live demo curl https://angular.ganatan.com/ > ssr-results.txt and verify the content of ssr-results.txt you will see the html code (here the text features)

Another proof use SEOQUAKE (SEO Toolbox) to verify SEO on angular.ganatan.com/

I apply ssr also on www.ganatan.com and angular.ganatan.com check with google requests "angular ssr" or 'angular bootstrap"

I hope it will help

In french we say "L'absence de preuves n'est pas la preuve de l'absence"

Thomasfds commented 4 years ago

I'd watch that. But at the moment I can't launch my app on nodejs on cpanel

I will soon abandon the idea of using the Framework js unfortunately :(

MehmetSert commented 4 years ago

@ganatan

Thank you very much for your answers. I clone your project and cannot publish it on my own server. I cannot publish it in my own project in the same way. However, I can publish an Angular 8 version of my own project. I can't do that in Angular 9. The server is the same server, the settings are the same. I use VPS and Plesk panel.

Since it runs on localhost, the problem is very likely server originated. But Angular 8 works. I believe the problem I was having was caused by the server, but I have no idea what configuration needs to be done. Do you have any suggestions?

I am writing these messages to you because you have used Angular 9 and broadcast it with SSR and you have used it. Please excuse.

Thomasfds commented 4 years ago

@ganatan

Thank you very much for your answers. I clone your project and cannot publish it on my own server. I cannot publish it in my own project in the same way. However, I can publish an Angular 8 version of my own project. I can't do that in Angular 9. The server is the same server, the settings are the same. I use VPS and Plesk panel.

Since it runs on localhost, the problem is very likely server originated. But Angular 8 works. I believe the problem I was having was caused by the server, but I have no idea what configuration needs to be done. Do you have any suggestions?

I am writing these messages to you because you have used Angular 9 and broadcast it with SSR and you have used it. Please excuse.

Plesk with nodejs application ? In Cpanel same (With PASSENGER) server don't launch so I'm stuck.

ganatan commented 4 years ago

@MehmetSert @Thomasfds

To test I took a Web Plesk - VPS Classic on OVH (15.59 euros instead of 3.59 euros for a vps) lots of features but lots of possibilities for incorrect configuration If i find a solution i will give it to you

The stuff for a simple VPS works is here https://github.com/ganatan/angular9-app/issues/1

MehmetSert commented 4 years ago

@ganatan

Thank you so much. I will continue to research and try. I will follow here. Thanks.

svbackend commented 4 years ago

Actually you can't see the ssr results on your browser (chrome for example) Perhaps because of angular 9 and the browser side

But SSR works on the server side with google robots

Use curl to verify if for example on localhost curl http://localhost:4000/ > ssr-results.txt

With live demo curl https://angular.ganatan.com/ > ssr-results.txt and verify the content of ssr-results.txt you will see the html code (here the text features)

Another proof use SEOQUAKE (SEO Toolbox) to verify SEO on angular.ganatan.com/

@ganatan Hello, do you have any ideas why this happening? Pretty weird as to me, same server returns different responses whether it's a curl request or regular browser request?

ganatan commented 4 years ago

Hi,

No ideas. but curl is the proof that SEO works. Another proof use SEOQUAKE (SEO Toolbox) to verify SEO on angular.ganatan.com/

Le sam. 1 août 2020 à 13:32, Valentin Saik notifications@github.com a écrit :

Actually you can't see the ssr results on your browser (chrome for example) Perhaps because of angular 9 and the browser side

But SSR works on the server side with google robots

Use curl to verify if for example on localhost curl http://localhost:4000/ > ssr-results.txt

With live demo curl https://angular.ganatan.com/ > ssr-results.txt and verify the content of ssr-results.txt you will see the html code (here the text features)

Another proof use SEOQUAKE (SEO Toolbox) to verify SEO on angular.ganatan.com/

Hello, do you have any ideas why this happening? Pretty weird as to me, same server returns different responses whether it's a curl request or regular browser request?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ganatan/angular10-app/issues/2#issuecomment-667517463, or unsubscribe https://github.com/notifications/unsubscribe-auth/AH3OPOP3FT44LGX72RWTOCDR6P4LFANCNFSM4KTXIHRA .