Search code examples
javascripthtmlseojson-ld

How can I dynamically update the JSON-LD script with Ajax?


I have JSON-LD as shown, where ratingValue and ratingCount are coming from backend, but I want do it from UI through Ajax call and update it in the aggregateRating.

But when opened page source it is showing data coming from the backend, but when I do console.log() it is showing the value expected but it is not updated in page source.

Is there any way possibly do it from the UI side?

<script type="application/ld+json"> {
    "@context": "http://schema.org/",
    "@type": "Product",
    "name": "Phone",

    "aggregateRating": {
        "@type": "AggregateRating",
        "ratingValue": "4.5",
        "ratingCount": "80"
    },
    "offers": {
        "@type": "AggregateOffer",
        "lowPrice": "5",
        "highPrice": "10",
        "priceCurrency": "USD",
        "availability": "http://schema.org/InStock"
    }
}
</script>
(function () {
    var id = $ {
        prdId
    };
    var response = "";
    $.ajax({
        url: url;
        dataType: "jsonp",
        data: {
            pid: id,
            _method: "GET",
            t: new Date().getTime()
        },
        timeout: 20000,
        xhrFields: {
            withCredentials: true
        },
        type: "get",
        success: function (json) {
            if (json.success == true) {
                response = json.data;
                //call api
                structureData(response);
            } else {
                response = "error";
            }

        }
    });


    function structureData(resp) {
        var json = document.querySelector('script[type="application/ld+json"]').textContent;
        json = JSON.parse(json);

        json["aggregateRating"] = {
            "@type": "AggregateRating",
            "ratingValue": resp.averageScore,
            "reviewCount": resp.averageScore
        }
        var jso = JSON.stringify(json);

        document.querySelector('script[type="application/ld+json"]').textContent = jso;

    }
}

Solution

  • You can definitely update JSON-LD dynamically, this is a more crude example - but you can run the code snippet and see it working. I found the code through this SO question about roughly the same topic but modified it to match your example better:

    let jsonLdScript = document.querySelector('script[type="application/ld+json"]');
    let jsonld = JSON.parse(jsonLdScript.innerText);
    
    document.getElementById('orig-result').textContent = jsonLdScript.innerText;
    
    jsonld.aggregateRating.ratingValue = "5";
    jsonld.aggregateRating.ratingCount = "95";
    
    let newJson = JSON.stringify(jsonld);
    
    jsonLdScript.innerHTML = newJson;
    
    document.getElementById('result').textContent = jsonLdScript.innerText;
    <html>
      <head>
      <script type="application/ld+json"> 
      {
        "@context": "http://schema.org/",
        "@type": "Product",
        "name": "Phone",
        "aggregateRating": {
            "@type": "AggregateRating",
            "ratingValue": "4.5",
            "ratingCount": "80"
        },
        "offers": {
            "@type": "AggregateOffer",
            "lowPrice": "5",
            "highPrice": "10",
            "priceCurrency": "USD",
            "availability": "http://schema.org/InStock"
        }
      }
      </script>
      </head>
      <body>
        <p>Original Output JSON-LD: <br /><strong id="orig-result"></strong></p>
        <p>New Output JSON-LD: <br /><strong id="result"></strong></p>
      </body>
    </html>

    How are you testing? A few things to keep in mind:

    • Obviously the raw page DOM won't be modified
    • You should see the changes in dev tools
    • If you're using Googles Structured Data Tool, and the original JSON is parsed before your function updates it, I'd wager Google won't catch the change.
    • If you're using querySelector, might want to confirm that the JSON-LD you intend to modify is the first instance of JSON-LD on the page.