# Assembly Variables

<span aria-hidden="true" id="assembly-instructions-basics"></span><span aria-hidden="true" id="22-assembly-variables"></span>

Transloadit supports variables from within your <dfn>Assemblies</dfn>
so you can create more powerful workflows. You can, for instance, filter files based on `width`,
influence storage location based on `type`, and plenty more. We've included a full list of
placeholder variables available to <dfn>Assembly Variables</dfn>. They can be used in any parameter value in any <dfn>Robot</dfn>.

> [!NOTE]
> Conditions on properties that a file doesn’t have will be ignored. For example, an image doesn’t
> have `${file.meta.bitrate}`. Also, note that since `${file.width}` will be ignored, use
> `${file.meta.width}` instead.

* `${assembly.id}` — The ID of the Assembly representing the current upload, which is a UUIDv4
  without dashes.
* `${assembly.region}` — The AWS region where the Assembly is being processed. You could use this
  to import files from a bucket in the same region, to reduce data transfer costs and latencies.
* `${assembly.parent_id}` — The ID of the parent Assembly when replaying that parent Assembly.
* `${unique_prefix}` — A unique 33-character prefix used to avoid file name collisions, such as
  `"f2/d3eeeb67479f11f8b091b04f6181ad"`.

  Notice the `/` in the prefix. If you use `${unique_prefix}` in the `path` parameter of
  [🤖/s3/store](/docs/robots/s3-store.md) for example, then it will create
  sub-directories in your S3 bucket. This may or may not be desired. Use `${file.id}` if you require
  a unique prefix without slashes.
* `${unique_original_prefix}` — This is similar to `${unique_prefix}`, with the exception that two
  different encoding results of the same uploaded file (the original file) will have the same prefix
  value here.
* `${previous_step.name}` — The name of the previous Step that produced the current file.
* `${file.id}` — The ID of the file being processed, which is a UUIDv4 without dashes.
* `${file.original_id}` — The ID of the original file that a certain file derives from. For example,
  if you use an import Robot to import files and then encode them somehow, the encoding result files
  will have a `${file.original_id}` that matches the `${file.id}` of the imported file.
* `${file.original_name}` — The name of the original file (including file extension) that a certain
  file derives from. For example, if you use an import Robot to import files and then encode them
  somehow, the encoding result files will have a `${file.original_name}` that matches the
  `${file.name}` of the imported file.
* `${file.original_basename}` — The basename of the original file that a certain file derives from.
  For example, if you use an import Robot to import files and then encode them somehow, the encoding
  result files will have a `${file.original_basename}` that matches the `${file.basename}` of the
  imported file.
* `${file.original_path}` — The import path of the original file that a certain file derives from.
  All of our import Robots set `${file.original_path}` accordingly.

  For example, if you use [🤖/s3/import](/docs/robots/s3-import.md) to import files
  from Amazon S3, the imported files, as well a all files that are derived from them, will have a
  `file.original_path` that equals the path to the file on S3, but without the filename. So if the
  S3 path was `"path/to/file.txt"`, then `file.original_path` will be `"/path/to/"`. If the path was
  `"/a.txt"`, `${file.original_path}` will be `"/"`.

  `file.original_path` will always have sufficient slashes in order for you to safely use it in the
  `path` parameter of your export step, like this: `"path": "${file.original_path}${file.name}"`.
  This is handy if you want to import files from, for example, S3, convert them somehow and store
  them again on S3 in the same (or similar) file structure.
* `${file.name}` — The name of the file being processed, including the file extension.
* `${file.url_name}` — The slugged name of the file.

  Filenames are transliterated and sanitized to produce a URL-safe version. Non-Latin characters are converted to Latin equivalents (e.g., `café.jpg` → `cafe.jpg`, `бубу.mov` → `bubu.mov`), and whitespace or punctuation is replaced with dashes. Consecutive non-distinct characters may collapse into a single dash.

  > [!WARNING]
  > Because non-Latin characters are transliterated to Latin equivalents, and other complex characters or special symbols are replaced with dashes, this can cause filename collisions that did not occur on a user's original machine. To avoid this, always use `${file.url_name}` together with `${unique_prefix}` or `${file.md5hash}`.
* `${file.basename}` — The name of the file being processed, without the file extension. This allows
  you to do things dynamically *per file* instead of per assembly with `fields`.
