---
id: data
title: Template data
sidebar_label: Template data
---

import Config from "@site/src/components/Config.js";

The `--data` flag supplies template properties from a file instead of the live environment. Use it to render
a prompt deterministically, without the git repository, Azure CLI, kubectl, or any other tooling a segment
normally detects: take prompt screenshots, build demos, or test a config on a machine that lacks your usual
setup.

`--data` is available on `oh-my-posh print` (every prompt type) and `oh-my-posh config export image`.

## File format

A data file has two top-level sections: `env` for global template properties and `segments` for
per-segment template properties. The format is JSON, YAML, or TOML, decided by the file extension.

<Config
  data={{
    env: {
      PWD: "~/dev/oh-my-posh",
      Code: 1,
      ExecutionTime: 341.0,
      UserName: "jan",
      HostName: "demo",
      Shell: "pwsh",
      Root: false,
    },
    segments: {
      git: {
        HEAD: "main",
        Working: { Added: 2, Modified: 1 },
        Staging: {},
        UpstreamIcon: "",
      },
      az: {
        Name: "posh-subscription",
        EnvironmentName: "AzureCloud",
        Origin: "CLI",
      },
    },
  }}
/>

## The `env` section

Keys are the [global template properties][templates] you already use in templates (`PWD`, `AbsolutePWD`,
`PSWD`, `Folder`, `UserName`, `HostName`, `Shell`, `ShellVersion`, `Root`, `OS`, `WSL`, `SHLVL`, `Jobs`,
`Code`, `PromptCount`, `Version`, and `Var`), plus `ExecutionTime` and `PipeStatus`.

A key present in the file overrides the live value. A key left out falls back to the real environment, so
specify only the properties your config depends on.

`Folder` derives from the effective `PWD` automatically. Set an explicit `Folder` key to override it.

The [`maps`][maps] aliases (`user_name`, `host_name`, `shell_name`) apply to data values as they do to live
ones.

### Precedence

`PWD`, `Code`, `ExecutionTime`, and `PipeStatus` feed the runtime itself, not just the template context. Live
segments that compute from them, such as [path][path], [status][status], and [executiontime][executiontime],
also see the overridden values.

Values are resolved in this order, highest priority first:

1. An explicit CLI flag on `print` (`--pwd`, `--status`, `--execution-time`, ...)
2. The data file
3. The live environment

## The `segments` section

Each key is a segment's `alias` if it has one, otherwise its `type` (for example `git` or `az`). The value is
an object whose keys are that segment's template properties, as documented on the segment's page.

