{
  "id": 14173854,
  "title": "Our structured data is two script tags, and the rule is that no node may claim more than the page shows",
  "url": "https://urgent.news/2026/10/13/our-structured-data-is-two-script-tags-and-the-rule-is-that-no-node",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-10-13T10:09:31.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/daniel_pertu/our-structured-data-is-two-script-tags-and-the-rule-is-that-no-node-may-claim-more-than-the-page-4812"
  },
  "original_language": "en",
  "account": "Every public page on Nakodo contains precisely two blocks of structured data. The first block is sourced from the marketing layout and outlines the entities that persistently exist, such as the organization and the website. The second block originates from the page itself and specifies the specific nature of that page. Both blocks can be accessed by viewing the source of any given page. On the pricing page, the blocks consist of BreadcrumbList and a SoftwareApplication with three Offer nodes. The guiding principle behind this structure is succinctly expressed in a comment at the beginning of the builder file: each node corresponds to an element visible to the reader on the page. Markup claiming more than what is displayed on the page is a manual action prone to attract penalties rather than a ranking strategy. Nodes that exist once, identified by their unique @id, prevent redundancy and inconsistencies. To achieve this, three stable IDs are exported: ORGANIZATION_ID for the organization, WEBSITE_ID for the website, and SOFTWARE_ID for the software. The layout ensures that the organization and website are displayed once per page, with all other elements referencing these IDs. Each article is assigned an @id in the format of the absolute URL of the article path followed by '#article', distinct from the page URL. The page URL is attributed to the WebPage node. By sharing the same @id, crawlers can understand that an article and a web page refer to the same entity. The @graph wrapper, along with a crucial replace function, transforms the data into a JSON-LD format suitable for search engine indexing. If the data is passed as an array, it encapsulates the @graph; if it is an object, it directly incorporates the data into the @graph. The JSON.stringify function escapes quotes and backslashes but does not handle commas, which could otherwise prematurely terminate a script tag and render subsequent JSON as markup. Escaping commas permanently resolves this issue. JSON-LD parsers interpret commas as the end of a value. The conditionality of two builders, softwareLd and faqLd, is due to their potential to overstate information. softwareLd includes offer nodes only if the pricing is visible on the page, as required by Google. The prices are retrieved from the same module that renders the plan cards, eliminating the need for duplicated price updates. Similarly, faqLd is invoked only when FAQs are visibly present on the page, ensuring consistency in the data provided.",
  "summary": "Every public page on Nakodo ships exactly two blocks of structured data. One comes from the marketing layout and describes the things that exist once: the organisation and the website. One comes from the page and describes what that page actually is. You can read both on any page. View source on a vetting guide and the page block is BreadcrumbList , Article , FAQPage and HowTo . Do the same on…",
  "key_points": [
    "Nakodo pages contain two blocks of structured data",
    "Each block corresponds to visible elements on the page",
    "Unique @id prevents redundancy and inconsistencies"
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}