Creating websites with Statify

This manual explains how to author the source files that Statify turns into a static website. For installation, CLI commands, template selection, and deployment, see the main Tool Manual.

Statify supports two complementary page formats:

  • Markdown pages for documentation, articles, policies, embedded YouTube videos, image carousels, and other content-oriented pages;
  • JSON pages for landing pages and structured widget layouts such as cards, FAQs, carousels, and video sections.

A single site may use both formats. The selected template provides the metadata, browser application, styles, and examples needed by the renderer.

Start with a template

Create a site from the template closest to the intended result:

statify init my-site documentation
statify init my-site landing
statify init my-site landing-rich

Use documentation for a Markdown-first manual, landing for a compact JSON landing page, and landing-rich as a reference for advanced widgets and media.

Do not reinitialize an existing site. Inspect and edit its metadata.json, pages/, assets/, and custom stylesheet instead.

The templates contain fictional organizations, placeholder legal text, example URLs, and demonstration media. Replace those values before publishing.

Source layout and output mapping

A typical Statify source site looks like this:

site/
  package.json
  metadata.json
  images.json
  pages/
    index.md or index.json
    guide/
      index.md
      installation.md
    res/
      diagram.webp
  assets/
    app/
      website.css
      website.min.js
      webfonts/
    res/
      custom.css
      logo.svg

Build it from inside the site directory:

statify folder .

The default output is .dist/. Statify walks pages/ recursively and applies these rules:

Source                              Output
pages/index.md                      .dist/index.html
pages/index.json                    .dist/index.html
pages/guide/installation.md         .dist/guide/installation.html
pages/res/diagram.webp              .dist/res/diagram.webp
assets/res/custom.css               .dist/res/custom.css
assets/app/website.min.js           .dist/app/website.min.js

Markdown and JSON files beneath pages/ become HTML. Other page files are copied unchanged. The contents of assets/ are copied into the output root.

Both pages/res/ and assets/res/ therefore produce /res/... URLs:

  • use pages/res/ for files owned by a page or nearby content;
  • use assets/res/ for shared logos, styles, images, and media;
  • use other assets/ subdirectories for global output directories—for example, assets/app/ becomes /app/.

Do not define the same output path in both pages/ and assets/. Preserve an existing site's resource partition unless there is a concrete reason to move files.

Configure site-wide metadata

Begin with the selected template's metadata.json. The renderer expects its established structure, so editing a known template is safer than creating the file from scratch.

Update at least:

  • the site title and description;
  • the canonical origin and social sharing image;
  • site.name, site.url, and site.domain;
  • author and publisher;
  • icons, stylesheets, scripts, and font paths in head;
  • navigation, documentation, and breadcrumb URLs.

site.domain is required. Keep the canonical origin consistent across the metadata. Use example.com only for an explicitly fictional or unfinished site.

Head resources

Entries in head use t for the HTML element name. The remaining properties become ordinary attributes:

{
  "t": "link",
  "rel": "stylesheet",
  "href": "app/website.css"
}

The same convention is used for icons, custom stylesheets, browser scripts, and other resources already demonstrated by the templates. Preserve their relative paths unless the corresponding files also move.

Primary navigation entries live in navibar.links. Begin with the template's working navigation and update its labels and URLs.

A separator or flexible spacer is represented by:

{
  "SPACER": {
    "separator": true
  }
}

Keep navigation routes consistent with the generated HTML paths. Verify every navigation target after building the complete site.

Construct documentation pages with Markdown

Markdown is the preferred page format for documentation and long-form text. Place .md files anywhere beneath pages/; directories become matching URL directories.

Example:

pages/
  index.md
  guide/
    index.md
    installation.md
    configuration.md
  reference/
    commands.md

This can represent an arbitrary documentation tree. Use one H1 for the page title, then meaningful H2 and H3 sections:

# Installation

A short summary of what the reader will accomplish.

## Requirements

- Node.js 18 or newer
- A writable project directory

## Install the package

```sh
npm install --save-dev example-package
```

## Verify the installation

Run the following command:

```sh
example-package --help
```

Statify supports ordinary inline Markdown, images, tables, task lists, fenced code, and headings. Headings form the page outline and documentation navigation, so use them in a logical order.

Relative Markdown links are rewritten to generated page routes. Prefer links relative to the source page:

[Installation](guide/installation.md)
[Configuration](configuration.md)

For an image stored beside page resources:

![Configuration screen](res/configuration.webp)

After reorganizing folders, check both links and image paths in the generated site.

YouTube and image carousels in Markdown

Statify's Showdown extensions support richer media directly in Markdown, so a page does not need to be converted to JSON just to include a video or image carousel.

Insert a YouTube video by placing @yt- immediately before its video ID:

@yt-<VIDEO_ID>

For example, combine the prefix @yt- with the video ID YECe-5fc5bU. Use a real video ID supplied by the content owner or verified from its source, and do not publish third-party material without the appropriate rights.

Create an image carousel with ordinary image elements inside .item-image-carousel:

<div class="item-image-carousel">
    <img class="fadein" src="https://nebular.tv/doc/res/sdk/overlay-sdk-catalogue.webp">
    <img class="fadein" src="https://nebular.tv/doc/res/sdk/overlay-sdk-ai-2.webp">
    <img class="fadein" src="https://nebular.tv/doc/res/sdk/overlay-sdk-tactical-3.webp">
</div>

The fadein class applies the expected carousel transition. Confirm that each image exists at its final output URL and uses suitable dimensions. When an image conveys important information, provide equivalent explanatory text near the carousel.

The documentation template includes example policy pages. Replace their organization, jurisdiction, dates, practices, storage keys, and contact details. They are structural examples, not legal advice or reviewed policies.

Construct landing pages with JSON

JSON pages are objects rendered by a named widget. Begin with templates/landing/pages/index.json; consult templates/landing-rich only when an advanced pattern is relevant.

The common landing-page shell uses the FeatureList widget:

{
  "widget": "FeatureList",
  "title": "Company name",
  "canonical": "https://example.com",
  "features": {
    "title": {
      "items": []
    },
    "cards": []
  },
  "footer": {
    "links": []
  }
}

Use the exact property names and nesting demonstrated by a template. CSS class strings are presentation hooks provided by the browser application and local stylesheet; reuse known classes instead of inventing behavior that the selected stub does not provide.

Text and headings

A content item may define an element, text, and presentation classes:

{
  "el": "h2",
  "text": "A useful heading",
  "class": "accent"
}

Choose elements semantically. Keep one primary page heading and use lower-level headings in order.

Images

An image item supplies a site URL, alternative text, and optional classes:

{
  "image": "/res/product.webp",
  "alt": "The product dashboard showing weekly activity",
  "class": "shot col-12"
}

Always provide useful alt text unless the image is purely decorative. Verify that the source file maps to the same output URL—for example, assets/res/product.webp produces /res/product.webp.

A link item is represented by a nested link object:

{
  "link": {
    "text": "Get started",
    "href": "/docs/start",
    "class": "accentbutton"
  }
}

Use descriptive link text and real destinations. Distinguish deliberate external links from site-relative paths.

Cards and nested content

Feature sections may contain cards. Cards can contain items, nested cards, and optional links. Begin with the closest example in the landing template and replace its content without changing unrelated structure.

Keep nesting shallow unless the demonstrated layout genuinely requires another level. A small number of clear sections is easier to read and maintain than reproducing every pattern from the rich reference.

Add media

The rich landing template demonstrates structured local video, consent-aware YouTube content, and image carousels for JSON pages. Markdown pages can also embed YouTube and carousels using the Showdown syntax described above.

Local video

Use features.video for a local background or showcase video:

{
  "url": "/res/videos/showcase",
  "title": "Product showcase",
  "autoplay": true,
  "muted": "muted",
  "loop": true
}

The URL follows the media-basename convention used by the rich template. Confirm that all required encoded files exist beneath pages/res/ or assets/res/.

Autoplay video must remain muted. Important information must also be available as text or another accessible form; never make a video the only explanation of a product or action.

YouTube

Use a youtube content item for a consent-aware embed:

{
  "youtube": {
    "ref": "VIDEO_ID",
    "image": "/res/video-poster.webp",
    "title": "Descriptive video title",
    "class": "smallervideo"
  }
}

Use a real video ID supplied by the content owner or verified from its source. Provide a local poster image and a descriptive title. Do not invent video IDs or publish third-party material without the appropriate rights.

Image carousels

imageCarousel accepts an array of objects with url values:

{
  "imageCarousel": [
    {"url": "/res/gallery/one.webp"},
    {"url": "/res/gallery/two.webp"},
    {"url": "/res/gallery/three.webp"}
  ]
}

Keep image dimensions and aspect ratios reasonably consistent to reduce layout movement. Provide contextual text outside the carousel when the images convey important information.

Construct an FAQ page

FAQ pages use the Faq widget and faq.mainEntity. Every entry contains a question in name and a Markdown-capable answer in acceptedAnswer:

{
  "widget": "Faq",
  "title": "Frequently asked questions",
  "faq": {
    "mainEntity": [
      {
        "name": "How do I get started?",
        "acceptedAnswer": "Install the package, initialize a template, and run `npm start`."
      },
      {
        "name": "Where is the generated website?",
        "acceptedAnswer": "The default output directory is **.dist/**."
      }
    ]
  }
}

Keep answers direct, factual, and self-contained. Do not use FAQs to introduce unsupported promises, invented policies, or unreviewed legal claims.

Configure decorative images

images.json supplies decorative image data in an Unsplash-compatible shape. Start from the template's working structure. Preserve attribution fields for third-party images, and do not invent attribution or remove licensing information merely to simplify the data.

Decorative imagery should not contain information that is absent from the page's accessible text.

Customize the local stylesheet

The compiled application stylesheet normally lives at assets/app/website.css. It contains shared responsive layout, widgets, and skin behavior. Do not edit it during ordinary site authoring because replacing the application stub would overwrite those changes.

Put site-specific branding and page presentation in the template-local stylesheet, normally:

