Setting Page Title Dynamically In AngularJS WordPress Theme

Changing the page title dynamically is an important feature in our AngularJS WordPress Theme. If you have checked some articles related to this topic, you might find it’s a bit hard to integrate those methods to our theme. There are two reasons:

  1. We just moved the ng-app="app" from html to #page div, that means the title element is beyond the scope of our app. Most of the tutorials use the $scope.title approach to change page title, unfortunately it won’t work with our theme.
  2. Most tutorials will predefine a title for each route, for example there are 3 files a.html, b.html and c.html, and their titles are like Page A, Page B and Page C. In such scenario it’s much easier to get and set the page title on $routeChangeSuccess event. But our case is a bit different that we’ll need to get a post from WP API first to know what the title is.

This post from stackoverflow gave me an idea to change the title with the global variable document. Here’s the snippet I use to change the page title dynamically (line 7, line 14).

Note that I use document.querySelector('title').innerHTML rather than document.title, so special characters like HTML entities won’t be decoded. You can get full project files from the GitHub repo.

If you have any question related to my AngularJS WordPress theme series, just leave a comment here, I’ll get back to you as soon as I can.

I’m a senior web developer helping clients build their websites to grow businesses. Currently I’m based in Taipei, Taiwan.

I write things about WordPress, AngularJS and life. Whenever you’d like to find someone to talk about these topics, just get in touch!

23 Comments

Submit a comment
  • Interesting approach, however it doesn’t ensure proper post sharing on Facebook. Source code for the FB debugger remains unchanged. Still looking for another way.

    • I’ve got some ideas working out this issue. Will do some tests and post the solution if I can find one.

  • Thank you Yoren. I would really appreciate your insight. Anyway I’m doing my own research in this matter, as it also important when it comes to SEO. Unfortunately most tutorials I’ve found take the title from route, not from the post controller.

    PS. Before I got here, I got that as simple as this:
    document.title = res.title;

    • Hey Maciej,

      I found a solution by Michael Bromley who is an experienced AngularJS developer: https://github.com/michaelbromley/angular-social-demo

      He provided an ultimate solution to enable rich social media sharing of your AngularJS app, I haven’t tested it yet but I believe it should fix the problem.

      To me because I still make my Angular app a standard WordPress theme, I can take advantages of wp_title() to provide the right title of each page for social media scrapper. I can even insert those open graph meta tags for them. In my opinion it’s kind of like Michael’s solution which depends on a server-side PHP scripts.

      Let me know your thoughts. Thanks.

    • My theory to deal with social media scrappers or some search engines that can’t process javascript generated content, is that we should still render the page (title, content, meta tags etc.) with PHP, and only manipulate the page when the user interact with it (i.e. click a post title to view the whole post).

      So what I mentioned about the wp_title() is that just something like < ?php wp_title(); ?>, and < ?php wp_head(); ?> in .

      In that way we’ll output those info by PHP by default, that when a scraper visits the page, it can get correct info, just like any human who visit the page in the browser.

      But I also want to note that such method should only work if you set the Angular route path the same as the WordPress permalink structure. If they are not consistent with each other, my theory won’t work.

      I’m going to host a live site to test my theory. I’d love to share here and also love to know your thoughts. Thanks.

  • My question is, what is the best solution. What does the .htaccess file look for? The one guys solution is not for a wordpress APP, so the .htaccess file is already doing a rewrite. How do you do the rewrite considering the wordpress rewrite is already there?

    • Hi, Philip,

      Please note our AngularJS WordPress theme is still a standard WP theme, so the .htaccess still works if there is one.

      Technically we are not “rewriting” the routes in our Angular scripts, we just make them be consist with the WP permalink structure.

      So when WordPress sends a user to our app, Angular will know which controller and template it should call, and gets the right content back.

  • Hey Yoren,

    I found little correction in a code.

    // Old
    document.querySelector(‘title’).innerHTML = res.title + ‘ | AngularJS Demo Theme’;

    // Need to be updated
    document.querySelector(‘title’).innerHTML = res[00.title + ‘ | AngularJS Demo Theme’;

    Thanks.

  • Hey really great tutorials,they really made me start out!
    But I’m struggling on one thing,if i need to use Wp functions in the /partials folder they shoot undefined.Do you have any workaround for have wp functions at disposal in the partials called by ng-routing?

    • Hey Kolima, we can’t call wp functions in the files in partials directory, they should be only as the templates for AngularJS. So basically if you follow this series of tutorials, you’ll need to get those data from WP API with Angular controllers, and then display them with directives or the curly braces notations {{}}.

      • So, i encountered this “error” while trying to setup a theme_options for some example textfield.I guess then the only workaround could be create a CPT for this fields and call it within WP Api.

  • isn’t it a bad practice to change the html content from the app.controler ?
    is there an other way to do it ( using directives ? )

    • Well, basically this tut just demonstrated what we can do but not always the best practice. I may use a service for that in the later tutorials. Can’t really recall it…

Submit a comment

Your email address will not be published. Required fields are marked *