# Product Factory

Product factory provides builder methods to help you create Firework product objects from any third-party format. Firework product objects are required for [Product Hydration](/firework-for-developers/web/integration-guide/shopping-integration-v2/product-hydration.md) and [Cart Sync](/firework-for-developers/web/integration-guide/shopping-integration-v2/cart-sync.md).

<figure><img src="/files/9rXPKxMIRa4PHS2Keq0K" alt=""><figcaption></figcaption></figure>

### Create a product

<table><thead><tr><th width="201.33333333333326">Name</th><th width="317">Description</th><th>Required</th></tr></thead><tbody><tr><td><code>extId</code></td><td>External ID in a partner database. It is used to match and update products synced with Firework.</td><td>Yes</td></tr><tr><td><code>name</code></td><td>Product name</td><td>Yes</td></tr><tr><td><code>description</code></td><td>Product description. Markdown for rich formating is allowed.</td><td>Yes</td></tr><tr><td><code>currency</code></td><td>Currency code. e.g. "USD".</td><td>Yes</td></tr><tr><td><code>variant</code></td><td>Variant factory, see <a href="#create-a-variant-product-unit">below</a>.</td><td>Yes, at least one variant should exist in a product</td></tr></tbody></table>

Sample Code

```javascript
window._fwn.shopping.productFactory((builder) => {
  builder
    .description(remoteProduct.description)
    .extId(remoteProduct.id)
    .name(remoteProduct.title)
    .currency('USD')
    .variant((variantBuilder) => {
      // See "Create a variant" section.
    })
})
```

### Create a variant (product unit)

Every product can have one or more variants. For example, a product may come in different sizes or colors. Please note each product needs at least one variant.

<table><thead><tr><th>Name</th><th width="313.3333333333333">Description</th><th>Required</th></tr></thead><tbody><tr><td><code>extId</code></td><td>External variant ID in a partner database. It is used to match and update product variants synced with Firework.</td><td>Yes</td></tr><tr><td><code>url</code></td><td>URL to product/variant detail page.</td><td>Yes</td></tr><tr><td><code>price</code></td><td>Numeric value of current price</td><td>Yes</td></tr><tr><td><code>sku</code></td><td>SKU identifier.</td><td>Optional</td></tr><tr><td><code>name</code></td><td>Variant name.</td><td>Optional</td></tr><tr><td><code>originalPrice</code></td><td>Numeric value of original price</td><td>Optional</td></tr><tr><td><code>isAvailable</code></td><td>Boolean indicating whether variant is currently available (out of stock).</td><td>Optional</td></tr><tr><td><code>image</code></td><td>Image factory, see <a href="#creating-a-product-image">below</a>.</td><td>Optional</td></tr><tr><td><code>option</code></td><td>Variant option. Accepts <code>{name, value}</code> object (e.g <code>{name: 'Size', value: 'Large'}</code>)</td><td>Optional</td></tr><tr><td><code>position</code></td><td>Numeric position amongst other variants. Variant options will also be sorted by this position.</td><td>Optional</td></tr></tbody></table>

<pre class="language-javascript"><code class="lang-javascript"><strong>productbuilder.variant((variantBuilder) => {
</strong>  variantBuilder
    .extId(remoteVariant.id)
    .url('https://www.example.com')
    .price(remoteVariant.price)
    .sku(remoteVariant.sku)
    .name(remoteVariant.name)    
    .isAvailable(remoteVariant.isAvailable)
    .image((imageBuilder) => {
      // See "Create an image" section
    })
  remoteVariant.options.forEach(({name, value}) => {
    variantBuilder.option({
      name,
      value,
    })
  })
})
</code></pre>

{% hint style="info" %}
To update the default pricing, a variant must be hydrated that matches the existing `unit_id`
{% endhint %}

### Create an image

<table><thead><tr><th width="192.33333333333331">Name</th><th width="350">Description</th><th>Required</th></tr></thead><tbody><tr><td><code>extId</code></td><td>External image ID in partner database. It is used to match images between the partner and the Firework database.</td><td>Yes</td></tr><tr><td><code>url</code></td><td>URL location of an image.</td><td>Yes</td></tr><tr><td><code>title</code></td><td>Alt title for an image.</td><td>Optional</td></tr><tr><td><code>position</code></td><td>Numeric value used to sort multiple images.</td><td>Optional</td></tr><tr><td><code>primary</code></td><td>Boolean to set an image as primary</td><td>Optional</td></tr></tbody></table>

```javascript
variantBuilder
  .image((imageBuilder) => {
    imageBuilder
      .extId(remoteVariant.featured_image.id)
      .position(remoteVariant.featured_image.position)
      .title(remoteVariant.featured_image.alt)
      .url(remoteVariant.featured_image.src)
  })
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.firework.com/firework-for-developers/web/integration-guide/shopping-integration-v2/product-factory.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
