Koa EJS View Rendering Middleware

raw JSON →
4.3.0 verified Thu Apr 23 auth: no javascript

Koa-ejs is a middleware for the Koa.js framework that facilitates server-side rendering using the EJS templating engine. It provides seamless integration with Koa's context (`ctx.render`) to render EJS templates, supporting all features of the underlying EJS library, including layouts, partials (includes), and access to `ctx.state` for passing data to views. The current stable version is 5.1.0, and the project appears actively maintained with recent releases addressing bug fixes and EJS v3 compatibility. Its primary differentiator is its tight integration with the Koa ecosystem, offering a straightforward setup for server-rendered applications, making it a popular choice for traditional web server setups with Koa. The release cadence is somewhat infrequent but significant updates (like v5.0.0) introduce major changes and compatibility improvements.

error Error: Failed to lookup view "<template_name>" in views directory "<path_to_root>"
cause The template file specified in `ctx.render()` was not found in the configured `root` directory, or it has an incorrect file extension.
fix
Ensure the root option in render() points to the correct directory containing your EJS files. Verify the filename passed to ctx.render() (e.g., user for user.html) and that viewExt is correctly configured (default is 'html'). Check for typos in filenames and paths.
error ReferenceError: <variable_name> is not defined
cause A variable used within your EJS template was not passed as data to `ctx.render()` or made available through `ctx.state` before rendering. This often happens due to typos or forgetting to include a variable.
fix
Ensure all variables required by your EJS template are available either in ctx.state (e.g., ctx.state.title = 'My Page';) or as an object passed as the second argument to await ctx.render('template', { variableName: value });. Double-check variable names for exact matches.
error Error: Cannot find module 'koa-ejs'
cause The `koa-ejs` package is not installed in your project, or Node.js cannot resolve its path. This can occur after cloning a repository or due to issues with `node_modules`.
fix
Run npm install koa-ejs or yarn add koa-ejs in your project's root directory to install the package. If already installed, check your node_modules directory and ensure proper module resolution (e.g., for monorepos or when using custom module loaders).
breaking Version 5.0.0 of `koa-ejs` introduced significant changes, including an update to support EJS v3. Ensure your EJS templates and configurations are compatible with EJS v3 when upgrading to `koa-ejs` v5 or later. This might involve minor adjustments to template syntax or options if you were using older EJS versions.
fix Review EJS v3 migration guides for any breaking changes in template syntax or options (e.g., custom delimiters). Test existing templates thoroughly after upgrading to `koa-ejs` v5+.
gotcha The default value for the `cache` option in `koa-ejs` is `true`. While convenient for development, explicitly setting `cache: false` is often necessary during development to see template changes without restarting the server. In production, always ensure caching is enabled for optimal performance.
fix For development, set `cache: false` in the `render()` options. For production, ensure `cache: true` or rely on the default behavior. A common pattern is `cache: process.env.NODE_ENV === 'production'`.
gotcha The `v5.0.0` release notes mentioned 'rename package to @koa/ejs'. However, the `koa-ejs` package on npm still retains its original name and continues to be updated under `koa-ejs`. This can cause confusion regarding which package to install or import. The `koa-ejs` package is the canonical one for this project.
fix Continue to install and import the package as `koa-ejs`. If you encounter `@koa/ejs` in other contexts, be aware it might refer to an alternative or deprecated package that is not actively maintained by the `koajs` organization.
deprecated The `README` examples often use `require()` for imports, which is a CommonJS pattern. While still supported by Node.js, modern Koa applications increasingly adopt ESM. Mixing CJS and ESM can lead to module resolution issues or require specific configurations.
fix For new projects or when modernizing, use ESM imports (`import render from 'koa-ejs';`) and configure your project for ESM (e.g., `"type": "module"` in `package.json` and updating `__dirname` resolution for file paths).
npm install koa-ejs
yarn add koa-ejs
pnpm add koa-ejs

This quickstart demonstrates how to set up `koa-ejs` middleware for an ESM Koa application, configure view paths, enable/disable caching based on environment, handle `ctx.state` for global data, and render a template with a layout. It includes minimal example template content to make the code runnable and illustrate the basic functionality.

import Koa from 'koa';
import render from 'koa-ejs';
import path from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';

const __filename = fileURLToP<ctrl60>ath(import.meta.url);
const __dirname = dirname(__filename);

const app = new Koa();

// Configure EJS rendering
render(app, {
  root: path.join(__dirname, 'view'),
  layout: 'template', // Name of your layout file (e.g., template.html)
  viewExt: 'html',
  cache: process.env.NODE_ENV === 'production', // Cache templates in production
  debug: process.env.NODE_ENV !== 'production' // Debug mode in development
});

// Example route to render a view
app.use(async (ctx) => {
  const user = { name: 'Alice', age: 30 };
  // Add data to ctx.state to be accessible in templates
  ctx.state.title = 'User Profile';
  ctx.state.user = user;

  // Render 'user.html' template with layout 'template.html'
  await ctx.render('user', { message: 'Welcome back!' });
});

const port = process.env.PORT || 7001;
app.listen(port, () => {
  console.log(`Server running on http://localhost:${port}`);
});

// --- Create 'view' directory and 'user.html', 'template.html' files ---
// (Ensure you create these files in a 'view' folder next to your main script)

// Example content for view/user.html:
// <h1><%= title %></h1>
// <p>Hello, <%= user.name %>! You are <%= user.age %> years old.</p>
// <p><%= message %></p>

// Example content for view/template.html:
// <!DOCTYPE html>
// <html>
// <head>
//   <title><%= title %></title>
// </head>
// <body>
//   <h3>Header from layout</h3>
//   <%- body %>
//   <h4>Footer from layout</h4>
// </body>
// </html>