assets/res/custom.css

Statify's shared skin is driven by CSS variables. Use :root for values shared by both modes, .skinroot.light for light-only overrides, and .skinroot.dark for dark-only overrides.

Minimal accent configuration

Most sites can begin by changing only the accent variables:

:root {
    --accent: #ff8800;
    --accent-tx: rgba(255, 136, 0, 0.5);
}

--accent-tx should be a translucent version or visual companion of the main accent. Check buttons, links, focus states, and text placed over the accent in both skins.

When the same accent does not provide enough contrast in both modes, scope it:

.skinroot.light {
    --accent: #b74d00;
    --accent-light: #fff1e6;
    --text-over-accent: #ffffff;
    --text-over-accent-hover: #ffffff;
}

.skinroot.dark {
    --accent: #ff9d3d;
    --text-over-accent: #111111;
    --text-over-accent-hover: #000000;
}

Core surface and text variables

Variable Role
--window-background Main application background
--window-background-0 Lowest dark-skin surface step
--window-background-1 First raised dark-skin surface step
--window-background-2 Second raised dark-skin surface step
--window-background-3 Third raised dark-skin surface step
--window-background-hi Highlighted or raised surface
--window-background-lo Recessed light-skin surface
--primary-color Primary chrome or strong surface color
--black Stable black token
--text Main text color
--text-lo Secondary or subdued text
--border-color Borders and separators
--placeholder Placeholder or empty-state surface
--inputs Input background
--shadow-color Shadow color

The numbered background variables originate in the dark skin, while --window-background-lo originates in the light skin. Define a fuller set in both modes only when custom components require it.

Accent and foreground variables

Variable Role
--accent Primary brand and action color
--accent-tx Translucent or softer decorative accent
--accent-light Pale accent surface, especially in light mode
--accent-alt Alternate accent
--text-over-accent Text placed over the main accent
--text-over-accent-hover Hover text over the main accent
--text-over-primary Text placed over the primary surface
--text-over-primary-hover Hover text over the primary surface

Treat each foreground/background combination as a pair. A visually attractive accent is unusable if its overlaid text lacks contrast.

Status and overlay variables

Variable Role
--back-success Success-message background
--back-warning Warning-message background
--back-error Error-message background
--bg-ok Strong success indicator
--bg-warning Strong warning indicator
--bg-error Strong error indicator
--alpha-band Translucent band or overlay
--alpha-gradient Overlay or gradient endpoint
--green Generic green utility color
--orange Generic orange utility color
--red Generic red utility color

Preserve recognizable success, warning, and error meaning. The strong status variables originate in the light skin; add dark-mode values only when the components using them need different contrast.

Section backgrounds

The .back-zero, .back-one, .back-two, and .back-three helpers consume matching variables:

Variable Intended role
--back-zero Base section background
--back-one First contrasting section background
--back-two Second contrasting section background
--back-three Third contrasting section background

They may be gradients or solid colors. Some templates add local levels such as --back-four and --back-five; those are template extensions rather than base skin variables.

Example paired palette:

.skinroot.light {
    --back-zero: #ffffff;
    --back-one: #f6f2ff;
    --back-two: #e8dcff;
    --back-three: #cab0ff;
}

.skinroot.dark {
    --back-zero: #111111;
    --back-one: #211934;
    --back-two: #32234f;
    --back-three: #49316f;
}

Define only the levels used by the page, and check both main and subdued text against every selected background.

Responsive font variables

Variable Default
--font-xs 16px
--font-sm 16px
--font-md 18px
--font-lg 18px
--font-xl 18px
--font-fullhd 18px

Override the global type scale only when necessary. Preserve readable mobile sizes and test long headings, navigation labels, tables, and code blocks.

Control-size variables

Variable Default Role
--unitsize 3rem Standard control and navigation unit
--unitsize-small 2.54rem Compact control unit

These are structural rather than decorative variables. Change them cautiously because controls, icons, and navigation share the same dimensions.

Build and preview while authoring

Build the whole website:

statify folder .

Open the generated home page:

statify open

During focused Markdown or JSON iteration, build one page:

statify file pages/path/page.md .
statify file pages/path/page.json .

Use the complete folder build before publishing because it also validates the rest of the page tree and copies shared assets.

Authoring checklist

Before publishing a Statify site:

  • parse every edited JSON file;
  • keep one H1 and a meaningful heading hierarchy on documentation pages;
  • confirm local image, stylesheet, script, font, video, and page references;
  • provide meaningful alternative text for informative images;
  • preserve accurate attribution and licensing information;
  • replace template companies, URLs, people, policies, dates, and contacts;
  • do not invent licenses, customers, testimonials, compliance claims, or analytics identifiers;
  • build the complete source folder;
  • inspect representative generated HTML for its title, canonical URL, navigation, and content;
  • preview the home page and a secondary page at desktop and narrow widths;
  • test both light and dark skins when the theme control is enabled;
  • confirm that the theme preference survives a reload.

Prefer the simplest supported structure that communicates the content well. The rich template is a syntax catalogue, not a target page length.