A few segments store a property under a different name than the template exposes. The [wakatime] segment, for
example, stores `.CumulativeTotal` as `cumulative_total`. When a property you wrote by hand has no effect, run
[`config export data`](#recording-data) and copy the names from its output: the recorder always uses the
stored names.

A segment listed here is force-enabled: it renders even where its own live check would otherwise suppress it,
for example a [battery][battery] segment on a machine without one. A segment left out of the file executes
normally against the live environment.

Whether the rest of that segment's state comes from the file or from a live probe depends on how the file was
produced:

- **A [recorded](#recording-data) file** carries a `version` marker and replays a listed segment from the
  supplied data alone. Detection is skipped: no git call, no HTTP request, nothing.
- **A hand-written file** has no `version` marker. Oh My Posh runs the segment's detection first and then
  overlays your properties on top, which fills in whatever you left unset. Some segments only compute their
  template state while detecting, so skipping that step would render them blank. The cost is that the segment
  still touches the live environment. Oh My Posh warns and names the file each time it takes this path.

:::caution
If your config has two segments of the same type, give each an `alias`. Without one, both segments match the
same `type` key in the `segments` section and can't receive distinct data.
:::

For example, this config has two `path` segments distinguished by `alias`:

<Config
  data={{
    segments: [
      {
        type: "path",
        alias: "PathMain",
        style: "plain",
        foreground: "#ffffff",
      },
      {
        type: "path",
        alias: "PathSecondary",
        style: "plain",
        foreground: "#ffffff",
      },
    ],
  }}
/>

The matching data file targets each segment by its alias:

<Config
  data={{
    segments: {
      PathMain: { Path: "~/dev/oh-my-posh" },
      PathSecondary: { Path: "~/dev/site" },
    },
  }}
/>

## Template and method fidelity

Templates evaluate over the data you supply, so template methods and functions work as expected.
`.Working.String` on the [git][git] segment, for example, computes from the `Working` property in the file,
just as it would from a live repository. Only logic that reads live runtime state at render time can't be
reproduced this way. This matches how a [cached][cache] segment behaves: it also renders from stored
properties instead of re-detecting them.

## Recording data

`oh-my-posh config export data` renders your prompt against the real environment and writes a complete data
file: the `env` section plus every configured segment, whether or not it was enabled at record time. The
recorder omits `Var`: the config's own `var` section already defines those values, though you can still set
`Var` in the file by hand to override them.

```bash
oh-my-posh config export data --config mytheme.omp.json --output data.json
```

| Flag       | Description                                    |
| ---------- | ---------------------------------------------- |
| `--config` | the configuration to render                    |
| `--output` | file to write the data to, defaults to stdout  |

The output format is JSON. Record your data files this way. It is the only way to get one that replays
hermetically: `--data` on a recorded file never touches the network, the filesystem, git or any other tooling,
for any segment, including the ones that were disabled when you recorded it.

A recorded file carries a top-level `version` marker and wraps each segment in an envelope pairing its
recorded enabled state with its data:

<Config
  data={{
    version: 1,
    segments: {
      git: { enabled: true, data: { HEAD: "main" } },
      wakatime: { enabled: false, data: {} },
    },
  }}
/>

A segment recorded as `enabled: false` renders as it did on the recording machine: disabled, and never probed
again. You do not have to write this shape yourself. The recorder produces it, and the
[hand-written form](#the-segments-section) with bare properties keeps working.

Record once, replay anywhere. Run the command on a machine where git, the cloud CLIs and the language runtimes
are all set up the way you want them to look, then edit values by hand and replay the result with `--data`
wherever you like. Editing values inside a `data` object is safe. So is editing `enabled`, with one catch:
turning it on for a segment whose recorded `data` is empty renders a blank segment, because none of its
properties were ever captured.

### Deriving instead of replaying a recorded file

`--data-derive` applies the [hand-written derive behavior](#the-segments-section) to a recorded file, running
every segment's detection instead of trusting the recorded `enabled` state and data. Use it to debug the
recorder or a segment's `Enabled` logic. It gives up hermetic replay for the command you pass it to.

## End-to-end example

Record a data file from a fully configured machine:

```bash
oh-my-posh config export data --config mytheme.omp.json --output data.json
```

Edit `data.json` to adjust the values you want to show: the branch name, the exit code, the Azure
subscription, and so on.

Render an image from the edited data, without touching git, Azure CLI, or anything else the config depends on:

```bash
oh-my-posh config export image --config mytheme.omp.json --data data.json
```

## Exporting an image

`config export image` writes an SVG of the rendered prompt. It draws from the prompt's own internal
representation rather than a screenshot, so every color, style and glyph matches what the terminal
would show.

<!-- markdownlint-disable MD013 -->

| Flag               | Description                                                                                |
| ------------------ | ------------------------------------------------------------------------------------------ |
| `--output`, `-o`   | File to write (defaults to the config's own name with an `.svg` extension)                  |
| `--terminal-width` | Columns to render the prompt and canvas at (default `120`)                                  |
| `--font-family`    | CSS `font-family` the SVG renders text with (defaults to a Nerd Font stack)                 |
| `--cell-width`     | Horizontal advance of one cell, as a multiple of font size (defaults to Hack Nerd Font's)   |
| `--line-height`    | Vertical advance of one row, as a multiple of font size (defaults to Hack Nerd Font's)      |
| `--fill-ascent`    | How far a segment background reaches above the baseline, as a multiple of font size         |
| `--fill-descent`   | How far a segment background reaches below the baseline, as a multiple of font size         |
| `--data`           | Render from a recorded data file instead of the live environment                            |
| `--data-only`      | Refuse the environment entirely: a segment renders from `--data` or reports itself absent   |

<!-- markdownlint-enable MD013 -->

The four metric flags travel together, because they describe one font. Set them whenever
`--font-family` names a font whose metrics differ from the default stack. Mixing one font's cell
width with another's line height lays out the grid for a font that does not exist.

```bash
oh-my-posh config export image --config ~/myconfig.omp.json \
  --output ~/mytheme.svg --font-family "Cascadia Code NF"
```

[templates]: /docs/configuration/templates#global-properties
[maps]: /docs/configuration/general#maps
[path]: /docs/segments/system/path
[status]: /docs/segments/system/status
[executiontime]: /docs/segments/system/executiontime
[git]: /docs/segments/scm/git
[cache]: /docs/configuration/segment#cache
[wakatime]: /docs/segments/web/wakatime
[battery]: /docs/segments/system/battery
