Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dynamically added meta tags does not recognize facebook #118

Open
8 tasks
mistrynilesh opened this issue Nov 7, 2017 · 53 comments
Open
8 tasks

dynamically added meta tags does not recognize facebook #118

mistrynilesh opened this issue Nov 7, 2017 · 53 comments
Labels

Comments

@mistrynilesh
Copy link

mistrynilesh commented Nov 7, 2017

I'm submitting a ... (check one with "x")

[ ] Support request => <!-- Please check the repository for a similar issue or PR before submitting -->

Current behavior

Expected/desired behavior

Minimal reproduction of the problem with instructions

import { MetaService } from '@ngx-meta/core';
import { FirstService } from './first.service';

export class FirstComponent {
      firstObj : any = {};

     constructor(private _metaService: MetaService,
                        private _firstService: FirstService) {}
      
     ngOnInit() {
             this._firstService.getQuestionOfTheWeek(0).subscribe(
                  res => firstObj = res,
                  error => this.errorGetRequest(error),
                  () => this.successGetRequest()
              );
       }

    successGetRequest(){
            this._metaService.setTag('og:description', this.firstObj .Desc);
            this._metaService.setTag('og:image', this.firstObj .ImageURL);
     }

}

What is the motivation / use case for changing the behavior?

Meta tag are getting added it is visible in the chrome developer tool but facebook does not recognize.

Environment

  • Angular version: 4.0.0
  • Browser:
  • Chrome (desktop) version XX
  • Chrome (Android) version XX
  • Chrome (iOS) version XX
  • Firefox version XX
  • Safari (desktop) version XX
  • Safari (iOS) version XX
  • IE version XX
  • Edge version XX
  • For Tooling issues:
  • Node version: XX
  • Platform:
  • Others:
@gianpaj
Copy link

gianpaj commented Nov 10, 2017

related to #101

this is because (i believe) the components code are executed on the client side and not at server rendering.

Perhaps this could work?
https://github.com/angular/universal#universal-gotchas

@mistrynilesh
Copy link
Author

@gianpaj I used server side rendering page but still not working. When I am doing view source on browser developer tool than meta tags are available. facebook Sharing Debugger doesn't shows OG tags.

@gianpaj
Copy link

gianpaj commented Nov 16, 2017

As mentioned in #101 , I used https://github.com/angular/universal-starter

How are you starting the server? I transpile/build it with npm run build:ssr and then start the server.js in the dist folder with npm run serve:ssr.

I have a very similar code:

export class ItemComponent implements OnInit {

  constructor(
    private route:         ActivatedRoute,
    private itemsService:  ItemsService, // my service
    private router:        Router,
    private readonly meta: MetaService
  ) { }

