Data file location
All variable data lives in the datas/html/ directory of your site. Each language has its own JSON file named with the language code:
websites/your-site/datas/html/ en.json English (default language) tr.json Turkish de.json German ar.json Arabic fr.json French ...
Every language file shares the same key structure. Only the values differ. The build reads each file independently and produces a complete set of HTML output for that language.
JSON structure
The JSON file is organized into a general section for site-wide values and a pages section for page-specific values. Keys in both sections mirror the page and section hierarchy of your site.
{ "general": { "site_name": "My Site", "site_description": "A description of my site.", "contact_email": "hello@example.com", "language": { "code": "en", "type": "ltr" } }, "pages": { "home": { "title": "Home | My Site", "meta_description": "Welcome to my site.", "hero_heading": "Welcome", "hero_subheading": "Great things live here." }, "about": { "title": "About | My Site", "meta_description": "Learn about what we do.", "heading": "About Us" } }}Variable syntax
In HTML templates and page files, variables are referenced using curly brace syntax: { variable_key }. The build substitutes these placeholders with the corresponding values from the JSON data file for the language being processed.
<h1>{ hero_heading }</h1><p>{ hero_subheading }</p><a href="mailto:{ contact_email }">{ contact_email }</a>Variable keys are flat strings regardless of their nesting in the JSON file. The build flattens the merged data object before substitution, so { hero_heading } works even though it is nested under pages.home in the JSON.
How variables are resolved
For each page, the build constructs the variable scope by merging two sources:
General keys
All keys from the general object are loaded first. These are available to every page and template on the site.
Page-specific keys
The keys from the matching page entry under pages are merged on top. If a key exists in both general and the page object, the page value wins.
This means you can define a default meta_description in general and override it per page under pages without repeating it for every page that uses the default.
The ! main_tags ! directive
The ! main_tags ! include directive is a special composite directive that injects the complete document preamble — the opening <html> tag with the correct lang and dir attributes, the <head> element with charset, viewport, canonical, title, meta description, Open Graph tags, Twitter Card tags, and JSON-LD schema markup. All values come from the merged variable scope for that page and language.
| Sub-directive | Content injected |
|---|---|
!top! | The <!DOCTYPE html> declaration and opening <html> tag with language attributes. |
!title! | The <title> tag populated from the {title} variable. |
!seo! | Meta description, canonical URL, Open Graph, Twitter Card, and JSON-LD schema tags. |
In practice, you always use ! main_tags ! at the top of every page file. It handles all head content automatically from the JSON data.
Asset injection
Versioned CSS and JS file paths are also injected through the variable system. The asset injection syntax uses a colon-delimited key that mirrors the source file path:
<link rel="stylesheet" href="/css/main/pages/home.css"><script src="/js/main/pages/home.js"></script>
After the CSS and JS pipeline stages run, the build writes the physical versioned paths (e.g. /css/main.abc123.css) into datas/html.json under the corresponding keys. When HTML pages are processed, these placeholders are replaced with the actual paths. This ensures browser caches are automatically invalidated whenever a CSS or JS file changes.
datas/html/en.json, force an HTML rebuild by writing {} to store/times/release/html.json before running the build to ensure all pages pick up the new values.