Cant use EJS hook showing error TypeError: ctx.render is not a function

What is the bug?
I am trying to render a page using strapi-hook-ejs but it is not working even I followed all official documentation.

It is giving following error
[2020-10-13T03:34:15.198Z] error TypeError: ctx.render is not a function
at Object.page (C:\Users\noman\Desktop\TestAPI\api\home\controllers\home.js:11:20)
at dispatch (C:\Users\noman\Desktop\TestAPI\node_modules\koa-router\node_modules\koa-compose\index.js:44:32)
at next (C:\Users\noman\Desktop\TestAPI\node_modules\koa-router\node_modules\koa-compose\index.js:45:18)
at dispatch (C:\Users\noman\Desktop\TestAPI\node_modules\koa-compose\index.js:42:32)
at C:\Users\noman\Desktop\TestAPI\node_modules\strapi\lib\middlewares\router\utils\routerChecker.js:79:28
at dispatch (C:\Users\noman\Desktop\TestAPI\node_modules\koa-compose\index.js:42:32)
at module.exports (C:\Users\noman\Desktop\TestAPI\node_modules\strapi-plugin-users-permissions\config\policies\permissions.js:86:9)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async C:\Users\noman\Desktop\TestAPI\node_modules\strapi-utils\lib\policy.js:68:5
at async serve (C:\Users\noman\Desktop\TestAPI\node_modules\koa-static\index.js:59:5)
at async C:\Users\noman\Desktop\TestAPI\node_modules\strapi\lib\middlewares\xss\index.js:26:9
[2020-10-13T03:34:15.212Z] debug GET /home/page (39 ms) 500
[2020-10-13T03:34:15.255Z] debug GET /favicon.ico (1 ms) 200

Steps to reproduce the behavior

  1. I installed strapi-hook-ejs (npm i strapi-hook-ejs --save)
  2. Create a new hook.json file in config folder. (./config/hook.json)
  3. Added this code
{
    "ejs": {
        "enabled": true,
        "layout": false,
        "viewExt": "ejs",
        "partial": true,
        "cache": false,
        "debug": true
    }
}
  1. Created views folder and a home.ejs file in it (./views/home.ejs) with this code <h1><%=title%></h1>

  2. Then I created a new controller and point a route to it.

module.exports = {
    page: async ctx => {
        return ctx.render('home', {title: 'My app title'});
    },
};
  1. Now when I am going to this route I am getting the error.

Expected behavior
Should render home page

My Package.json

{
  "name": "source-api",
  "private": true,
  "version": "0.1.0",
  "description": "A Strapi application",
  "scripts": {
    "develop": "strapi develop",
    "start": "strapi start",
    "build": "strapi build",
    "strapi": "strapi"
  },
  "devDependencies": {},
  "dependencies": {
    "axios": "^0.20.0",
    "strapi": "3.1.4",
    "strapi-admin": "3.1.4",
    "strapi-connector-mongoose": "3.1.4",
    "strapi-hook-ejs": "^3.2.3",
    "strapi-plugin-content-manager": "3.1.4",
    "strapi-plugin-content-type-builder": "3.1.4",
    "strapi-plugin-email": "3.1.4",
    "strapi-plugin-upload": "3.1.4",
    "strapi-plugin-users-permissions": "3.1.4",
    "strapi-provider-upload-cloudinary": "^3.1.4",
    "strapi-utils": "3.1.4"
  },
  "author": {
    "name": "Nehal Ahmad"
  },
  "strapi": {
    "uuid": "1034d7e9-73ba-49d4-8862-0d5d62ae7008"
  },
  "engines": {
    "node": "12.x",
    "npm": "6.x"
  },
  "license": "MIT"
}

System

  • Node.js version: v12.18.1
  • NPM version: 6.14.5
  • Strapi version: 3.1.4
  • Database: Mongo db
  • Operating system: Windows 10 pro

I have also tried it on latest version of strapi.

Hey,
Is your hook.json right?

https://strapi.io/documentation/v3.x/concepts/hooks.html#structure

Yes, I already included my hook.json file’s code.
Anyway my hook.json contains following code

{
  "ejs": {
    "enabled": true,
    "layout": false,
    "viewExt": "ejs",
    "partial": true,
    "cache": false,
    "debug": true
  }
}

Yeah. I saw. In the doc the hook.js looks like this:

module.exports = {
  timeout: 2000,
  settings: {
    'hook-name': {
      enabled: true,
      timeout: 3000,
    },
  },
};

Here see the settings keyword.

I think it is the file when you create your own hook but I am using already available hook ‘strapi-hook-ejs’. You can see there documention here

By the way here is a file ./node_modules/strapi-hook-ejs/lib/index.js

'use strict';

/**

 * Module dependencies

 */

// Native

const path = require('path');

// Externals

const co = require('co');

const render = require('koa-ejs');

/**

 * EJS hook

 */

module.exports = function(strapi) {

  const hook = {

    /**

     * Default options

     */

    defaults: {

      root: path.join(strapi.config.appPath, strapi.config.paths.views),

      layout: 'layout',

      viewExt: 'ejs',

      cache: true,

      debug: true,

    },

    /**

     * Initialize the hook

     */

    initialize() {

      // Force cache mode in production

      if (strapi.config.environment === 'production') {

        strapi.config.hook.settings.ejs.cache = true;

      }

      render(

        strapi.app,

        Object.assign(this.defaults, strapi.config.hook.settings.ejs)

      );

      strapi.app.context.render = co.wrap(strapi.app.context.render);

    },

  };

  return hook;

};

Maybe its important to have the settings key. Maybe just rewrite it and try.

// check if a hook is enabled
  const hookEnabled = key => get(hookConfig, ['settings', key, 'enabled'], false) === true;

Sorry I can’t understand what should I do. Should I create a new hook.js file or what please explain me.

try this:
./config/hook.json

{
  settings: {
    "ejs": {
      "enabled": true,
      "layout": false,
      "viewExt": "ejs",
      "partial": true,
      "cache": false,
      "debug": true
    }
  }
}
1 Like

It Worked :star_struck:. Thank you very very much. I needed it so much. My project was on halt due to this. :smiling_face_with_three_hearts:

2 Likes