  ngOnInit() {
    this.route.params.subscribe((data: any) => this.itemsService.getItem(data.id)
      .subscribe((item: Item) => {
        this.item = item;
        this.meta.setTag('og:type', 'product');
        this.meta.setTag('og:image', item.photo);
...

@mistrynilesh
Copy link
Author

@gianpaj, Thanks.

I am also using default values to set OG tags-

export function metaFactory(): MetaLoader {
  return new MetaStaticLoader({
    pageTitlePositioning: PageTitlePositioning.PrependPageTitle,
    pageTitleSeparator: ' - ',
    applicationName: 'Tour of (lazy/busy) heroes',
    defaults: {
      'og:title': 'Mighty mighty mouse',
      'og:description': 'Mighty Mouse is an animated superhero mouse character',
      'og:image': 'https://d2y8liyagvllvg.cloudfront.net/images/website/nclexqow/20170801.png',
      'og:type': 'website',
      'og:locale': 'en_US',
      'og:locale:alternate': 'en_US,nl_NL,tr_TR'
    }
  });
}
 MetaModule.forRoot({
      provide: MetaLoader,
      useFactory: (metaFactory)
    }),

"og:image" rendered properly but "og:description" and "og:title" doesn't works. not showing facebook debugger.

@linusbrolin
Copy link

linusbrolin commented Nov 24, 2017

I still have the same problem aswell, just like I mentioned here: #101 (comment)

I think the reason its working for @gianpaj is simply timing, the Facebook crawler has a really low timeout, and for very basic apps such as the universal-starter, the time it takes to load the item in ngOnInit is probably fast enough for it to work, but if the loading time is slightly longer, then the Facebook crawler will get a timeout before the item has been loaded.

What we need is a router guard that collects the needed data from the server before activating the route, which will force the Facebook crawler to wait for that.

However, the only way I know about to do this in ngx-meta is to use a backend service similar to the ngx-translate example provided.
But, it seems that ngx-meta can only provide parameters with a fixed value to that backend service, from what I understand, not dynamic values like route ID's, etc.

If I'm wrong in that assumption then I would be very happy if someone can provide a howto on how to acheive what we need.

@gianpaj
Copy link

gianpaj commented Nov 24, 2017

I don't think that's true. I don't know the underlying reasons why exactly it works, but my SSR server runs properly and renders the correct meta-tags in the HTML.
View the source of this page for example: https://givebox.xyz/item/H1-ybixCZ

The og:image, og:url,og:title (and title) are dynamically generated.

I think you need to make sure you are running something like npm run build:ssr and npm run serve:ssr.

See the package.json
https://github.com/angular/universal-starter/blob/master/package.json#L24

@linusbrolin
Copy link

linusbrolin commented Nov 24, 2017

I am running a proper aot build with angular-cli.
When and how do you collect the correct image url for the og:image tag?
Because I can get the og:title to be set to what it should, but the og:image tag is simply not being set, despite the fact that I have created a router guard specifically for this that sets both the og:title and the og:image at the same time from the same data.

Edit:
Some source code example on how you set the og:image tag from dynamic data would be welcome.

Edit2:
I also want to clarify that I can get the og:image tag to work if I use the defaults, or if I specify a manual value, like in @mistrynilesh example.
It is only when the image url is retrieved dynamically that it doesn't work.
But the og:title does work, so it makes very little sense.

Edit3:
Here is a small code example of a route guard that collects the data and sets the tags, before activating the route:

@Injectable()
export class ProductMetaGuard implements CanActivate {
  constructor(private _platformLocation: PlatformLocation,
              private _productsService: ProductsService,
              private readonly meta: MetaService) {}

  canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return Observable.create((observer: any) => {
      let url: string = state.url;
      let id: string = next.params['id'];

      this._http
        .get(environment.apiUrl + '/products/' + id)
        .map((res: Response) => res.json())
        .subscribe(
          (val: Product) => {
            let metaSettings: any = (next && next.data && next.data['meta'])
              ? next.data['meta']
              : {};

            if (val && val.title) {
              metaSettings.title = val.title;

              if (val.image && this._platformLocation && this._platformLocation['location']) {
                metaSettings['og:image'] = this._platformLocation['location'].origin + '/images/products/' + val.image;
              }
            }

            this.meta.update(url, metaSettings);

            return observer.next(true);
          },
          (err: any) => {
            return observer.error(err);
          }
        );
    });
  }
}

It sets the og:title properly, but it does not set the og:image properly.
In the browser, the og:image is set, but not when I view source.
But og:title is set on both.

I do believe it might be platformLocation that screws it up.
However, how do I get the origin path during server rendering?
I do not want to hardcode a path, since the origin is dynamic.

@gianpaj
Copy link

gianpaj commented Nov 24, 2017

my component class implements OnInit (see #118 (comment)).
I've never used or heard of CanActivate. Hopefully somebody can guide you in the right direction

@linusbrolin
Copy link

CanActivate is used in the router, as a way to determine if a route is allowed or not, before the component is rendered.

As an update to the issue here, PlatformLocation was the reason that the image does not show up for me.
So for now I'm gonna have to live with hardcoding the image paths and just retrieve the filename itself from the server.

I still wish there was a way to do this kind of thing using the ngx-meta router MetaGuard, instead of having to either create my own custom router guard, or make calls in OnInit.
As it is now, I can only use the ngx-meta MetaGuard for non-dynamic content.

@fulls1z3 fulls1z3 changed the title Dynamically added meta tags does not recognize facebook dynamically added meta tags does not recognize facebook Jan 7, 2018
@cahkee
Copy link

cahkee commented Jan 9, 2018

Any update on this issue? I'm also encountering the same issue @linusbrolin reported when the tags are dynamically retrieved from an API rather than being hard-coded. @linusbrolin did you end up resolving your issue?

@linusbrolin
Copy link

@cahkee No, not really.
I'm still hard-coding the paths and then use an API to retrieve the filenames.
It's ugly, but works for now.

@chozharajan
Copy link

chozharajan commented Mar 14, 2018

@gianpaj can you share your full code for meta update because am getting error in .subscribe((item: Item) => {
can't find name Item am also using same Repo from https://github.com/angular/universal-starter and ngx-meta

  1. if i update manually its work --- this.meta.setTag('og:image', 'cAngulsadasdar 4 meta service');
  2. but when i update after API call its not reflected in view source(Cntrl + U) --- this.meta.setTag('og:description', res[i].DocDesc);. any one help me out from this

@gianpaj
Copy link

gianpaj commented Mar 14, 2018

@chozharajan my code is like #118 (comment)

I don't understand the error you're mentioning: can't find name Item.

Maybe open a StackOverflow question with the code, error message, or even better, a repo to reproduce, and the link to the SO question, and I'll try to help.

@chozharajan
Copy link

@gianpaj thanks for your kind replay. can you share your full code. so it's helpful to build my app. because am also using same as your project. hlp me out
my main issue is ---(when i update after API call its not reflected in view source(Cntrl + U))

@kylecordes
Copy link

Reading through all the conversation, the result is not exactly clear. Here is what I think everything above means: to make this work with Facebook it is necessary to:

  • Use server-side rendering
  • arrange things such that routing waits for the data for the meta-tags
  • ... and thus that the meta-tags end up already populated in the <head> of the statically served prerendered content

Is that correct?

@linusbrolin
Copy link

@kylecordes If the content you want to use for the facebook meta-tags is dynamically collected via an api, based on the id and other variables you get from the route, then yes.

@chozharajan
Copy link

chozharajan commented Mar 27, 2018

Hi, finally my project work well in local. but once deployed in server. i got view source (cntrl + U) but meta update not happening. i used npm run build:prerender cmd for build the project my reference Repo. and i placed dist/browser files in root directory. here is my project Link. so how to make meta update possible. NOTE: in local am getting meta update for npm run build:ssr cmd. i think am wrongly doing the build cmd. so how to deploy the universal project in IIS server. thanks in advance

@canpalte
Copy link

canpalte commented Jul 3, 2018

Hi, how do you do to work well? do you use canactive to set meta before render??

@bharath-holla
Copy link

@kylecordes, @linusbrolin,
any update on this issue? have you been able to find an alternative? My issue is the same as the original problem explained in the ticket. As long as the static content is provided, it appears in facebook crawler. Any dynamic content coming from a http api never appears in the crawler.

@kylecordes
Copy link

@bharath-holla Yes, we had to do what I wrote above. Server-side render the pages so that Facebook can pick up the fields. In our case it is very slowly changing content so we did server side pre-rendering on a schedule. If your data is changing frequently,instead you would do server-side rendering on demand. There's plenty to read about angular Universal to make this happen, but the net result is you'll be serving HTML with all of the data already populated, which Facebook can parse to get its fields.

@bharath-holla
Copy link

bharath-holla commented Jul 26, 2018

@kylecordes,
Thanks, and even we found a similar solution yesterday. We modified server.ts to make a backend call and populated the index.html contents before issuing it to the renderer. And with that Facebook started to pickup the contents that renderer provided and tags started to appear in the FB Sharing Debugger. Thanks anyway.

@ishan123456789
Copy link

HI, @bharath-holla can you please share the changes you made in server.ts as I'm stuck with this issue for quite while now.

@thecoconutstudio
Copy link

@bharath-holla @ishan123456789 I'm also stuck on this, please are you able to share your solution. My meta tags are showing fine when viewing page-source, but not coming through via Facebook.

@ishan123456789
Copy link

@thecoconutstudio not able to get it fixed for a while now. Really depressing problem.

@bharath-holla
Copy link

bharath-holla commented Jan 7, 2019

@ishan123456789 @thecoconutstudio Somehow the emails got filtered out and I never observed these comments from both of you.

The below code is of course the most horrible hack, but it worked for me when no other solution on net was working. Till Angular team provides a fix, we decided to go with this.

Here's my partial code.

//all imports
enableProdMode();

export const app = express();

const mysql = require('mysql');
const httpRequest = require("request");
// all other consts

app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}));
//all other piece of code in server.ts

app.get('/*', (req, res) => {
  res.render('index', {req, res}, (err, html) => {
    if (html) {
        
        //console.log(html);
        // This is where you get hold of HTML which "is about to be rendered"
    
        // after some conditional checks make a HTTP call
        let url = 'http://....';
        httpRequest.get(url, (error, response, body) => {
                        if(error) {
                            return console.log(error);
                        }
                        const respBody = JSON.parse(body);
                        if(respBody){
                              html = html.replace(/\$TITLE/g, respBody.title);
                              html = html.replace(/\$DESCRIPTION/g, respBody.description);
                              html = html.replace(/\$OG_META_KEYWORDS/g, respBody.metaKeywords);
                              html = html.replace(/\$OG_META_DESCRIPTION/g, respBody.metaDescription);
                              html = html.replace(/\$OG_DESCRIPTION/g, respBody.ogDescription);
                              html = html.replace(/\$OG_TITLE/g, respBody.ogTitle);
                              html = html.replace(/\$OG_IMAGE/g, respBody.img);
                              html = html.replace(/\$OG_SITE/g, respBody.ogSite);
                        }
                        res.send(html);
            });
     }
  }
}

And in index.html, create template values as below:

     
    <title>$TITLE</title>

    <meta name="description" content="$DESCRIPTION"/> 
    <meta name="keywords" content="$OG_META_KEYWORDS" />
    <meta name="metaDescription" content="$OG_META_DESCRIPTION"/> 
    <meta name="metaKeywords" content="$OG_META_KEYWORDS" />
    <meta property="og:title" content="$OG_TITLE" />
    <meta property="og:description" content="$OG_DESCRIPTION" />
    <meta property="og:site_name" content="$OG_SITE" /> 
    <meta property="og:type" content="website" />	
    <meta property="og:image" content="$OG_IMAGE" />

@matbalazsi
Copy link

Depressing was a good word for it. Has anyone else found a working solution? If not, I'll look into the @bharath-holla (I would need to hack it further for it to work for my needs)
Thanks!

@stevesaw
Copy link

I am facing this problem as well. Anyone got a better working solution for this?

@maseranw
Copy link

@bharath-holla , can you please provide me with your source code?

@KateDobrilko
Copy link

@bharath-holla's solution is really the best I've managed to find after 3 days of searching and experimenting with different solutions. Thanks!

@maseranw
Copy link

maseranw commented Jun 2, 2019

im still unable to implement it, can you provide will full server.ts imports ?

@MikeG96
Copy link

MikeG96 commented Aug 11, 2019

This it's mi PoC, I add validations for get the params, and I add a promise depending on params. I know this code can improve, but it's a PoC

"use strict";

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

import * as express from "express";
import { join } from "path";

// SEO
const url = "YOUR_URL_API";
const url_img = url + "/img";
const api_url = url + "/api";

// Express server
const app = express();

// Http Request
const request = require("request-promise");

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), "dist/browser");

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {
  AppServerModuleNgFactory,
  LAZY_MODULE_MAP,
  ngExpressEngine,
  provideModuleMap
} = require("./dist/server/main");

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine(
  "html",
  ngExpressEngine({
    bootstrap: AppServerModuleNgFactory,
    providers: [provideModuleMap(LAZY_MODULE_MAP)]
  })
);

app.set("view engine", "html");
app.set("views", DIST_FOLDER);

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

// All regular routes use the Universal engine
app.get("*", (req, res) => {
  var seo: any = {
    title: "YOUR DEFAULT TITLE",
    description:
      "DEFAULT DESCRIPTION",
    image: "YOUR DEFAUL ROUTE IMAGE"
  };
  res.render("index", { req, res }, async (err, html) => {
    const params = req.params[0];
    if (params.indexOf("talento/") > -1) {
      let id = params.split("/");
      id = params[params.length - 1];
      id = Number(id);
      if (!isNaN(id) || Math.sign(id) > 0) {
        const talent = await getTalent(id);
        seo.title = talent.name;
        seo.description = strip_html_tags(talent.description);
        seo.image = `${url_img}/${talent.image}`;
      }
    }
    html = html.replace(/\$TITLE/g, seo.title);
    html = html.replace(/\$DESCRIPTION/g, strip_html_tags(seo.description));
    html = html.replace(/\$OG_DESCRIPTION/g, seo.description);
    html = html.replace(/\$OG_TITLE/g, seo.title);
    html = html.replace(/\$OG_IMAGE/g, seo.image);
    res.send(html);
  });
});

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

function strip_html_tags(str) {
  if (str === null || str === "") {
    return false;
  } else {
    str = str.toString();
    return str.replace(/<[^>]*>/g, "");
  }
}

async function getTalent(id): Promise<any> {
  try {
    const options = {
      uri: `${api_url}/services/${id}`,
      json: true
    };
    const res = await request(options)
      .then(repos => {
        return repos.response;
      })
      .catch(err => {
        return err;
      });
    return res;
  } catch (err) {
    return err;
  }
}


@Ilyoskhuja
Copy link

@bharath-holla I changed my server.ts like your code but it cant update meta tags, view source doesnt shows new metatags value
Screen Shot 2019-09-30 at 20 40 36

@MikeG96
Copy link

MikeG96 commented Sep 30, 2019

@bharath-holla I changed my server.ts like your code but it cant update meta tags, view source doesnt shows new metatags value
Screen Shot 2019-09-30 at 20 40 36

Because, this is only for response in server-side

@Ilyoskhuja
Copy link

@MikeG96 I want that when I get responce from backend api it will change meta tags and show in "view source page", my app showed changed metatags in "inspect" view, but in "view source page" doesnt changed, and in facebook or other messangers shows link without any updated metatags.

@Ilyoskhuja
Copy link

Do you have any solution for shows updated meta tags on facebook or other messengers ?

@MikeG96
Copy link

MikeG96 commented Sep 30, 2019

Do you have any solution for shows updated meta tags on facebook or other messengers ?

This is an example of the "dirty solution" if you have your backend in JS #118 (comment)

For Angular, you need update metas with a service, docs: https://angular.io/api/platform-browser/Meta

@Ilyoskhuja
Copy link

Ilyoskhuja commented Sep 30, 2019

@MikeG96 My backend asp.net core 2.1, I can update my meta tags but when I open "view source page" from console it doesnt shows updated meta tags, and when i share my link in facebook also doesnt shows updated meta tags
Screen Shot 2019-09-30 at 20 40 36
Screen Shot 2019-09-30 at 21 50 33

@ghost
Copy link

ghost commented Oct 24, 2019

Worked as expected @MikeG96 @bharath-holla, was out of nowhere but this small forum helped me solve the nightmare of 2 days. Just to help @Ilyoskhuja, make sure you have the correct route setup in your server.ts file and also check if there are multiple res.send() or res.render() blocks in your app.get(*).

Thanks with regards,
Praveen Thirumurugan.

@Ilyoskhuja
Copy link

I already fixed, my problem was in prerendering.

@rasyad
Copy link

rasyad commented Dec 17, 2019

I already fixed, my problem was in prerendering.

i have the same exact problem as yours. I can update the meta tags, shown in inspector, but nowhere to be seen in view source (ctrl+u) how did you solve this?

@Ilyoskhuja
Copy link

@rasyad You should check your prerendering code especially with backend part

@kasius
Copy link

kasius commented Mar 17, 2020

Has anyone solved this issue ?, managing to publish a link on facebook linkedin and that these platforms recognize the og tags corresponding to each route?

@MikeG96
Copy link

MikeG96 commented Jun 4, 2020

Hello everyone, after doing more research and seeing that my "solution" mentioned above was not the best and much less was it in line with good practices, I finally solved the SEO issue with Angular SSR, I share my repository

https://gitlab.com/mikeag96/angular-ssr

@FabrizioBilleciUNICT
Copy link

Hello everyone, after doing more research and seeing that my "solution" mentioned above was not the best and much less was it in line with good practices, I finally solved the SEO issue with Angular SSR, I share my repository

https://gitlab.com/mikeag96/angular-ssr

Please, can you explain your solution? I'm already working with an Angular SSR project and a service to update meta tags, but crawlers don't recognize "in time" the changes.

@MikeG96
Copy link

MikeG96 commented Jun 8, 2020

Hello everyone, after doing more research and seeing that my "solution" mentioned above was not the best and much less was it in line with good practices, I finally solved the SEO issue with Angular SSR, I share my repository
https://gitlab.com/mikeag96/angular-ssr

Please, can you explain your solution? I'm already working with an Angular SSR project and a service to update meta tags, but crawlers don't recognize "in time" the changes.

What are your doubts?

@evyperez
Copy link

Hello everyone, after doing more research and seeing that my "solution" mentioned above was not the best and much less was it in line with good practices, I finally solved the SEO issue with Angular SSR, I share my repository

https://gitlab.com/mikeag96/angular-ssr

I tested using your solution and meta tags worked on Facebook and Twitter, but it looks like the standard meta tags didn't work. I tested using https://metatags.io. Did you have this problem too?

@MikeG96
Copy link

MikeG96 commented Jun 30, 2020

Hello everyone, after doing more research and seeing that my "solution" mentioned above was not the best and much less was it in line with good practices, I finally solved the SEO issue with Angular SSR, I share my repository
https://gitlab.com/mikeag96/angular-ssr

I tested using your solution and meta tags worked on Facebook and Twitter, but it looks like the standard meta tags didn't work. I tested using https://metatags.io. Did you have this problem too?

which are your "standard" tags?

@faizaldong
Copy link

faizaldong commented Feb 7, 2021

Hello everyone, after doing more research and seeing that my "solution" mentioned above was not the best and much less was it in line with good practices, I finally solved the SEO issue with Angular SSR, I share my repository
https://gitlab.com/mikeag96/angular-ssr

Please, can you explain your solution? I'm already working with an Angular SSR project and a service to update meta tags, but crawlers don't recognize "in time" the changes.

What are your doubts?

@https://github.com/MikeG96

So the different in your changes was just
{ provide: 'NgxRequest', useValue: req, }, { provide: 'NgxResponse', useValue: res, }, in server.ts?
and to update the metatags, just use the meta service from Angular. rite?

@faizaldong
Copy link

faizaldong commented Feb 7, 2021

I just added this { provide: 'NgxRequest', useValue: req, }, { provide: 'NgxResponse', useValue: res, } in server.ts and updated the meta tags with Angular Meta service but it doesn't work.
The meta tags can be seen in Element but not in page view source.

@nikhilbhalwankar
Copy link

nikhilbhalwankar commented Feb 14, 2021

app.get('/*', (req, res) => {
res.render('index', {req, res}, (err, html) => {
if (html) {

    //console.log(html);
    // This is where you get hold of HTML which "is about to be rendered"

    // after some conditional checks make a HTTP call
    let url = 'http://....';
    httpRequest.get(url, (error, response, body) => {
                    if(error) {
                        return console.log(error);
                    }
                    const respBody = JSON.parse(body);
                    if(respBody){
                          html = html.replace(/\$TITLE/g, respBody.title);
                          html = html.replace(/\$DESCRIPTION/g, respBody.description);
                          html = html.replace(/\$OG_META_KEYWORDS/g, respBody.metaKeywords);
                          html = html.replace(/\$OG_META_DESCRIPTION/g, respBody.metaDescription);
                          html = html.replace(/\$OG_DESCRIPTION/g, respBody.ogDescription);
                          html = html.replace(/\$OG_TITLE/g, respBody.ogTitle);
                          html = html.replace(/\$OG_IMAGE/g, respBody.img);
                          html = html.replace(/\$OG_SITE/g, respBody.ogSite);
                    }
                    res.send(html);
        });
 }

}
}

HI @bharath-holla ... How to get the route params here? Can you please provide inputs? I need to get the product details and render meta tags based on productId route param.

@robjean9
Copy link

app.get('/*', (req, res) => {
res.render('index', {req, res}, (err, html) => {
if (html) {

    //console.log(html);
    // This is where you get hold of HTML which "is about to be rendered"

    // after some conditional checks make a HTTP call
    let url = 'http://....';
    httpRequest.get(url, (error, response, body) => {
                    if(error) {
                        return console.log(error);
                    }
                    const respBody = JSON.parse(body);
                    if(respBody){
                          html = html.replace(/\$TITLE/g, respBody.title);
                          html = html.replace(/\$DESCRIPTION/g, respBody.description);
                          html = html.replace(/\$OG_META_KEYWORDS/g, respBody.metaKeywords);
                          html = html.replace(/\$OG_META_DESCRIPTION/g, respBody.metaDescription);
                          html = html.replace(/\$OG_DESCRIPTION/g, respBody.ogDescription);
                          html = html.replace(/\$OG_TITLE/g, respBody.ogTitle);
                          html = html.replace(/\$OG_IMAGE/g, respBody.img);
                          html = html.replace(/\$OG_SITE/g, respBody.ogSite);
                    }
                    res.send(html);
        });
 }

}
}

HI @bharath-holla ... How to get the route params here? Can you please provide inputs? I need to get the product details and render meta tags based on productId route param.

Try adding

app.get('/custom-path/:param', (req,res) => {
  res.render('index', {req,res}, (err,html)=> {
     if(html){
       ....
     }
});
});

@NerminKarapandzic
Copy link

I had the same issue and I managed to solve it using resolvers.
The problem was when I would view page source after opening a dynamic route I would see meta tags and server side rendering, but facebook didn't see them.
So I used a resolver for that route to fetch the data before loading the component and then I took the data and set meta tags inside a constructor of that component. Maybe it would have worked inside ngOnInit as well but I didn't try.
Hopefully this will help some of you.

@MikeG96
Copy link

MikeG96 commented Jun 25, 2021

I had the same issue and I managed to solve it using resolvers.
The problem was when I would view page source after opening a dynamic route I would see meta tags and server side rendering, but facebook didn't see them.
So I used a resolver for that route to fetch the data before loading the component and then I took the data and set meta tags inside a constructor of that component. Maybe it would have worked inside ngOnInit as well but I didn't try.
Hopefully this will help some of you.

Check my repo: https://gitlab.com/mikeag96/angular-ssr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests