skip to Main Content

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.

2

Answers


  1. Chosen as BEST 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 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.


  2. Why you don’t use something like that?

    https://github.com/steeve/angular-seo

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search