# Product entity
In Vue Storefront
there is a defined Product type you're to use in your TypeScript code. It contains many optional fields. Please check sample-data/products.json to be sure which fields are critical for Storefront API to work.
Here we present the core purpose of the product properties:
"id": 1769,
This is a unique product identifier:; it's numeric and it's defined as an integer in the elastic.schema.product.json. However, nowhere in the code is it used as intval
. That means when you need to have product IDs presented as GUID's or strings, please just feel free to modify the schema and run yarn db rebuild
. Should be fine!
"name": "Chloe Compete Tank",
This is just a product name 😃
"image": "/w/t/wt06-blue_main.jpg",
Product image - by deafult, it's relative because vue-storefront-api/img
endpoint uses this relative URL against the base platform images URL/CDN to generate the thumbnail.
Note: If you want to use absolute urls, that's not a problem. Please put the absolute URL in this field and then make sure the vue-storefront
knows about it by setting the config.images.useExactUrlsNoProxy
option. It will use the exact image URLs without the resizer. You can also perform a trick to use the resizer with absolute URLS, by setting the config.images.baseUrl
to the URL address containing the placeholder. Something like:
https://demo.vuestorefront.io/img/?url=
. The magic happens here.
"sku": "WT06",
The Stock Keeping Unit is a unique string. The format is not restricted to any form. It's used as a cache key for products. It's also used for figuring out the selected configurable variant of a configurable
product.
"url_key": "chloe-compete-tank",
"url_path": "women/tops-women/tanks-women/bras-and-tanks-26/chloe-compete-tank-1769.html",
As of Vue Storefront 1.9, the url_key
is no longer used for URL routing. It's just a string and well, it's optional. The urlo_path
, however, is a must. It must be unique across all routable URL addresses, because it's used by the Url Dispatcher to map the URL to a specific product for PDP.
"type_id": "configurable",
Storefront API supports the following product types:
simple
- simple products with no configurable options,configurable
- products with variants - they're assigned in theconfigurable_children
and the options used to select the proper variant (likecolor
andsize
) are defined in theconfigurable_options
,bundle
- products that consist other products under a single virtual SKU. The sub-products can be configured / checked / unchecked.grouped
- products grouping different products that were added to the cart as separate items,virtual
- virtual products are partially supported (Vue Storefront does not ask the user for shipping information if there are just virtuals in the cart, that's it).
The routes
in the Vue Storefront are customizable to specific product types so you can create a different PDP for specific types of products.
"price": 39,
This is the price that Vue Storefront treats as Net price (not including tax). The thing is that by default Vue Storefront takes the prices from the Elastic/Backend, but you can switch the config.tax.calculateServerSide=false
to start calculating taxes in the frontend app (for example based on the current address).
"special_price": 0,
This is a special price (if set, the price
will be crossed over in the UI) - also Net.
"price_incl_tax": null,
"special_price_incl_tax": null,
If these fields are set, Vue Storefront shows these prices as default, end-user prices in the store. They should include all the taxes.
"special_to_date": null,
"special_from_date": null,
The special price field is limited in time by these dates (should be ISO date format). See how.
"status": 1,
Product status:
- <=1 - product is enabledd,
- 2 - product is disabled,
- 3 - product is out of stock (however VSF checks the
stock.is_in_stock
property).
"visibility": 4,
Visibility status:
- 1 - not visible (won't be displayed in the listings),
- 2 - visible in catalog,
- 3 - visible in search,
- 4 - visible in both.
"size": null,
"color": null,
Color, size - typically numerical indexes. Vue Storefront for all non system properties loads the attribute
definitions.
If the definition exists then, if the type is select
or multiselect
the value of the property is used as the index in the attribute values dictionary. Read more on attributes. Otherwise, it's being used as text.
So you can put any color name you like in this field and it still could be used for product browsing. This is, for example, how the bigcommerce2vuestorefront
integration works. It doesn't use the attribute metadata at all because, for some platforms using a kind of Wordpress like semantics, it's very hard to create an attribute dictionary.
"size_options": [
167,
168,
169,
170,
171
],
"color_options": [
50,
58,
60
],
For any property (color and sizes are just an examples) you might want to create a propertyName + "_options"
helper which is used for product filtering. In this case, it consist of all configurable_children
colors and sizes.
"category_ids": [
"26"
],
Category IDs (don't have to be numerical but usually are 😃). This field is used for product filtering on the Category.vue
page in Vue Storefront.
"category": [
{
"category_id": 26,
"name": "Bras & Tanks",
"slug": "bras-and-tanks-26",
"path": "women/tops-women/tanks-women/bras-and-tanks-26"
}
],
In addition to category_ids
, we have a category
collection which is a denormalized set of categories assigned to this product. It is used in the SearchPanel
for generating the output categories in the search results and .. probably that's all. So if you disable this feature, the category
property is no longer needed.
"media_gallery": [
{
"image": "/w/t/wt06-blue_main.jpg",
"pos": 1,
"typ": "image",
"lab": null,
"vid": null
},
{
"image": "/w/t/wt06-blue_back.jpg",
"pos": 2,
"typ": "image",
"lab": null,
"vid": null
}
],
This is just a list of images used by the ProductGallery
component. Paths can be relative or absolute - exactly the same as with product.image
.
"configurable_options": [
{
"id": 300,
"attribute_id": "93",
"label": "Color",
"position": 1,
"values": [
{
"value_index": 50,
"label": "Blue"
},
{
"value_index": 58,
"label": "Red"
},
{
"value_index": 60,
"label": "Yellow"
}
],
"product_id": 1769,
"attribute_code": "color"
},
{
"id": 301,
"attribute_id": "142",
"label": "Size",
"position": 0,
"values": [
{
"value_index": 167,
"label": "XS"
},
{
"value_index": 168,
"label": "S"
},
{
"value_index": 169,
"label": "M"
},
{
"value_index": 170,
"label": "L"
},
{
"value_index": 171,
"label": "XL"
}
],
"product_id": 1769,
"attribute_code": "size"
}
],
This collection contains all configurable options that can be used to identify a simple
product, assigned in the configurable_children
collection. Usually, it's a set of available colors
and sizes
. It is used to construct the Color/Size switcher on the Product.vue
page. If you set the proper label
's then the attribute_id
is not required. It means you don't have to have the attribute defined in the dictionary. It's a pretty usefull option for platforms that don't support attribute dictionaries like BigCommerce.
"stock": [
{
"is_in_stock": true,
"qty": 0
}
],
Stock is used to check if a product is available or not. There is also an api/stock
endpoint (to be implemented dynamically) to make sure Vue Storefront is up to date with the data. This Elastic based stock is used mostly for filtering out unavailable products (and not as a source of truth for adding to the cart).
"configurable_children": [
{
"type_id": null,
"sku": "WT06-XS-Blue",
"special_price": 0,
"special_to_date": null,
"special_from_date": null,
"name": "Chloe Compete Tank-XS-Blue - tier price",
"price": 39,
"price_incl_tax": null,
"special_price_incl_tax": null,
"id": 1754,
"image": "/w/t/wt06-blue_main.jpg",
"url_key": "chloe-compete-tank-xs-blue",
"url_path": null,
"status": 1,
"size": "167",
"color": "50"
},
{
"type_id": null,
"sku": "WT06-XS-Red",
"special_price": 0,
"special_to_date": null,
"special_from_date": null,
"name": "Chloe Compete Tank-XS-Red",
"price": 39,
"price_incl_tax": null,
"special_price_incl_tax": null,
"id": 1755,
"image": "/w/t/wt06-red_main.jpg",
"url_key": "chloe-compete-tank-xs-red",
"url_path": null,
"status": 1,
"size": "167",
"color": "58"
}
]
},
All configurable
products consist of simple
products assigned to the configurable_childdren
collection. Those are the ones finally ordered. The important feature of the configurable_children
collection is that it should consist of only the properties that differentiate these products from the main configurable
one. You could probably skip the name
. It's because each product is merged with its configurable_children
- well, selected configurable children when the user switches the color and sizes. There is a Vuex action product/confgure
which performs exactly this merge operation.
# What was skipped?
We haven't described the Bundle and Grouped products yet. It's on our TODO 😃