So I built an app using MEAN.js, and I made some updates to the Articles (blog) section for better SEO, readability, design, etc. One problem I can't seem to figure out, though, is how to share the Articles using Facebook, Google+, Twitter, etc. and have them populate the right data using og meta tags.
WHAT I WANT
All I want is to be able to share Articles (blog posts) from my MEAN.js application, and have the article content show up when I post the link in Social sites (e.g. Facebook).
WHAT I HAVE TRIED
I've tried creating a separate server layout specifically for blog posts, but this breaks so many other things that I realized the amount of work probably wasn't worth it - there has to be a smarter way.
I've also tried updating og meta tag data with Angular on the client side, but these values must not get updated before Social sites grab those tags...in other words, it didn't actually do what I wanted it to.
I've tried grabbing the Angular route URL when the index is rendering so I can update those og meta values before the index is rendered, but I can't find these values anywhere in the req
data.
WHAT I THINK THE PROBLEM IS
Conceptually, this is what I believe is happening:
The request hits my server, but since it's a single page application using Angular's routing, the
req.url
value is simply the root page ('/').The index file gets loaded, which uses the standard server template layout.
Angular gets loaded and makes an AJAX call to get the Article data, then binds that data to the variables on the page.
So basically the layout is getting rendered (with the og meta values) before Angular even figures out what article information to grab.
WHAT I'M GUESSING THE IDEAL SOLUTION IS
In my express.js
file, the app's local variables are set as follows:
// Setting application local variables
app.locals.siteName = config.app.siteName;
app.locals.title = config.app.title;
app.locals.description = config.app.description;
app.locals.keywords = config.app.keywords;
app.locals.imageUrl = config.app.imageUrl;
app.locals.facebookAppId = config.facebook.clientID;
app.locals.jsFiles = config.getJavaScriptAssets();
app.locals.cssFiles = config.getCSSAssets();
These local variables are then rendered by Swig in the layout.server.view.html
file as follows:
// Note the {{keywords}}, {{description}}, etc. values.
<!-- Semantic META -->
<meta id="keywords" name="keywords" content="{{keywords}}">
<meta id="desc" name="description" content="{{description}}">
<!-- Facebook META -->
<meta id="fb-app-id" property="fb:app_id" content="{{facebookAppId}}">
<meta id="fb-site-name" property="og:site_name" content="{{siteName}}">
<meta id="fb-title" property="og:title" content="{{title}}">
<meta id="fb-description" property="og:description" content="{{description}}">
<meta id="fb-url" property="og:url" content="{{url}}">
<meta id="fb-image" property="og:image" content="{{imageUrl}}">
<meta id="fb-type" property="og:type" content="website">
<!-- Twitter META -->
<meta id="twitter-title" name="twitter:title" content="{{title}}">
<meta id="twitter-description" name="twitter:description" content="{{description}}">
<meta id="twitter-url" name="twitter:url" content="{{url}}">
<meta id="twitter-image" name="twitter:image" content="{{imageUrl}}">
So ideally I think we want to update these values with Article specific information before rendering the page. The problem is, if the layout gets rendered before Angular even figures out which article data to populate, how can I do this? Again, the Angular route doesn't appear to be available anywhere in the req
object, so I'm completely stumped on how to do this.
So I go back to my original desire - how can I share my articles on social media in a "pretty" way using MEAN.js? Am I on the right track? Is it possible with the current Article setup? Do I need to build a complete blogging module that doesn't use Angular at all?