I'm working on an Angular 14 app and I trying to make twitter cards with dynamic routes. The case is the following:
I have an online store that shows different products, obviously is the same route just changing the product info by a param in the route
{ path: 'product/:id', component: ProductLayoutComponent, children: [{ path: '', loadChildren: () => import('./pages/section-custom/modules/product/product.module').then(m => m.ProductComponent) }, ] }
This page has two buttons to share the link of the product on Facebook and Twitter, here is the code
productId: string; constructor(public activatedRoute: ActivatedRoute) { this.activatedRoute.params.subscribe((params) => { this.productId = params['id']; }); } shareFacebook() { const facebookshare = 'https://www.facebook.com/sharer/sharer.php?u=' + this.productId; window.open(facebookshare, '_blank'); } shareTwitter() { const facebookshare = 'https://twitter.com/intent/tweet?url=' + this.productId; window.open(facebookshare, '_blank'); }
Every product has its own image, title and description to appear in the Twitter card and Facebook post, after many days of researching I understand that the social network crawler need to read some meta tags to show correctly the post and cards, so when I load the product I have this function:
productId: string; constructor(public activatedRoute: ActivatedRoute: public http: HttpClient, private metaService: Meta) { this.activatedRoute.params.subscribe((params) => { this.productId = params['id']; this.loadResources(); }); } loadResources() { this.http.get(`https://backend.demo.com/product/${this.productId}`).subscribe(data => { const shareLink = `${document.location.origin}/product/${this.productId}`; this.metaService.addTags([ { name: 'twitter:card', content: 'summary_large_image' }, { name: 'twitter:title', content: data.title }, { name: 'twitter:description', content: data.description }, { name: 'twitter:image', content: data.image }, { name: 'twitter:domain', content: shareLink }, { name: 'og:type', content: 'website' }, { name: 'og:url', content: shareLink }, { name: 'og:title', content: data.title }, { name: 'og:description', content: data.description }, { name: 'og:image', content: data.image }, ]); }); }
I already know that the previous solution doesn't work because angular is a Single Page Application and the Crawlers do not execute JavaScript. So I implemented Angular Universal to use Server Side Rendering, but SSR doesn't work because the browser is still the tool to render the app and the Crowlers do not recognize the meta tags.
So now I'm trying to implement the Pre-Render strategy, but for some reason, it seems not working for this case because Crawlers don't know there is a root with and specific code for example "https://www.myfakesite.com/product/AAE607" to get the specific image, title and description when the link is copied and pasted, even when I do the pre-render
I think that robots.txt and sitemap.xml could be involved but I don't know how. (The product database is created in another system, so as the product ID)
So my question is, how can I share the twitter card and Facebook post with dynamic image, title and description depending on a dynamic route in angular?