Nginx Config For Single Page Angularjs Website To Work With Prerender.io For Facebook Open Graph
I have a single page angularjs web app. I'm trying enable it to be crawlable by search engines. To achieve this I'm using prerender.io, a nodejs webserver with a phantomjs browser to render ajax pages.
I am basing my nginx config off the following gist: https://gist.github.com/Stanback/6998085
This works for the most part. I can curl my app and get the correct response:
curl -o test.html domain.com/?_escaped_fragment=/path
The request is redirected to the prerender.io proxy and the proxy makes a single request with the following url:
All other requests (js, img, css and xhr) pass through nginx as normal. Phantomjs has no trouble rendering the proxy request after waiting for the following JS variable to be set to true:
window.prerenderReady = false;
This is all great... Google can crawl my website! Enter Facebook.
I'm setting a number of OG metatags so that I can use the Facebook like button (iFrame). The following metatags are set for each page:
<link rel="canonical" target="_blank" rel="nofollow noreferrer" href="http://domain.com/#!/asset"> <meta property="og:url" content="http://domain.com/#!/asset"> <meta property="og:type" content="website"> <meta property="og:image" content="http://domain.com/image.jpg"> <meta property="fb:app_id" content="xxx"> <meta property="og:description" content="foo"> <meta property="og:title" content="bar"> <meta property="og:site_name" content="domain.com">
These metatags are updated correctly by angularjs for each asset and the phantomyjs proxy correctly waits for them to be updated before returning the response.
However when I test the URL
http://domain.com/#!/asset with the Facebook URL linter I get some problems.
- Facebook claims that the canonical URL and the og:url differ, however when I click "See exactly what our scraper sees for your URL" they are idential
- When I click "See exactly what our scraper sees for your URL" the canonical and og:url have been replaced with
- The proxy receives 3 requests. The first for the asset then it seems it follows the canonical and og:url
- When a user clicks the Like this page iFrame the link back to my website looks like
Number 4 is the issue that is a deal breaker. If a user likes a page on my post it goes into their Facebook activity stream. If that user then clicks on the link back to my site in their stream it will direct them through the proxy and render the page through phantomjs!
I'm guessing that I shouldn't be sharing the links with the hash-bang through Facebook. I think I should be sharing a link and setting the canonical / og:url to something like
domain.com/static/asset. The nginx config should be updated to catch
/static urls, if useragent = Facebook or params contain _escaped_fragment_ then direct to proxy else redirect the user to #!/asset.
I have tired all that I can think to get a modified nginx config to work with this however it has beaten me. When I intercept those
/static urls and rewrite to the proxy randomly image, css and js assets are requested through the proxy and phantomjs crashes.
Could someone please help me modify this nginx config so that I can forward web crawler requests to the proxy, allow facebook to scrape the correct og tags off my site AND have the correct link-back url specified when users share my content on Facebook?
Did you figure this out yet? Facebook doesn't do a very good job with #! urls. This StackOverflow answer does a good job explaining it: How to handle facebook sharing/like with hashbang urls?
When a user is on a page on your site (
http://domain.com/#!/asset) and does a sharing action on your website, it should share the canonical url
Then if a user visits
http://domain.com/asset, you just redirect them to
And if Facebook accesses the canonical URL (
http://domain.com/asset), then redirect it to your Prerender.io server.
Or...just switch from #! to html5 pushstate, and you won't have to do any of the #! redirecting for Facebook. That way the proxy becomes more simple, so you'd always just proxy any request from Facebook to your Prerender.io server
- → Import statement and Babel
- → Getting Comments of comments Facebook API
- → Facebook Developer API in reactjs code
- → Facebook PHP SDK - Graph Error "Authorization code has been used" on page refresh
- → How is possible to open website inside facebook mobile app like buzzfeed?
- → Laravel - set meta tag dynamically with @section
- → Do Flux (by Facebook) handle server side update with sockets
- → understanding of real example open graph protocol
- → flynsarmy-sociallogin (Facebook api) in octoberCMS - Authentication failed! Facebook returned an invalid user id
- → Open Graph data facebook
- → Putting Facebook photos on canvas, taint canvas when trying to send it toDataURL. Can I set Facebook's header for CORS?
- → OctoberCMS plugin SEO Meta Og image
- → Shopify + og:image resulting in "was not a valid URL."