Skip to content

How to Customize Templates

This guide shows you how to create and customize version file templates using Nagare’s Vento template engine. Use custom templates when built-in formats don’t meet your requirements.

Ensure you have:

  • Nagare configured in your project
  • Basic understanding of template syntax
  • Knowledge of the Vento template engine

Use this approach for standard version file formats.

  1. TypeScript template (default):

    versionFile: {
    path: "./version.ts",
    template: "typescript",
    }

    Generates:

    export const VERSION = "1.2.3";
    export const BUILD_INFO = {
    buildDate: "2025-01-11T12:00:00.000Z",
    gitCommit: "abc1234",
    };
  2. JSON template:

    versionFile: {
    path: "./version.json",
    template: "json",
    }

    Generates:

    {
    "version": "1.2.3",
    "buildInfo": {
    "buildDate": "2025-01-11T12:00:00.000Z",
    "gitCommit": "abc1234"
    }
    }
  3. YAML template:

    versionFile: {
    path: "./version.yaml",
    template: "yaml",
    }

Use this for basic customization needs.

  1. Custom TypeScript constants:

    versionFile: {
    path: "./src/constants.ts",
    template: "custom",
    customTemplate: `/**
    * Application version information
    * Generated by Nagare on {{ buildDate |> safe }}
    */
    export const APP_VERSION = "{{ version |> safe }}";
    export const BUILD_DATE = "{{ buildDateFormatted |> safe }}";
    export const GIT_SHA = "{{ gitCommit |> safe }}";
    export const GIT_SHA_SHORT = "{{ shortCommit |> safe }}";
    `
    }
  2. Custom configuration file:

    versionFile: {
    path: "./config/build.js",
    template: "custom",
    customTemplate: `// Build configuration
    module.exports = {
    version: "{{ version |> safe }}",
    buildTime: "{{ buildDate |> safe }}",
    commit: "{{ gitCommit |> safe }}",
    environment: "{{ environment.NODE_ENV || 'production' |> safe }}",
    };`
    }

Use Vento’s control structures for complex templates.

  1. Conditional exports based on metadata:

    versionFile: {
    path: "./version.ts",
    template: "custom",
    customTemplate: `export const VERSION = "{{ version |> safe }}";
    {{- if metadata.experimental }}
    export const EXPERIMENTAL_FEATURES = {{ metadata.experimental |> jsonStringify |> safe }};
    {{- /if }}
    {{- if environment.NODE_ENV === 'development' }}
    export const DEBUG_INFO = {
    commit: "{{ gitCommit |> safe }}",
    branch: "{{ metadata.branch |> safe }}",
    buildMachine: "{{ environment.HOSTNAME |> safe }}",
    };
    {{- /if }}
    export const VERSION_INFO = {
    major: {{ versionComponents.major |> safe }},
    minor: {{ versionComponents.minor |> safe }},
    patch: {{ versionComponents.patch |> safe }},
    {{- if versionComponents.prerelease }}
    prerelease: "{{ versionComponents.prerelease |> safe }}",
    {{- else }}
    prerelease: null,
    {{- /if }}
    };`
    }
  2. Multi-format export template:

    customTemplate: `// Version information in multiple formats
    // CommonJS
    exports.VERSION = "{{ version |> safe }}";
    // ES Module
    export const VERSION = "{{ version |> safe }}";
    // Global for browsers
    if (typeof window !== 'undefined') {
    window.APP_VERSION = "{{ version |> safe }}";
    }
    // AMD
    if (typeof define === 'function' && define.amd) {
    define([], function() {
    return { version: "{{ version |> safe }}" };
    });
    }`;

Use this to add custom exports to existing templates.

  1. Add configuration constants:

    versionFile: {
    path: "./version.ts",
    template: "typescript",
    additionalExports: [
    {
    name: "CONFIG",
    type: "const",
    value: {
    apiUrl: "https://api.example.com",
    timeout: 5000,
    retries: 3,
    },
    description: "Application configuration",
    asConst: true,
    },
    ],
    }
  2. Add utility functions:

    additionalExports: [
    {
    name: "getVersionString",
    type: "function",
    content: `(): string {
    return \`v\${VERSION} (\${BUILD_INFO.gitCommit.slice(0, 7)})\`;
    }`,
    description: "Get formatted version string",
    },
    {
    name: "VersionUtils",
    type: "class",
    content: `{
    static isNewer(other: string): boolean {
    return VERSION.localeCompare(other, undefined, { numeric: true }) > 0;
    }
    static getMajor(): number {
    return parseInt(VERSION.split('.')[0]);
    }
    }`,
    },
    ];

Include changelog information in version files.

versionFile: {
path: "./version.ts",
template: "custom",
customTemplate: `/**
* Version: {{ version |> safe }}
* Released: {{ buildDateFormatted |> safe }}
*/
export const VERSION = "{{ version |> safe }}";
export const CHANGELOG = {{ releaseNotes |> jsonStringify |> safe }};
export const RECENT_CHANGES = [
{{- for note in releaseNotes.added }}
"Added: {{ note |> safe }}",
{{- /for }}
{{- for note in releaseNotes.fixed }}
"Fixed: {{ note |> safe }}",
{{- /for }}
];`
}

Create version files for other languages.

versionFile: {
path: "./src/__version__.py",
template: "custom",
customTemplate: `"""
Package version information.
Generated by Nagare on {{ buildDate |> safe }}
"""
__version__ = "{{ version |> safe }}"
__git_commit__ = "{{ gitCommit |> safe }}"
__build_date__ = "{{ buildDateFormatted |> safe }}"
VERSION_INFO = {
"major": {{ versionComponents.major |> safe }},
"minor": {{ versionComponents.minor |> safe }},
"patch": {{ versionComponents.patch |> safe }},
"prerelease": {{ if versionComponents.prerelease }}"{{ versionComponents.prerelease |> safe }}"{{ else }}None{{ /if }},
}
`
}

All templates have access to these variables:

interface TemplateData {
// Version information
version: string; // "1.2.3"
versionComponents: {
major: number; // 1
minor: number; // 2
patch: number; // 3
prerelease?: string; // "alpha.1"
};
// Build information
buildDate: string; // ISO timestamp
buildDateFormatted: string; // Human-readable date
gitCommit: string; // Full commit hash
shortCommit: string; // Short commit hash (7 chars)
// Project information
project: {
name: string;
description?: string;
repository: string;
homepage?: string;
license?: string;
author?: string;
};
// Release information
releaseNotes?: {
added: string[];
changed: string[];
deprecated: string[];
removed: string[];
fixed: string[];
security: string[];
};
// Environment variables
environment: Record<string, string>;
// Custom metadata
metadata?: Record<string, any>;
// Utility
currentYear: number;
}

Use these filters to transform values:

  • |> safe - Output without escaping (for code generation)
  • |> escape - HTML escape (for HTML templates)
  • |> jsonStringify - Convert to JSON string
  • |> upper - Convert to uppercase
  • |> lower - Convert to lowercase

Test template rendering:

Terminal window
# Preview with dry run
deno task nagare --dry-run
# Check generated file
cat version.ts
# Validate syntax
deno check version.ts # For TypeScript

Problem: “Template processing failed” Solution: Check Vento syntax, especially |> for filters (not single |)

Problem: “Undefined variable in template” Solution: Check variable name matches TemplateData interface

Problem: “Invalid JSON in generated file” Solution: Use |> jsonStringify |> safe for JSON values