<p>Andrew will likely come along and give a better answer, but you can definitely extend the outputted JSON-LD in SEOMatic.  No need to copy any of the schema things over, I think.</p>
<p>Here's an example from a good while ago of adding brand, mpn, sku to the <code>mainEntityOfPage</code> i.e. your Product.</p>
<pre><code>
{% if not craft.app.request.isAjax and 'debug' not in craft.app.request.segment(1) %}
    
    {# Set the brand ... #}
    {% set mainEntity = seomatic.jsonLd.get('mainEntityOfPage') %}
    {% set brand = product.brand.one() ??? null %}

    {% if brand|length %}
        {% set productBrand = seomatic.jsonLd.create({
            'type': 'Brand',
            'name': brand.title,
            'url': brand.homepageUrl,
        }, false) %}
    {# If someone has left off the brand, let's just say it belongs to us... #}
    {% else %}
        {% set productBrand = seomatic.jsonLd.create({
            'type': 'Brand',
            'name': 'Store Brand',
            'url': 'https://yourstore.com',
        }, false) %}
    {% endif %}

    {% do mainEntity.brand(productBrand) %}
    {# We use the title here as the actual offers below have the real MPN/SKU #}
    {% do mainEntity.mpn(product.title) %}
    {% do mainEntity.sku(product.title) %}

{% endif %}

</code></pre>
<p>Here's an example dealing with offers, for the actual variants of that product (assuming these are variant products):</p>
<pre><code>
    {# We show out of stock offers even for discontinued products at the moment #}
    {% set offers = [] %}
    {% for variant in variations %}

            {% set offers = offers|merge([seomatic.jsonLd.create({
                'type': 'Offer',
                'name': variant.description,
                'description': variant.description,
                'url': product.url,
                'availability' : (variant.available and object.available and (variant.hasUnlimitedStock or variant.stock &gt; 0)) ? 'http://schema.org/InStock' : 'http://schema.org/OutOfStock',
                'itemCondition' : 'https://schema.org/NewCondition',
                'mpn' : variant.mpn ??? &quot;&quot;,
                'price' : variant.salePrice|number_format(2, '.', ''),
                'priceCurrency' : 'AUD',
                'priceValidUntil' : now | date_modify('+1 year') | atom,
                'offeredBy' : {&quot;@id&quot; : &quot;https://yourstore.com/#identity&quot;},
                'seller' : {&quot;@id&quot; : &quot;https://yourstore.com/#identity&quot;},
                'sku': variant.sku,
                'image' : (one(object.masterImage)|length) ?   { &quot;@type&quot;: &quot;ImageObject&quot;, &quot;url&quot; : &quot;https://yourstore.com&quot; ~ craft.imager.transformImage( one(object.masterImage), 'large' ).getUrl() } : &quot;&quot;,
                'category' : (one(object.categories)|length) ? one(object.categories).title : &quot;&quot;,
            }, false)]) %}

    {% endfor %}

    {% do mainEntity.offers(offers) %}

</code></pre>
<p>SEOmatic is really very well documented, you'd want to review (well, the whole Using SEOMatic section really!) - but more specifically:</p>
<p><a href="https://nystudio107.com/docs/seomatic/Using.html#seomatic-variables" rel="nofollow noreferrer">https://nystudio107.com/docs/seomatic/Using.html#seomatic-variables</a></p>
<p>and</p>
<p><a href="https://nystudio107.com/docs/seomatic/Using.html#json-ld-meta-object-functions-seomatic-jsonld" rel="nofollow noreferrer">https://nystudio107.com/docs/seomatic/Using.html#json-ld-meta-object-functions-seomatic-jsonld</a></p>

CC BY-SA 4.0
2020-11-21T23:06:14.943Z
Nope, that's a great answer! :)
andrew.welch
CC BY-SA 4.0
2020-11-20T22:48:23.217Z
2020-12-11T06:01:38.567Z
2020-12-11T06:01:38.567Z
Jeremy Daalder
<p>My products have a lot of attributes that I would like to serve to Google AMP via JSON-LD. The attributes vary between product types.</p>
<p>How should I do this?</p>
<p>I see there is a file under <code>nystudio107\craft-seomatic\src\seomatic-config\productmeta\JsonLdContainer.php</code>, and I am guessing I should put that file in my own config and modify it a bit, but I am not sure how to approach this.</p>
<p><strong>Edit: Then of course there is the question</strong>: What are you really trying to do?</p>
<p>I am under the impression that I can tell Google what the different attributes on my product are, and that Google can use this when generating rich previews of search results. I understand that Google has a list of <a href="https://developers.google.com/search/docs/guides/search-gallery" rel="nofollow noreferrer">Supported Structured Data</a>, and from that it doesn't seem you can or should add additional non-supported attributes to the JSON-LD output...</p>
<p>Then again, I see there are a lot of attributes that <a href="https://support.google.com/merchants/answer/6386198?hl=en" rel="nofollow noreferrer">are in fact supported</a>. Like Brand. How do I add Brand to my JSON-LD? I guess all attributes from <a href="https://schema.org/docs/full.html" rel="nofollow noreferrer">Schema.org</a> are supported?</p>

<plugin-seomatic>
Outputting structured product attributes in JSON-LD code with SEOMatic
# Outputting structured product attributes in JSON-LD code with SEOMatic

(Asked by: username_0 on 2020-11-20)

My products have a lot of attributes that I would like to serve to Google AMP via JSON-LD. The attributes vary between product types.

How should I do this?

I see there is a file under `nystudio107\craft-seomatic\src\seomatic-config\productmeta\JsonLdContainer.php`, and I am guessing I should put that file in my own config and modify it a bit, but I am not sure how to approach this.

**Edit: Then of course there is the question**: What are you really trying to do?

I am under the impression that I can tell Google what the different attributes on my product are, and that Google can use this when generating rich previews of search results. I understand that Google has a list of [Supported Structured Data](https://developers.google.com/search/docs/guides/search-gallery), and from that it doesn't seem you can or should add additional non-supported attributes to the JSON-LD output...

Then again, I see there are a lot of attributes that [are in fact supported](https://support.google.com/merchants/answer/6386198?hl=en). Like Brand. How do I add Brand to my JSON-LD? I guess all attributes from [Schema.org](https://schema.org/docs/full.html) are supported?

**Tags:** plugin-seomatic


---

## 1 answers

### Answer by username_1 on 2020-11-20. Score: 2 | Accepted answer

Andrew will likely come along and give a better answer, but you can definitely extend the outputted JSON-LD in SEOMatic.  No need to copy any of the schema things over, I think.
Here's an example from a good while ago of adding brand, mpn, sku to the mainEntityOfPage i.e. your Product.

{% if not craft.app.request.isAjax and 'debug' not in craft.app.request.segment(1) %}
    
    {# Set the brand ... #}
    {% set mainEntity = seomatic.jsonLd.get('mainEntityOfPage') %}
    {% set brand = product.brand.one() ??? null %}

    {% if brand|length %}
        {% set productBrand = seomatic.jsonLd.create({
            'type': 'Brand',
            'name': brand.title,
            'url': brand.homepageUrl,
        }, false) %}
    {# If someone has left off the brand, let's just say it belongs to us... #}
    {% else %}
        {% set productBrand = seomatic.jsonLd.create({
            'type': 'Brand',
            'name': 'Store Brand',
            'url': 'https://yourstore.com',
        }, false) %}
    {% endif %}

    {% do mainEntity.brand(productBrand) %}
    {# We use the title here as the actual offers below have the real MPN/SKU #}
    {% do mainEntity.mpn(product.title) %}
    {% do mainEntity.sku(product.title) %}

{% endif %}


Here's an example dealing with offers, for the actual variants of that product (assuming these are variant products):

    {# We show out of stock offers even for discontinued products at the moment #}
    {% set offers = [] %}
    {% for variant in variations %}

            {% set offers = offers|merge([seomatic.jsonLd.create({
                'type': 'Offer',
                'name': variant.description,
                'description': variant.description,
                'url': product.url,
                'availability' : (variant.available and object.available and (variant.hasUnlimitedStock or variant.stock > 0)) ? 'http://schema.org/InStock' : 'http://schema.org/OutOfStock',
                'itemCondition' : 'https://schema.org/NewCondition',
                'mpn' : variant.mpn ??? "",
                'price' : variant.salePrice|number_format(2, '.', ''),
                'priceCurrency' : 'AUD',
                'priceValidUntil' : now | date_modify('+1 year') | atom,
                'offeredBy' : {"@id" : "https://yourstore.com/#identity"},
                'seller' : {"@id" : "https://yourstore.com/#identity"},
                'sku': variant.sku,
                'image' : (one(object.masterImage)|length) ?   { "@type": "ImageObject", "url" : "https://yourstore.com" ~ craft.imager.transformImage( one(object.masterImage), 'large' ).getUrl() } : "",
                'category' : (one(object.categories)|length) ? one(object.categories).title : "",
            }, false)]) %}

    {% endfor %}

    {% do mainEntity.offers(offers) %}


SEOmatic is really very well documented, you'd want to review (well, the whole Using SEOMatic section really!) - but more specifically:
https://nystudio107.com/docs/seomatic/Using.html#seomatic-variables
and
https://nystudio107.com/docs/seomatic/Using.html#json-ld-meta-object-functions-seomatic-jsonld

> **Comments:**
> **username_2**: Nope, that's a great answer! :)  

---

