Size: a a a

Angular-universal-ru

2020 March 16

YG

Yurii Gavdan in Angular-universal-ru
nur tlek
а тут нельзя было просто вставить в index.html
можно, но у нас кроме Google Tag Manager'а еще много скриптов планируется,
и нам очень хотелось все вынести в сервисы.
источник

nt

nur tlek in Angular-universal-ru
понял
источник

nt

nur tlek in Angular-universal-ru
а с iframe получилось ?
источник

YG

Yurii Gavdan in Angular-universal-ru
Yurii Gavdan
Всем привет,
поскажите пожалуйста, кто сталкивался с такой проблемой?

Очень нужно обновлять мета тэги,
которые мы получаем по HTTP.

В результате чего,
для обычных страниц у меня все работает отлично с:
@ngx-meta/core
this.meta.setTitle(title);
this.meta.setTag(name, content);

И тут я дошел до главного,
я получаю данные через клиентский http сервис,
import { HttpClient } from '@angular/common/http';

в результате чего, я не могу обновлять мета теги на сервере,

и у нас есть некий пример с "angular-universal-starter", который использует
import { TransferHttpService } from '@gorniv/ngx-transfer-http';

итого получаем, внутри ApiService'а, теперь есть 2 провайдера,
далее я пытаюсь сделать вот так, менять динамически, уже в сущесвующем серисе:

@Injectable()
export class ApiService {
 private API_URL = '';
 constructor(
   @Inject(DOCUMENT) private document: Document,
   @Inject(PLATFORM_ID) private platformId: string,
   private http,
   private httpServer: TransferHttpService,
   private httpClient: HttpClient,
 ) {
  // вот здесь нужно получить универсальный http клиент
  // чтобы в DEV/SPA версии юзался HttpClient
  // а в SSR httpServer

   this.http = isPlatformServer(this.platformId)
     ? this.httpServer
     : this.httpClient;

И самое главное - нужно добится обновления meta тэгов в SSR режиме!

Кто знает, что я в этой жизни делаю не так? :)
Возможно у кого-то есть примеры?
Заранее, огромное спасибо!
Кстати по поводу вот этой проблемы, хочу поделится:
с тем что данные от HTTP не обновляли мета тэги, вот решение (оч. много времени пришлось потратить - пока не дошел сюда):
https://v8.angular.io/guide/universal#absolute-http-urls
начиная с "Using absolute URLs for server requests",
мне нужно было создать "universal-interceptor.ts" и обновить файлы app.server.module.ts и server.ts, и все заработало! :)

Но я так понял что в стартере там из коробки и это тоже есть и еще много другого вшито.

Просто мы начинали писать без стартера, и уже поздно на него переходить.

В итоге мета теги обновляются! И решилась еще 1 проблема, у нас данные с HTTP выводились только в браузере, а теперь они и в SSR отдаются!
источник

YG

Yurii Gavdan in Angular-universal-ru
nur tlek
понял
да, сек, найду код новый и скину
источник

nt

nur tlek in Angular-universal-ru
ok
источник

YG

Yurii Gavdan in Angular-universal-ru
import {
 InjectableInjectable, InjectInject, PLATFORM_IDPLATFORM_ID, Renderer2, RendererFactory2,
} from '@angular/core'@angular/core';
import { DOCUMENTDOCUMENT, isPlatformBrowser, isPlatformServer } from '@angular/common'@angular/common';
import { CommonService } from '@shared/services/common/common.service'@shared/services/common/common.service';

@Injectable()
export class GtmService {
 config: object;
 isInjected: boolean;
 private renderer2: Renderer2;

 constructor(
   @Inject(PLATFORM_IDPLATFORM_ID) private platformId: string,
   @Inject(DOCUMENTDOCUMENT) private document: Document,
   rendererFactory: RendererFactory2,
 ) {
   this.renderer2 = rendererFactory.createRenderer(null, null);
   this.config = CommonService.config();
 }

 gtmPush(data) {
   if (isPlatformBrowser(this.platformId) && windowwindow) {
     // @ts-ignore
     window
window.dataLayer = windowwindow.dataLayer || [];
     // @ts-ignore
     window
window.dataLayer.push(data);
   }
 }

 gtmInject() {
   const {
     id,
     isEnabled,
     blackList,
   } = this.config['GTM'];
   if (!isEnabled) {
     return;
   }

   if (isPlatformServer(this.platformId)) {
     this.isInjected = true;
     // ### GTM > head > script
     
const script = this.renderer2.createElement('script');
     script.type = 'text/javascript';
     script.text = `
     (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
       new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
       j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
       'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
     })(window,document,'script','dataLayer','
https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
     })(window,document,'script','dataLayer','${id}');
     `
;
     this.renderer2.appendChild(this.document.head, script);

     // ### GTM > body > iframe
     
const iframe = this.renderer2.createElement('iframe');
     iframe.src = https://www.googletagmanager.com/ns.html?id=${id};
     iframe.height = 0;
     iframe.width = 0;
     iframe.stylestyle = 'display:none;visibility:hidden';
     const noscript = this.renderer2.createElement('noscript');
     this.renderer2.appendChild(noscript, iframe);
     this.renderer2.appendChild(this.document.body, noscript);
   }
 }
}
источник