* `${file.url_basename}` — The slugged basename of the file (the file name without the file extension).

  Filenames are transliterated and sanitized to produce a URL-safe version. Non-Latin characters are converted to Latin equivalents (e.g., `café.jpg` → `cafe.jpg`, `бубу.mov` → `bubu.mov`), and whitespace or punctuation is replaced with dashes. Consecutive non-distinct characters may collapse into a single dash.

  > [!WARNING]
  > Because non-Latin characters are transliterated to Latin equivalents, and other complex characters or special symbols are replaced with dashes, this can cause filename collisions that did not occur on a user's original machine. To avoid this, always use `${file.url_basename}` together with `${unique_prefix}` or `${file.md5hash}`.
* `${file.user_meta}` — Tus uploads, which you use to upload to Transloadit, can carry metadata
  values. All the extra values sent along will end up in `user_meta`. This is custom metadata that
  you supply yourself, not Transloadit's detected file type or MIME type.
* `${file.ext}` — The file extension.
* `${file.size}` — The file size in bytes.
* `${file.type}` — A broad file category detected by Transloadit and exposed in Assembly status JSON,
  such as `image`, `video`, `audio`, `pdf`, `office`, `xls`, `swf`, or `document`. Use this when you
  need a coarse category or compatibility with existing workflows. For robust content checks, prefer
  `${file.mime}`.
* `${file.mime}` — The file's MIME type as detected by Transloadit, typically during server-side
  metadata extraction in the normal upload flow. This can differ from the MIME type originally
  reported by the client or browser. Prefer this for content-type branching, using MIME family
  matches such as `image/*`, `video/*`, or `audio/*` where possible.
* `${file.md5hash}` — The file's MD5 hash. This is a hash over the file's contents, not only over
  the file's name.
* `${file.*}` — Any file property available in the final results array, such as `${file.meta.width}`.
  Not all meta keys are available for all file types.
* `${fields.*}` — <span aria-hidden="true" id="23-form-fields-in-instructions"></span><span aria-hidden="true" id="form-fields-in-instructions"></span><span aria-hidden="true" id="form-fields-in-assembly-instructions"></span>The fields submitted together with the upload.

  For example, in the case of a Form submission where Uppy was set to allow `fields: ['myvar']`, and
  the form had a tag like `<input type="hidden" name="myvar" value="1" />`, `${fields.myvar}` would
  contain a value of `1`.

  Alternatively, fields could also be populated programmatically like so:

  ```json
  {
    "steps": {
      "store": {
        "use": "encoded",
        "robot": "/s3/store",
        "credentials": "YOUR_S3_CREDENTIALS_NAME",
        "path": "${assembly.id}/${fields.subdir}/356"
      }
    },
    "fields": {
      "subdir": "bar"
    }
  }
  ```

  In the case of a conflict, variables derived from form fields take precedence over those derived
  from the `fields` key.
* `${Date.now()}` — The current date and time represented as the number of milliseconds elapsed
  since the UNIX epoch,  which is defined as the midnight at the beginning of January 1, 1970, UTC.
  Technically, this is not a variable, but uses
  [dynamic code evaluation](/docs/topics/dynamic-evaluation.md).

## Assembly Variables example

Let's say you don't like the location where files are stored. By default, Transloadit is careful not
to overwrite anything. All [export Robots](/docs/robots.md#service-file-exporting/) have a `path`
parameter with a default of `"${unique_prefix}/${file.url_name}"`, resulting in locations such as:
`"f2/d3eeeb67479f11f8b091b04f6181ad/my-file-name.png"`.

We could, for example, change the parameter's value to
`"${previous_step.name}/${file.id}.${file.ext}"`, which would make the paths end up looking like
`"video-step-name/a8d3eeeb67479f11f8b091b04f6181ad.png"`.

Not all <dfn>Assembly Variables</dfn> are created equal and
some are more unique (and hence suitable to solely base storage location on). here are some
examples, ordered from less to more unique:

* `${file.ext}` is the same for many files
* `${file.url_name}` especially across users and time, a high likelihood of collisions, for
  instance: `avatar.jpg`
* `${previous_step.name}` is the same for all files that are results of the same <dfn>Step</dfn>
* `${assembly.id}` is the **same** for all files within a single <dfn>Assembly</dfn>
* `${file.id}` as well as `${unique_prefix}` are **unique** for each file

<span aria-hidden="true" id="assembly-instructions-examples"></span>

If <dfn>Assembly Variables</dfn> don't offer quite enough
flexibility for your use-case, we also offer
[dynamic code execution](/docs/topics/dynamic-evaluation.md), using the
[/script/run](/docs/robots/script-run.md) <dfn>Robot</dfn>,
which allows JavaScript to be evaluated from your <dfn>Assembly Instructions</dfn>.
