Skip to content

Best Practices ​

1. Validate Templates in CI ​

typescript
import { readFile } from 'node:fs/promises';
import { validateTemplate } from 'janja';

for (const file of templateFiles) {
  const { valid, errors } = await validateTemplate(await readFile(file, 'utf-8'));

  if (!valid) {
    console.error(file, errors);
    process.exitCode = 1;
  }
}

2. Reuse One Renderer ​

The compile cache lives on the Renderer. Create one at startup and reuse it rather than building new options on every request. If your templates never change while the process runs, set cache.revalidate: false to skip re-reading included templates.

3. Pre-compile for Production ​

bash
janja compile ./templates ./dist/templates --recursive

4. Keep Auto-Escaping On ​

Leave autoEscape enabled and mark trusted HTML explicitly with the safe filter or new Safe(html). Read SECURITY.md before rendering templates written by people you do not trust.

5. Decide How Errors Surface ​

Let errors throw in development and tests. In production either catch them around render(), or pass a debug handler that reports to your error tracker and lets the page render without the broken part.

6. Organize Templates with Blocks ​

janja
{{# base.janja #}}
<html>
<head>
  {{ block head }}<title>Default Title</title>{{ endblock }}
</head>
<body>
  {{ block content }}Default content{{ endblock }}
</body>
</html>
janja
{{# page.janja #}}
{{ include "base" }}
{{ block head }}<title>My Page</title>{{ endblock }}
{{ block content }}<h1>My Content</h1>{{ endblock }}

Released under the MIT License.