> ## Documentation Index
> Fetch the complete documentation index at: https://docs.uselayers.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Computed attribute Functions

> Write JavaScript Functions in Layers to compute custom product attributes from Shopify data using an input query, JS logic, and a typed output schema.

## Overview

Functions let you create computed attributes with JavaScript. Use a Function when you need a value that is not already stored on the product, such as discount percentage, SKU coverage, average margin, or a custom label based on several product fields.

A Function has three parts:

* **Input query** - The product data the Function can read.
* **JS function** - The JavaScript that calculates the value.
* **Output schema** - The type and shape of the value the Function returns.

Functions run during catalog processing. After a Function is saved and compiled, Layers recalculates products in the background and stores the returned value as a computed attribute.

<Note>
  The JS function editor is currently in beta. Existing derived attributes and legacy computed attributes continue to work.
</Note>

## Prerequisites

Before you create a Function, make sure:

* Your products have completed a catalog sync.
* The product data you want to use exists in Layers, such as variants, tags, prices, metafields, or collection titles.
* You know how the result should be used: searchable, filterable, sortable, visible in API responses, or available as a storefront facet.

## Create a Function

<Steps>
  <Step title="Open Attributes">
    Go to **Catalog & Data** > **Attributes**, then click **Create Attribute**.
  </Step>

  <Step title="Choose Computed Attribute">
    Select **Computed Attribute**. This opens the Function editor.
  </Step>

  <Step title="Name the attribute">
    Enter a clear name, such as "Discount Percentage" or "Inventory Health". Layers creates a computed attribute code from the name.
  </Step>

  <Step title="Choose a template or start from scratch">
    Click **Templates** to start from a built-in recipe, or write your own Function in the editor.
  </Step>

  <Step title="Define the input query">
    In **Select inputs**, select only the product fields your Function needs. Smaller input queries are easier to review and faster to process.
  </Step>

  <Step title="Define the output schema">
    In **Define outputs**, describe the value your Function returns. The schema tells Layers whether the result is a number, string, boolean, array, or object.
  </Step>

  <Step title="Preview with a product">
    Open **Test results**, choose a product, and click **Run**. Review **Received data** and **Returned data** before saving.
  </Step>

  <Step title="Save the attribute">
    Save the attribute. Layers compiles the Function and recalculates product values in the background.
  </Step>
</Steps>

## Input query

The input query controls what product data your Function receives. You can use fields such as:

* `title`, `vendor`, `productType`, `handle`
* `available`, `publishedAt`, `createdAt`, `updatedAt`
* `tags`, `namedTags`, `collectionTitles`
* `priceRange`
* `variants`
* `metafields`
* `category`, `options`, `images`, `featuredMedia`

For variant data, select the variant fields you need, such as `price`, `compareAtPrice`, `cost`, `sku`, `available`, `inventoryQuantity`, or `createdAt`.

<Tip>
  Use **Received data** in **Test results** to confirm the exact data shape before you save.
</Tip>

## Output schema

The output schema tells Layers what your Function returns. Supported output types are:

* `number`
* `string`
* `boolean`
* `array`
* `object`

For a single returned value, use one output field. Layers stores the value directly on the computed attribute.

For multiple returned values, define multiple output fields. Layers stores the parent result as an object and creates generated sub-fields for each output field. You can configure each sub-field for filtering, sorting, and faceting separately.

<Note>
  If a Function returns `null`, or returns an empty value for a product, Layers excludes that computed value from the product. This keeps empty computed attributes out of API responses and facet results.
</Note>

## Preview and compile status

The editor shows a compile status:

* **Not compiled** - The Function has not been compiled yet.
* **Queued** - The Function is waiting to compile.
* **Compiling** - Layers is compiling the Function.
* **Ready** - The Function compiled successfully and can run during catalog processing.
* **Failed** - Layers could not compile the Function. Review the compile error in the editor.

Status updates appear in real time, so you do not need to refresh the page while a Function compiles. Layers also shows the status as a colored dot next to each computed attribute on the **Attributes** list. Hover the dot to see the current state, or the error message if a compile fails.

Use **Test results** before saving. The preview shows:

* **Console output** - Logs captured while the Function ran.
* **Received data** - The input assembled from your input query.
* **Returned data** - The value returned by the Function.

## Function limits

Functions are designed for product data transformation. They must be synchronous and self-contained.

Supported:

* Plain JavaScript helper functions.
* Array methods such as `map`, `filter`, and `reduce`.
* Built-in JavaScript methods for strings, numbers, objects, arrays, dates, `Math`, and `JSON`.

Not supported:

* Imports or `require`.
* Network calls such as `fetch`.
* Async functions, `await`, and Promise APIs.
* Timers such as `setTimeout` or `setInterval`.
* Classes.
* `for`, `for...of`, `for...in`, `while`, and `do...while` loops.
* Recursive functions.

## Troubleshooting

### The Run button is disabled

Select a product in the **Preview** panel and make sure the editor does not show a blocking syntax error.

### The Function returns no value

Check **Received data** to confirm your input query includes the field you expect. If the input is empty, add the missing field to the input query.

### A returned field is missing

Compare **Returned data** with your output schema. Required fields must be returned for every product where the Function produces a result.

### The output type is rejected

Make sure the returned value matches the output schema. For example, a boolean field must return `true` or `false`, not `"true"` or `"false"`.

### The Function compiles but products do not show values yet

Product recalculation runs in the background after you save. Check again after processing finishes, and confirm the attribute is configured for the place you expect to use it, such as API visibility, filtering, sorting, or storefront facets.

## Next steps

* [Computed attributes](/platform/attributes/calculated-attributes)
* [Computed attribute recipes](/platform/attributes/calculated-attributes/recipes)
* [Attribute options](/platform/attributes/attribute-options)
* [Catalog attributes](/platform/attributes/catalog-attributes)
