I want my Angular7 code to take a URL that contains a route and present desired updated meta tags to Twitter so that Twitter will render the correct social card.
Following standard practices for meta tags, which includes declaring in index.html header and updating in constructors of pages loaded by routes, I can see the correct updated values in the browser console, but twitter ignores those updates and uses the first meta tags from index.html.
From index.html...
<head>
<title>My Title</title>
<!-- Other Tags -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@myAccountName">
<meta name="twitter:title" content="My Title">
<meta name="twitter:description" content="A detailed description of the site">
<meta name="twitter:image" content="https://www.oursite.com/welcome.png">
From app.module.ts…
import { mySubComponent } from './components/mySub/mySub.component';
...
const appRoutes: Routes = [
...
{ path: 'mySubPage', component: mySubComponent },
...
From the .ts file for the module loaded by www.oursite.com/mySubPage...
import { Router, ActivatedRoute, Params } from '@angular/router';
import { Meta, Title } from '@angular/platform-browser';
@Component({
selector: 'app-mySub',
templateUrl: './mySub.component.html',
styleUrls: ['./mySub.component.css']
})
export class mySubComponent implements OnInit {
...
constructor(
...
public meta: Meta, public title: Title) {
meta.updateTag({ name: 'twitter:card', content: 'summary_large_image' });
meta.updateTag({ name: 'twitter:site', content: '@myAccountName});
meta.updateTag({ name: 'twitter:title', content: 'My Sub Title' });
meta.updateTag({ name: 'twitter:description', content: 'The descript of the sub page' });
meta.updateTag({ name: 'twitter:image', content: 'https://www.oursite.com/mySubPageLogo.png' });
}
When I run this in the browser and manually type the full URL with the route (www.oursite.com/mySubPage, the console Inspector shows all the correct settings...
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@myAccountName">
<meta name="twitter:title" content="My Sub Title">
<meta name="twitter:description" content="The descript of the sub page">
<meta name="twitter:image" content="https://https://www.oursite.com/mySubPageLogo.png">
But the twitter card validator set to the exact same Sub URL shows the card from the main index.html and appears to ignore the updates from the route altogether.
By the way, I did attempt all steps to flush the twitter cache, and even waited for longer than 12 hours and tried again. But I can make an update to the main tags and the change shows up, so it's not a cache issue with twitter.
This following is from https://twittercommunity.com/t/not-whitelisted-unable-to-render-or-no-image-read-this-first/62736 It looks like unless someone knows of a different approach, they are basically saying we can't serve up different cards from different angular routes from the same app domain. You only get one. Notice they spell it out in the middle...
Before posting a Cards issue, please READ the following:
If you are posting about any issue with your site, please include a
link to the publically-accessible URL where your Card markup is
visible, or we will be unable to help you.
You should also make sure that you’ve checked the items below, and
perform your own troubleshooting before asking for additional help.
Posts that indicate that none of these checks have been performed will
not be prioritised for attention.
As of early 2018, cards no longer require whitelisting (including
player cards)
The not whitelisted error message from the Validator is misleading, and almost certainly means that the tool cannot see or
find any twitter:card markup in your page.
If you see a message saying that you need to submit your card for approval, you’ve probably specified an incorrect card type in the
markup.
Please review the following if you are having other issues:
when you view the source of your page, the expected Twitter Cards meta tags 581 are shown
NB at a minimum, your page must contain at least a twitter:card meta tag specifying a valid card type 370, or suitable OpenGraph
fallback tags 170.
if you execute curl -v -A Twitterbot at the command prompt, does your page still show the twitter:card tags in the section
of the page? Does your server return a 200 response code and a valid
Content-Type header?
is your page adding the tags after it is loaded, for instance using Javascript (e.g. Angular, Meteor, Google Tags Manager)? The
crawler and validator cannot execute Javascript and the tags must be
static.
is your site accessible by the Twitterbot/1.0 user-agent? Are all the files (including image files) accessible to Twitterbot? you should
check http://your-site-url/robots.txt 646 and ensure that it allows
access to our crawler. If your images are on a different domain, also
make sure you check the robots.txt file for that domain.
are you using a Wordpress (or other CMS/blogging platform) plugin? We provide our own official Wordpress plugin 614, but cannot easily
provide support for those built by third parties. Check that the
configuration includes all of the required tags. Avoid using multiple
plugins at the same time, as tags will override one another.
are you putting the top-level site URL into the Validator, or the specific URL where your markup is present? you’ll need to make sure
that you provide a link to where your Card markup is visible in the
page.
are you using a supported 370 Card type? Product, Gallery and Photo cards were deprecated in mid-2015 128. Is the card type spelled
correctly, or is there a typo?
if your image is not showing, is it accessible on a URL that is not blocked by your robots.txt file? Does it conform to our size
constraints? Are you using an absolute and full URL (including the
http protocol piece), not a relative one?
if you see a validator message about Fetching the page failed because other errors or similar, check your SSL configuration. The
certificate and server name must match (or be aliased to match) due to
Java security constraints. More in this thread 220.
are you using a fully qualified DNS domain name? The crawler does not support dotted IP addresses as domain references, and cannot
access localhost.
There is much more Troubleshooting 302 information on our Developer
site.
Looks like there's no work-around for Angular7 at this time. Apparently there can be only one card, served up statically from on index.html per angular domain name.
Are you using a firebase as a BaaS? If so I was able to get twitter to render cards by doing exactly what you were doing above(setting up a service or inserting Meta tags into components). this lesson helped me out https://fireship.io/lessons/angular-universal-firebase/ , but base on my issue besides it having anything to do with being firebase app, my universal would not serve into the browser under app-root. I did not have to render any meta tags in my default index.html. Check the tutorial above and see if that helps out your issue at all.
https://angular.io/guide/universal
// Sub-Component
import { Component, OnInit } from '@angular/core';
import { Title, Meta } from '@angular/platform-browser';
@Component({
selector: 'app-about',
templateUrl: './about.component.html',
styleUrls: ['./about.component.scss']
})
export class AboutComponent implements OnInit {
data = {
name: 'Michael Jordan',
bio: 'Former baseball player',
image: ''
};
constructor(private title: Title, private meta: Meta) {}
ngOnInit() {
this.title.setTitle(this.data.name);
this.meta.addTags([
{ name: 'twitter:card', content: 'summary' },
{ name: 'og:url', content: '/about' },
{ name: 'og:title', content: this.data.name },
{ name: 'og:description', content: this.data.bio },
{ name: 'og:image', content: this.data.image }
]);
}
}