amp-story-shopping JSON Validation I2I
See original GitHub issueSummary
JSON will be specified inline or fetched from a src
attribute.
An inline configuration is required. If src
is specified it will override the inline JSON.
To prevent CLS, the experience will render once the request resolves. If the request rejects, the experience will render using the inline config.
Data will be validated by the client at the component-level.
It is validated by the client since the config can be loaded via src
.
If any required fields are missing or invalid, no templates will be rendered for the associated product (PDP, product tag, PLP) and a warning will be thrown in the console.
In the case that both src
and inline JSON are specified, src
will take precedence.
Optional fields that are invalid still will block rendering. Optional fields that are missing will not block rendering. Optional fields with required child attributes will block rendering if they are found to be invalid or missing.
isValidConfig = false;
should not be set when an optional config field is present && validateRequired
is not in the array. I’m adding in some additional checks for this.
JSON
{
items: [
{
productId: "..." // Required. Keys to amp-story-shopping-tag nodes.
productUrl: "...", // Required. String. Links to the product's website.
productTitle: "...", // Required. String.
productPrice: 100, // Required. Number.
productPriceCurrency: "..." // Required. String. ISO 4217 currency code used to display the correct currency symbol.
productImages: [ // Required. Array of objects.
{
url: "..." // Required. String.
alt: "..." // Required. String.
}
],
productDetails: "...", // Required. String.
aggregateRating: { // Optional. All sub fields are required if defined.
"ratingValue": 4.4, // Required. Number.
"reviewCount": 89, // Required. Number.
"reviewUrl": // Required. String. Links to page where user can read reviews.
},
productBrand: "...", // Optional. String.
productIcon: "...", // Optional. Links to an image. Defaults to a shopping bag icon.
productTagText: "...", // Optional. String.
},
…
]
}
A validation config object will store a list of valid attributes. Each entry pairs to an array of validation functions to run against the value.
Validation and the validation config will be contained within the amp-story-shopping-config
component.
Validation Config:
const productValidationConfig = {
'productId': [validateRequired, validateStringLength, validateHTMLId],
'productBrand': [validateStringLength],
'productIcon': [validateURL],
…
}
Validation Scalability
In future versions of the component, additional fields may be added to render different templates.
For example, a “productDetails” page may be added to pick the size and color of a product. This validation pattern can be expanded to accommodate nested validation configs. In the case that a productDetails
entry exists, the productDetailsValidationConfig can be run to check its contents.
Scaled JSON
{
items: [
{
productUrl: "...", // Required. String. Links to the products website.
productId: "..." // Required. Keys to amp-story-shopping-tag nodes.
productBrand: "...", // Optional. String.
productIcon: "...", // Optional. Links to an image. Defaults to a shopping bag icon.
productTagText: "...", // Optional. String.
productTitle: "...", // Required. String.
productPrice: 100, // Required. Number.
productPriceCurrency: "..." // Required. String. ISO 4217 currency code used to display the correct currency symbol.
productImages: [ // Required. Must have at least one entry. Array of objects.
{
url: "..." // Required. String.
altText: "..." // Required. String.
}
],
productDetails: "...", // Required. String.
aggregateRating: { // Optional. All sub fields are required if defined..
"ratingValue": 4.4, // Required. Number.
"reviewCount": 89, // Required. Number.
"reviewUrl": // Required. String. Links to page where user can read reviews.
}
productOptions: {
size: "..." // Required. Array of strings.
color: "..." // Required. Array of strings.
}
},
…
]
}
Scaled Validation Config:
const productValidationConfig = {
…
'productOptions': [validateProductOptions]
}
const productOptionsValidationConfig = {
'size': [validateRequired, validateStringEntries],
'color': [validateStringEntries]
}
TODO
Investigate using JSON Schema.
Consider SWR (stale-while-revalidate) for caching src
data.
Notifications
Issue Analytics
- State:
- Created 2 years ago
- Reactions:2
- Comments:15 (15 by maintainers)
True, though I guess I also meant “what if, as a platform, I do not support ratings”?
Is the
aggregateRating
key really required here? What happens if I don’t have ratings for the item?