3

I am working on a small blogging app. The application has a backend (made in PHP) that spits out JSONs.

These are managed and displayed by an AngularJS (version 1.7.8) frontend.

The index.html file looks like this:

<!-- Header -->
<header id="header">
  <div class="logo"><a href="/">{{siteTitle}}</a></div>
</header>

<!-- Main -->
<section id="main">
  <div class="inner" ng-view></div>
</section>

<!-- Footer -->
<footer id="footer">
  <div class="container">
    <ul class="icons">
      <li><a href="{{twitter}}" target="_blank" class="icon fa-twitter"><span class="label">Twitter</span></a></li>
      <li><a href="{{facebook}}" target="_blank" class="icon fa-facebook"><span class="label">Facebook</span></a></li>
      <li><a href="{{instagram}}" target="_blank" class="icon fa-instagram"><span class="label">Instagram</span></a></li>
      <li><a href="mailto:{{company_email}}" class="icon fa-envelope-o"><span class="label">Email</span></a></li>
    </ul>
    <ul class="icons">
      <li ng-repeat="page in pages">
        <a href="pages/page/{{page.id}}">{{page.title}}</a>
      </li>
    </ul>
  </div>
  <div class="copyright">
    &copy; {{companyName}}. All rights reserved. Design by <a href="https://templated.co" target="_blank">TEMPLATED</a>
  </div>
</footer>

The list of posts and single post templates are displayed via the $routeProvider

angular.module('app', [
    'ngRoute',
    'app.controllers',
    'ngSanitize'
]).config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
    $routeProvider.when('/', {
        templateUrl: 'themes/caminar/templates/posts.html',
        controller: 'PostsController'

    }).when('/:slug', {
        templateUrl: 'themes/caminar/templates/singlepost.html',
        controller: 'SinglePostController'

    }).otherwise({
        redirectTo: '/'
    })
}])

The posts.html file:

<div class="spotlight" ng-repeat="post in posts" ng-if="$index > 0" ng-class="{ '': $even , 'alt': $odd }">
    <div class="image flush">
        <a href="{{post.slug}}">
            <img ng-src="api/assets/img/posts/{{post.post_image}}" alt="{{post.title}}" />
        </a>
    </div>
    <div class="inner">
        <h3>{{post.title}}</h3>
        <p>{{post.description}}</p>
        <div ng-class="{ 'text-right': $even , 'text-left': $odd }">
            <a href="{{post.slug}}" class="button special small">Read More</a>
        </div>
    </div>
</div>

The singlepost.html file:

<div class="content">
    <h2>{{post.title}}</h2>

    <p class="meta clearfix">
        <span class="pull-left">By <a href="posts/byauthor/{{post.author_id}}" title="All posts by {{post.first_name}} {{post.last_name}}">{{post.first_name}} {{post.last_name}}</a></span>

        <span class="pull-right">Published on {{post.created_at  | dateParse | date : "MMMM dd y"}} in <a href="categories/posts/{{post.cat_id}}" title="All posts in {{post.category_name}}">{{post.category_name}}</a></span>
    </p>

    <div class="image fit">
        <img ng-src="api/assets/img/posts/{{post.post_image}}" alt="{{post.title}}">
    </div>

    <div class="post-content" ng-bind-html="post.content"></div>
</div>

The application works well, but it does have a flaw: it is not SEO friendly: while inspecting the single posts shows all its rendered code correctly, viewing the source ([CTRL] + [U] in Chrome) reveals:

<section id="main">
    <div class="inner" ng-view></div>
</section>

I have been unable to find a way to show all the content in the page source, not only in the Chrome inspector.

Seositecheckup.com gives me this preview:

enter image description here

In other words, I am looking for a server-side rendering method in AngularJS. How can I achieve that?

Razvan Zamfir
  • 4,209
  • 6
  • 38
  • 252
  • The page source never gets modified by script...it is only what gets sent from server – charlietfl Sep 07 '19 at 18:12
  • 1
    Your test for SEO is not so good, you need to check if Google able to understand your app, I've an AngaulrJS app the gets indexed properly (without any SSR), Google runs JS when it crawls the page. – felixmosh Sep 07 '19 at 19:14
  • @charlietfl This is what I was thinking of: a server-side rendering method in AngularJS. – Razvan Zamfir Sep 08 '19 at 04:59
  • how about https://stackoverflow.com/questions/16232631/angularjs-server-side-rendering ? – skyboyer Sep 08 '19 at 05:23

1 Answers1

0

While Angular (current versions 7x) can be used as server side rendered for this purpose, the code you show is for Angularjs (v 1.9x). This will make your work harder to be SEO friendly.

Now I do recommend you to read, and test prerender.io middleware / service, it will give your app supper powers on this field, I can say it will be the solution, but it might help or even be the solution you are looking for.

The Prerender.io middleware that you install on your server will check each request to see if it's a request from a crawler. If it is a request from a crawler, the middleware will send a request to Prerender.io for the static HTML of that page. If not, the request will continue on to your normal server routes. The crawler never knows that you are using Prerender.io since the response always goes through your server. -- prerender.io

Check : https://prerender.io

Good luck.

Pablo Palacios
  • 2,767
  • 20
  • 37
  • Prerender is great but unfortunately not *free*. – Razvan Zamfir Sep 09 '19 at 20:18
  • It is not free «they have a free limited/option», but if you want a 'free' solution, I recommend you to re write all the code on the latests Angular, Vue or React versions that are compatible with SSR. If not you are out of luck. Now if it is a small, personal project, probably the free prerender.io account can be the solution. – Pablo Palacios Sep 09 '19 at 22:28
  • My project is open-source. – Razvan Zamfir Sep 10 '19 at 20:05