'How to use dynamic page titles in sails.js >v1.0?

For the last few days I was looking for a viable solution in order to optimize html page titles <title>SOME_TITLE</title> within sails.js layout files, like layout.ejs, that by default use a static page title.
Obviously, it would be way better to have dynamic page titles, e.g. Dashboard, Shopping Cart, etc...
Other people were looking for this answer before and got answers for prior sails versions in Solution 1, Solution 2 and Solution 3. Unfortunately, none of them seem to be appropriate for the latest version of sails.js (as of this post).

Solution 1 was leading in the right direction and suggested what I was looking for. But you had to define a title for every controller and pass it into the view. Otherwise you will get

title is not defined at eval

So how to define a local variable that is accessible in each controller/view by default?



Solution 1:[1]

So one working complete solution for the current sails.js version is the following:

In your layout.ejs file define a dynamic page title like this

<head>
  <title>
    <%= title %>
  </title>
  ...
</head>
...

Create a new custom hook, e.g. api/hooks/dynamic-page-title/index.js

module.exports = function dynamicPageTitleHook(sails) {

  return {
    routes: {
      /**
       * Runs before every matching route.
       *
       * @param {Ref} req
       * @param {Ref} res
       * @param {Function} next
       */
      before: {
        '/*': {
          skipAssets: true,
          fn: async function(req, res, next){
            // add page title variable to each response
            if (req.method === 'GET') {
              if (res.locals.title === undefined) {
                res.locals.title = 'plusX';
              }
            }
            return next();
          }
        }
      }
    }
  };

};

Now overwrite the page title in every controller that should use a custom page title, e.g. view-login.ejs

module.exports = {


  friendlyName: 'View login',


  description: 'Display "Login" page.',


  exits: {

    success: {
      viewTemplatePath: 'pages/entrance/login',
    },

    redirect: {
      description: 'The requesting user is already logged in.',
      responseType: 'redirect'
    }

  },


  fn: async function (inputs, exits) {

    if (this.req.me) {
      throw {redirect: '/'};
    }

    return exits.success({title: 'Login'});

  }


};

Solution 2:[2]

module.exports = {


  friendlyName: 'View homepage or redirect',


  description: 'Display or redirect to the appropriate homepage, depending on login status.',


  exits: {

    success: {
      statusCode: 200,
      description: 'Requesting user is a guest, so show the public landing page.',
      viewTemplatePath: 'pages/homepage'
    },

    redirect: {
      responseType: 'redirect',
      description: 'Requesting user is logged in, so redirect to the internal welcome page.'
    },

  },


  fn: async function () {
    if (this.req.me) {
      throw {redirect:'/welcome'};
    }
    return {title: 'Home page'};
  }
};

e.g: return (title: 'Home page')

Solution 3:[3]

I use version 1.4 of sails

I have add to the file layout.ejs the following code

<% if (typeof pagetitle=="undefined"){%>
    <title>write your default title</title>
   <% }else{%>
      <title><%= pagetitle %></title>
    <%}%>

    <% if (typeof pagemetadescription=="undefined"){%>
    <m?t? n?m?="d???r??t??n" ??nt?nt="write your default metadescription"></m?t?>
    <% }else{%>
    <m?t? n?m?="d???r??t??n" ??nt?nt="<%= pagemetadescription %>"></m?t?>
    <%}%>

If in controller, i return variable pagetitle or pagedescription, they will be add to layout. Otherwise, the default value will be print.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Tigerbui
Solution 3 Antoine Moulin