YG

Yurii Gavdan in Angular-universal-ru
вот в конце смотри,
сразу создаем iframe, затем noscript, и
iframe вставляем в noscript
this.renderer2.appendChild(noscript, iframe);
а затем noscript вставляем в body:
this.renderer2.appendChild(this.document.body, noscript);
источник

nt

nur tlek in Angular-universal-ru
Yurii Gavdan
import {
 InjectableInjectable, InjectInject, PLATFORM_IDPLATFORM_ID, Renderer2, RendererFactory2,
} from '@angular/core'@angular/core';
import { DOCUMENTDOCUMENT, isPlatformBrowser, isPlatformServer } from '@angular/common'@angular/common';
import { CommonService } from '@shared/services/common/common.service'@shared/services/common/common.service';

@Injectable()
export class GtmService {
 config: object;
 isInjected: boolean;
 private renderer2: Renderer2;

 constructor(
   @Inject(PLATFORM_IDPLATFORM_ID) private platformId: string,
   @Inject(DOCUMENTDOCUMENT) private document: Document,
   rendererFactory: RendererFactory2,
 ) {
   this.renderer2 = rendererFactory.createRenderer(null, null);
   this.config = CommonService.config();
 }

 gtmPush(data) {
   if (isPlatformBrowser(this.platformId) && windowwindow) {
     // @ts-ignore
     window
window.dataLayer = windowwindow.dataLayer || [];
     // @ts-ignore
     window
window.dataLayer.push(data);
   }
 }

 gtmInject() {
   const {
     id,
     isEnabled,
     blackList,
   } = this.config['GTM'];
   if (!isEnabled) {
     return;
   }

   if (isPlatformServer(this.platformId)) {
     this.isInjected = true;
     // ### GTM > head > script
     
const script = this.renderer2.createElement('script');
     script.type = 'text/javascript';
     script.text = `
     (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
       new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
       j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
       'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
     })(window,document,'script','dataLayer','
https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
     })(window,document,'script','dataLayer','${id}');
     `
;
     this.renderer2.appendChild(this.document.head, script);

     // ### GTM > body > iframe
     
const iframe = this.renderer2.createElement('iframe');
     iframe.src = https://www.googletagmanager.com/ns.html?id=${id};
     iframe.height = 0;
     iframe.width = 0;
     iframe.stylestyle = 'display:none;visibility:hidden';
     const noscript = this.renderer2.createElement('noscript');
     this.renderer2.appendChild(noscript, iframe);
     this.renderer2.appendChild(this.document.body, noscript);
   }
 }
}
а в чем разница renderer & rendererfactory
источник

YG

Yurii Gavdan in Angular-universal-ru
nur tlek
а в чем разница renderer & rendererfactory
это нужно было для того чтобы не было ошибок комиляции, когда я передвинул всю логику из контролллера во врешний сервис, нашел в примерах на stackoverflow, и теперь это работает :)
источник

nt

nur tlek in Angular-universal-ru
понял
источник

YG

Yurii Gavdan in Angular-universal-ru
nur tlek
понял
источник

YG

Yurii Gavdan in Angular-universal-ru
nur tlek
понял
It’s not a good idea to inject Renderer2 in Service.
источник

IF

Igor Filippov in Angular-universal-ru
Есть еще вопросик. angular 9 - билжу в прод моде, в рантайме такой вот сообщение заходит Angular is running in the development mode. Call enableProdMode() to enable the production mode.
источник

IF

Igor Filippov in Angular-universal-ru
Хотя на 9ке уже ж не ставится enableProdMode() ..я вот в стартере смотрю, там ничего такого нет
источник

MH

Max Horobets in Angular-universal-ru
Igor Filippov
Хотя на 9ке уже ж не ставится enableProdMode() ..я вот в стартере смотрю, там ничего такого нет
Столкнулся с такой же проблемой. Дописал в server.ts enableProdMode(), работает стабильно.
источник

P

Pappu in Angular-universal-ru
Hi everyone,
I am struggling to render root url as SSR but i did not found any solution, can anyone help me to resolve this.
источник

P

Pappu in Angular-universal-ru
источник

P

Pappu in Angular-universal-ru
please can anyone help me to get rid of this problem,  I am new to nodejs.
источник

EB

Evgeny Berkus in Angular-universal-ru
Pappu
Hi everyone,
I am struggling to render root url as SSR but i did not found any solution, can anyone help me to resolve this.
Hello, did you read it? https://angular.io/guide/universal
источник