Ad

How To Show Page Title On Google With Angular Precomposition?

Based on superluminary response here I've set up an Angular 1 app without Hashbangs and html5Mode(true) and rely on Google to execute javascript. The page is being indexed by Google but dynamic titles and description tags are not.

My index.html head is the following:

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <base href="/">

    <meta name="author" content="me">
    <meta name="robots" content="index,follow">

    <title ng-bind="meta.title">Temp Title</title>
    <meta name="description" content="{{meta.description}}">

    <!-- Scripts & CSS -->
</head>

The title and description are correctly loaded but they don't display on Google.

How can I do that?

Also does this technique works with Facebook and other social networks? Thank you.

Ad

Answer

Actually superluminary response here has the solution. HTML page head must be sent fully resolved by the server.

So in order for this solution to work I was forced to replicate angular routes in the server side and send the info resolved.

Instead of using a plain html view I changed to .ejs and also changed the header to something like this:

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <base target="_blank" rel="nofollow noreferrer" target="_blank" rel="nofollow noreferrer" href="/">

    <meta name="robots" content="index,follow">

    <script type="text/javascript"> 
        window.title = <%- JSON.stringify(precomposition) %>.title;
    </script> 

    <title ng-bind="title"><%= precomposition.title %></title>
    <meta name="description" content="<%= precomposition.description %>">
    <!-- More meta information -->
    <!-- Scripts & CSS -->
</head>

Now when the website gets a direct hit (initially resolved by the server instead of Angular, always the case for crawlers) I handle the request server side:

//Express route
app.route('/').get(precomposition.render);

//precomposition
exports.render = function (req, res) {
    const precomposition = {title: 'tile', description: 'description'};
    res.locals.precomposition = precomposition;
    res.render('index.ejs');
};

If it's not a direct hit Angular handles the title update (because the other info is not displayed to the user).

It has off course some downsides but Google since October 2015 recommends this approach instead of "_escaped_fragment_ URLs". Also I think it's a lot less resource consuming than the selfhosted pre-render alternatives and cheaper than the paid ones.

Ad
source: stackoverflow.com
Ad