Repository: yext/visual-editor
Pull request #408: fix: remove buildSchema logic and use document._schema
Author: login: asanehisa
Created: 2025-04-28T18:14:04Z | Merged: 2025-04-28T21:14:12Z

<img width="1840" alt="Screenshot 2025-04-28 at 2 46 35 PM" src="https://github.com/user-attachments/assets/734fe0fd-a6cc-45ec-be55-48d921f83f00" />


confirmed directory template adjustments works properly in storm and in dev mode. 


Diff:
diff --git a/packages/visual-editor/src/vite-plugin/templates/directory.tsx b/packages/visual-editor/src/vite-plugin/templates/directory.tsx
index e0cb9eeb83..04ce3d0a94 100644
--- a/packages/visual-editor/src/vite-plugin/templates/directory.tsx
+++ b/packages/visual-editor/src/vite-plugin/templates/directory.tsx
@@ -18,8 +18,7 @@ import {
   applyAnalytics,
 } from "@yext/visual-editor";
 import { themeConfig } from "../../theme.config";
-import { buildSchema } from "../utils/buildSchema";
-import { AnalyticsProvider } from "@yext/pages-components";
+import { AnalyticsProvider, SchemaWrapper } from "@yext/pages-components";
 
 export const getHeadConfig: GetHeadConfig<TemplateRenderProps> = ({
   document,
@@ -66,7 +65,7 @@ export const getHeadConfig: GetHeadConfig<TemplateRenderProps> = ({
     other: [
       applyAnalytics(document),
       applyTheme(document, themeConfig),
-      buildSchema(document),
+      SchemaWrapper(document._schema),
     ].join("\n"),
   };
 };
diff --git a/packages/visual-editor/src/vite-plugin/templates/main.tsx b/packages/visual-editor/src/vite-plugin/templates/main.tsx
index 5f5c417f20..e6a05a2a99 100644
--- a/packages/visual-editor/src/vite-plugin/templates/main.tsx
+++ b/packages/visual-editor/src/vite-plugin/templates/main.tsx
@@ -19,8 +19,7 @@ import {
   applyAnalytics,
 } from "@yext/visual-editor";
 import { themeConfig } from "../../theme.config";
-import { buildSchema } from "../utils/buildSchema";
-import { AnalyticsProvider } from "@yext/pages-components";
+import { AnalyticsProvider, SchemaWrapper } from "@yext/pages-components";
 
 export const getHeadConfig: GetHeadConfig<TemplateRenderProps> = ({
   document,
@@ -67,7 +66,7 @@ export const getHeadConfig: GetHeadConfig<TemplateRenderProps> = ({
     other: [
       applyAnalytics(document),
       applyTheme(document, themeConfig),
-      buildSchema(document),
+      SchemaWrapper(document._schema),
     ].join("\n"),
   };
 };
diff --git a/starter/localData/dev-dm-city-stream__en__8932945.json b/starter/localData/dev-dm-city-stream__en__8932945.json
index 914ffbb8e3..79cbd9dec7 100644
--- a/starter/localData/dev-dm-city-stream__en__8932945.json
+++ b/starter/localData/dev-dm-city-stream__en__8932945.json
@@ -3,6 +3,96 @@
     "entityPageSet": {},
     "name": "dev-location"
   },
+  "_schema": {
+    "@graph": [
+      {
+        "@context": "https://schema.org",
+        "@type": "ItemList",
+        "description": "Directory of locations",
+        "itemListElement": [
+          {
+            "@type": "ListItem",
+            "item": {
+              "@type": "Place",
+              "address": {
+                "@type": "PostalAddress",
+                "addressCountry": "US",
+                "addressLocality": "Arlington",
+                "addressRegion": "VA",
+                "postalCode": "22209",
+                "streetAddress": "1101 Wilson Blvd"
+              },
+              "name": "Galaxy Grill"
+            },
+            "position": 1
+          }
+        ],
+        "name": "Arlington",
+        "numberOfItems": 1
+      },
+      {
+        "@context": "https://schema.org",
+        "@type": "BreadcrumbList",
+        "itemListElement": [
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/index.html",
+              "@type": "Thing"
+            },
+            "name": "All Locations",
+            "position": 1
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/index.html",
+              "@type": "Thing"
+            },
+            "name": "Location Pages Directory",
+            "position": 2
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us",
+              "@type": "Thing"
+            },
+            "name": "US",
+            "position": 3
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us/va",
+              "@type": "Thing"
+            },
+            "name": "VA",
+            "position": 4
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us/va/arlington",
+              "@type": "Thing"
+            },
+            "name": "Arlington",
+            "position": 5
+          }
+        ]
+      },
+      {
+        "@context": "https://schema.org",
+        "@type": "WebPage",
+        "description": "Browse locations in Arlington",
+        "isPartOf": {
+          "@type": "WebSite"
+        },
+        "name": "Arlington",
+        "url": "yawningly-long-trout.pgsdemo.com/us/va/arlington"
+      }
+    ]
+  },
   "_site": {
     "copyrightMessage": "© 2025 Yext",
     "favicon": {
diff --git a/starter/localData/dev-dm-country-stream__en__8932938.json b/starter/localData/dev-dm-country-stream__en__8932938.json
index 52b850730c..1632247fc4 100644
--- a/starter/localData/dev-dm-country-stream__en__8932938.json
+++ b/starter/localData/dev-dm-country-stream__en__8932938.json
@@ -3,6 +3,94 @@
     "entityPageSet": {},
     "name": "dev-location"
   },
+  "_schema": {
+    "@graph": [
+      {
+        "@context": "https://schema.org",
+        "@type": "ItemList",
+        "description": "Directory of locations",
+        "itemListElement": [
+          {
+            "@type": "ListItem",
+            "item": {
+              "@type": "Place",
+              "name": "VA"
+            },
+            "position": 1
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@type": "Place",
+              "name": "FL"
+            },
+            "position": 2
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@type": "Place",
+              "name": "NY"
+            },
+            "position": 3
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@type": "Place",
+              "name": "DC"
+            },
+            "position": 4
+          }
+        ],
+        "name": "US",
+        "numberOfItems": 4
+      },
+      {
+        "@context": "https://schema.org",
+        "@type": "BreadcrumbList",
+        "itemListElement": [
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/index.html",
+              "@type": "Thing"
+            },
+            "name": "All Locations",
+            "position": 1
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/index.html",
+              "@type": "Thing"
+            },
+            "name": "Location Pages Directory",
+            "position": 2
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us",
+              "@type": "Thing"
+            },
+            "name": "US",
+            "position": 3
+          }
+        ]
+      },
+      {
+        "@context": "https://schema.org",
+        "@type": "WebPage",
+        "description": "Browse locations in US",
+        "isPartOf": {
+          "@type": "WebSite"
+        },
+        "name": "US",
+        "url": "yawningly-long-trout.pgsdemo.com/us"
+      }
+    ]
+  },
   "_site": {
     "copyrightMessage": "© 2025 Yext",
     "favicon": {
diff --git a/starter/localData/dev-dm-region-stream__en__8932944.json b/starter/localData/dev-dm-region-stream__en__8932944.json
index b2e1660e90..7cf94f6455 100644
--- a/starter/localData/dev-dm-region-stream__en__8932944.json
+++ b/starter/localData/dev-dm-region-stream__en__8932944.json
@@ -3,6 +3,79 @@
     "entityPageSet": {},
     "name": "dev-location"
   },
+  "_schema": {
+    "@graph": [
+      {
+        "@context": "https://schema.org",
+        "@type": "ItemList",
+        "description": "Directory of locations",
+        "itemListElement": [
+          {
+            "@type": "ListItem",
+            "item": {
+              "@type": "Place",
+              "name": "Arlington"
+            },
+            "position": 1
+          }
+        ],
+        "name": "VA",
+        "numberOfItems": 1
+      },
+      {
+        "@context": "https://schema.org",
+        "@type": "BreadcrumbList",
+        "itemListElement": [
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/index.html",
+              "@type": "Thing"
+            },
+            "name": "All Locations",
+            "position": 1
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/index.html",
+              "@type": "Thing"
+            },
+            "name": "Location Pages Directory",
+            "position": 2
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us",
+              "@type": "Thing"
+            },
+            "name": "US",
+            "position": 3
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us/va",
+              "@type": "Thing"
+            },
+            "name": "VA",
+            "position": 4
+          }
+        ]
+      },
+      {
+        "@context": "https://schema.org",
+        "@type": "WebPage",
+        "description": "Browse locations in VA",
+        "isPartOf": {
+          "@type": "WebSite"
+        },
+        "name": "VA",
+        "url": "yawningly-long-trout.pgsdemo.com/us/va"
+      }
+    ]
+  },
   "_site": {
     "copyrightMessage": "© 2025 Yext",
     "favicon": {
diff --git a/starter/localData/dev-dm-root-stream__en__8932937.json b/starter/localData/dev-dm-root-stream__en__8932937.json
index b05d3665f8..18de4f922d 100644
--- a/starter/localData/dev-dm-root-stream__en__8932937.json
+++ b/starter/localData/dev-dm-root-stream__en__8932937.json
@@ -3,6 +3,61 @@
     "entityPageSet": {},
     "name": "dev-location"
   },
+  "_schema": {
+    "@graph": [
+      {
+        "@context": "https://schema.org",
+        "@type": "ItemList",
+        "description": "Directory of locations",
+        "itemListElement": [
+          {
+            "@type": "ListItem",
+            "item": {
+              "@type": "Place",
+              "name": "US"
+            },
+            "position": 1
+          }
+        ],
+        "name": "Location Pages Directory",
+        "numberOfItems": 1
+      },
+      {
+        "@context": "https://schema.org",
+        "@type": "BreadcrumbList",
+        "itemListElement": [
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/index.html",
+              "@type": "Thing"
+            },
+            "name": "All Locations",
+            "position": 1
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/index.html",
+              "@type": "Thing"
+            },
+            "name": "Location Pages Directory",
+            "position": 2
+          }
+        ]
+      },
+      {
+        "@context": "https://schema.org",
+        "@type": "WebPage",
+        "description": "Browse locations in Location Pages Directory",
+        "isPartOf": {
+          "@type": "WebSite"
+        },
+        "name": "Location Pages Directory",
+        "url": "yawningly-long-trout.pgsdemo.com/index.html"
+      }
+    ]
+  },
   "_site": {
     "copyrightMessage": "© 2025 Yext",
     "favicon": {
diff --git a/starter/localData/dev-location-stream__en__8573da7e3961090ddb59214a1f01e59a.json b/starter/localData/dev-location-stream__en__8573da7e3961090ddb59214a1f01e59a.json
index 3625491cb4..cf5fd64d8f 100644
--- a/starter/localData/dev-location-stream__en__8573da7e3961090ddb59214a1f01e59a.json
+++ b/starter/localData/dev-location-stream__en__8573da7e3961090ddb59214a1f01e59a.json
@@ -3,6 +3,100 @@
     "entityPageSet": {},
     "name": "dev-location"
   },
+  "_schema": {
+    "@graph": [
+      {
+        "@context": "https://schema.org",
+        "@type": "LocalBusiness",
+        "address": {
+          "@type": "PostalAddress",
+          "addressCountry": "US",
+          "addressLocality": "Brooklyn",
+          "addressRegion": "NY",
+          "postalCode": "11211",
+          "streetAddress": "288 Grand St"
+        },
+        "hasOfferCatalog": {
+          "@type": "OfferCatalog",
+          "itemListElement": [
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Corporate Catering"
+              }
+            },
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Tailgate Catering"
+              }
+            },
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Birthday Parties"
+              }
+            },
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Delivery"
+              }
+            }
+          ],
+          "name": "Services"
+        },
+        "name": "Galaxy Grill",
+        "openingHours": ["Mo-Su 10:00-22:00"]
+      },
+      {
+        "@context": "https://schema.org",
+        "@type": "BreadcrumbList",
+        "itemListElement": [
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/index.html",
+              "@type": "Thing"
+            },
+            "name": "Location Pages Directory",
+            "position": 1
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us",
+              "@type": "Thing"
+            },
+            "name": "US",
+            "position": 2
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us/ny",
+              "@type": "Thing"
+            },
+            "name": "NY",
+            "position": 3
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us/ny/brooklyn",
+              "@type": "Thing"
+            },
+            "name": "Brooklyn",
+            "position": 4
+          }
+        ]
+      }
+    ]
+  },
   "_site": {
     "name": "Example Business",
     "siteName": "Example Business Pages",
diff --git a/starter/localData/dev-location-stream__en__a5ac5ff0d6330870779568c3bc865bc7.json b/starter/localData/dev-location-stream__en__a5ac5ff0d6330870779568c3bc865bc7.json
index c43b0f1012..29ba1be989 100644
--- a/starter/localData/dev-location-stream__en__a5ac5ff0d6330870779568c3bc865bc7.json
+++ b/starter/localData/dev-location-stream__en__a5ac5ff0d6330870779568c3bc865bc7.json
@@ -3,6 +3,101 @@
     "entityPageSet": {},
     "name": "dev-location"
   },
+  "_schema": {
+    "@graph": [
+      {
+        "@context": "https://schema.org",
+        "@type": "LocalBusiness",
+        "address": {
+          "@type": "PostalAddress",
+          "addressCountry": "US",
+          "addressLocality": "Miami",
+          "addressRegion": "FL",
+          "postalCode": "33155",
+          "streetAddress": "7751 Bird Rd"
+        },
+        "hasOfferCatalog": {
+          "@type": "OfferCatalog",
+          "itemListElement": [
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Corporate Catering"
+              }
+            },
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Tailgate Catering"
+              }
+            },
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Birthday Parties"
+              }
+            },
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Delivery"
+              }
+            }
+          ],
+          "name": "Services"
+        },
+        "name": "Galaxy Grill",
+        "openingHours": ["Mo-Sa 10:00-22:00"],
+        "telephone": "+13014588348"
+      },
+      {
+        "@context": "https://schema.org",
+        "@type": "BreadcrumbList",
+        "itemListElement": [
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/index.html",
+              "@type": "Thing"
+            },
+            "name": "Location Pages Directory",
+            "position": 1
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us",
+              "@type": "Thing"
+            },
+            "name": "US",
+            "position": 2
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us/fl",
+              "@type": "Thing"
+            },
+            "name": "FL",
+            "position": 3
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us/fl/miami",
+              "@type": "Thing"
+            },
+            "name": "Miami",
+            "position": 4
+          }
+        ]
+      }
+    ]
+  },
   "_site": {
     "name": "Example Business",
     "siteName": "Example Business Pages",
diff --git a/starter/localData/dev-location-stream__en__aa6fc9407fdca53fc4133ee078b93231.json b/starter/localData/dev-location-stream__en__aa6fc9407fdca53fc4133ee078b93231.json
index 8d36de6c9a..7d8e62cfcb 100644
--- a/starter/localData/dev-location-stream__en__aa6fc9407fdca53fc4133ee078b93231.json
+++ b/starter/localData/dev-location-stream__en__aa6fc9407fdca53fc4133ee078b93231.json
@@ -3,6 +3,100 @@
     "entityPageSet": {},
     "name": "dev-location"
   },
+  "_schema": {
+    "@graph": [
+      {
+        "@context": "https://schema.org",
+        "@type": "LocalBusiness",
+        "address": {
+          "@type": "PostalAddress",
+          "addressCountry": "US",
+          "addressLocality": "Washington",
+          "addressRegion": "DC",
+          "postalCode": "20024",
+          "streetAddress": "2 15th St NW"
+        },
+        "hasOfferCatalog": {
+          "@type": "OfferCatalog",
+          "itemListElement": [
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Corporate Catering"
+              }
+            },
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Tailgate Catering"
+              }
+            },
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Birthday Parties"
+              }
+            },
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Delivery"
+              }
+            }
+          ],
+          "name": "Services"
+        },
+        "name": "Galaxy Grill",
+        "openingHours": ["Mo-Su 10:00-22:00"]
+      },
+      {
+        "@context": "https://schema.org",
+        "@type": "BreadcrumbList",
+        "itemListElement": [
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/index.html",
+              "@type": "Thing"
+            },
+            "name": "Location Pages Directory",
+            "position": 1
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us",
+              "@type": "Thing"
+            },
+            "name": "US",
+            "position": 2
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us/dc",
+              "@type": "Thing"
+            },
+            "name": "DC",
+            "position": 3
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us/dc/washington",
+              "@type": "Thing"
+            },
+            "name": "Washington",
+            "position": 4
+          }
+        ]
+      }
+    ]
+  },
   "_site": {
     "name": "Example Business",
     "siteName": "Example Business Pages",
diff --git a/starter/localData/dev-location-stream__en__ca4c1a79172a9c40124e5cae94716adb.json b/starter/localData/dev-location-stream__en__ca4c1a79172a9c40124e5cae94716adb.json
deleted file mode 100644
index f889c5ae2f..0000000000
--- a/starter/localData/dev-location-stream__en__ca4c1a79172a9c40124e5cae94716adb.json
+++ /dev/null
@@ -1,103 +0,0 @@
-{
-  "__": {
-    "entityPageSet": {},
-    "name": "dev-location"
-  },
-  "_site": {
-    "name": "Example Business",
-    "siteName": "Example Business Pages",
-    "copyrightMessage": "© 2025 Yext",
-    "favicon": {
-      "height": 1152,
-      "url": "https://a.mktgcdn.com/p-dev/YfHDxOszJCxQZt7PEHtzUWk8sGzV5E_q2BLXYc_fCHo/1152x1152.png",
-      "width": 1152
-    },
-    "footer": {
-      "links": [
-        {
-          "label": "Privacy Policy",
-          "link": "https://www.yext.com/privacy-policy",
-          "linkType": "URL"
-        },
-        {
-          "label": "Contact Us",
-          "link": "sumo@yext.com",
-          "linkType": "EMAIL"
-        }
-      ]
-    },
-    "header": {
-      "links": [
-        { "label": "Home", "link": "index.html", "linkType": "OTHER" },
-        {
-          "label": "More Info",
-          "link": "https://yext.com",
-          "linkType": "URL"
-        },
-        { "label": "Call Us", "link": "+12125550110", "linkType": "PHONE" }
-      ]
-    },
-    "id": "site-63590",
-    "instagramHandle": "yextinc",
-    "logo": {
-      "image": {
-        "alternateText": "The Galaxy Grill Logo",
-        "height": 1152,
-        "url": "https://a.mktgcdn.com/p-dev/YfHDxOszJCxQZt7PEHtzUWk8sGzV5E_q2BLXYc_fCHo/1152x1152.png",
-        "width": 1152
-      }
-    },
-    "meta": { "entityType": { "id": "site", "uid": 29107 }, "locale": "en" },
-    "uid": 8932936,
-    "youTubeChannelUrl": "https://www.youtube.com/c/yext"
-  },
-  "dm_directoryParents_63590_locations": [
-    { "name": "Locations Directory", "slug": "en/index.html" },
-    {
-      "name": "US",
-      "slug": "en/us",
-      "dm_addressCountryDisplayName": "United States"
-    },
-    {
-      "name": "NV",
-      "slug": "en/us/nv",
-      "dm_addressCountryDisplayName": "United States",
-      "dm_addressRegionDisplayName": "Nevada"
-    },
-    {
-      "name": "Las Vegas",
-      "slug": "en/us/nv/las-vegas",
-      "dm_addressCountryDisplayName": "United States",
-      "dm_addressRegionDisplayName": "Nevada"
-    }
-  ],
-  "address": {
-    "city": "Las Vegas",
-    "countryCode": "US",
-    "line1": "Casino St",
-    "localizedCountryName": "United States",
-    "localizedRegionName": "Nevada",
-    "postalCode": "12345",
-    "region": "NV"
-  },
-  "businessId": 1000146856,
-  "id": "casino_st",
-  "locale": "en",
-  "meta": {
-    "entityType": {
-      "id": "location",
-      "uid": 0
-    },
-    "locale": "en"
-  },
-  "name": "Supernova BBQ",
-  "siteDomain": "",
-  "siteId": 0,
-  "siteInternalHostName": "",
-  "slug": "locations/casino_st",
-  "uid": 8695734,
-  "yextDisplayCoordinate": {
-    "latitude": 36.171563,
-    "longitude": -115.1391009
-  }
-}
diff --git a/starter/localData/dev-location-stream__en__cbafb9cd1c3e63d9814e236ba9181377.json b/starter/localData/dev-location-stream__en__cbafb9cd1c3e63d9814e236ba9181377.json
index 7afa461fc8..3ab1c9b77a 100644
--- a/starter/localData/dev-location-stream__en__cbafb9cd1c3e63d9814e236ba9181377.json
+++ b/starter/localData/dev-location-stream__en__cbafb9cd1c3e63d9814e236ba9181377.json
@@ -3,6 +3,101 @@
     "entityPageSet": {},
     "name": "dev-location"
   },
+  "_schema": {
+    "@graph": [
+      {
+        "@context": "https://schema.org",
+        "@type": "LocalBusiness",
+        "address": {
+          "@type": "PostalAddress",
+          "addressCountry": "US",
+          "addressLocality": "Arlington",
+          "addressRegion": "VA",
+          "postalCode": "22209",
+          "streetAddress": "1101 Wilson Blvd"
+        },
+        "hasOfferCatalog": {
+          "@type": "OfferCatalog",
+          "itemListElement": [
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Corporate Catering"
+              }
+            },
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Tailgate Catering"
+              }
+            },
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Birthday Parties"
+              }
+            },
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Delivery"
+              }
+            }
+          ],
+          "name": "Services"
+        },
+        "name": "Galaxy Grill",
+        "openingHours": ["Mo-Su 10:00-22:00"],
+        "telephone": "+17577017560"
+      },
+      {
+        "@context": "https://schema.org",
+        "@type": "BreadcrumbList",
+        "itemListElement": [
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/index.html",
+              "@type": "Thing"
+            },
+            "name": "Location Pages Directory",
+            "position": 1
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us",
+              "@type": "Thing"
+            },
+            "name": "US",
+            "position": 2
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us/va",
+              "@type": "Thing"
+            },
+            "name": "VA",
+            "position": 3
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us/va/arlington",
+              "@type": "Thing"
+            },
+            "name": "Arlington",
+            "position": 4
+          }
+        ]
+      }
+    ]
+  },
   "_site": {
     "name": "Example Business",
     "siteName": "Example Business Pages",
diff --git a/starter/localData/dev-location-stream__en__d7f52f17aa2a321e60e8c1a8fae53637.json b/starter/localData/dev-location-stream__en__d7f52f17aa2a321e60e8c1a8fae53637.json
index dcb7605e19..402d57847e 100644
--- a/starter/localData/dev-location-stream__en__d7f52f17aa2a321e60e8c1a8fae53637.json
+++ b/starter/localData/dev-location-stream__en__d7f52f17aa2a321e60e8c1a8fae53637.json
@@ -3,6 +3,100 @@
     "entityPageSet": {},
     "name": "dev-location"
   },
+  "_schema": {
+    "@graph": [
+      {
+        "@context": "https://schema.org",
+        "@type": "LocalBusiness",
+        "address": {
+          "@type": "PostalAddress",
+          "addressCountry": "US",
+          "addressLocality": "New York",
+          "addressRegion": "NY",
+          "postalCode": "10014",
+          "streetAddress": "61 9th Avenue"
+        },
+        "hasOfferCatalog": {
+          "@type": "OfferCatalog",
+          "itemListElement": [
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Corporate Catering"
+              }
+            },
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Tailgate Catering"
+              }
+            },
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Birthday Parties"
+              }
+            },
+            {
+              "@type": "Offer",
+              "itemOffered": {
+                "@type": "Service",
+                "name": "Delivery"
+              }
+            }
+          ],
+          "name": "Services"
+        },
+        "name": "Galaxy Grill",
+        "openingHours": ["Mo-Su 10:00-22:00"]
+      },
+      {
+        "@context": "https://schema.org",
+        "@type": "BreadcrumbList",
+        "itemListElement": [
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/index.html",
+              "@type": "Thing"
+            },
+            "name": "Location Pages Directory",
+            "position": 1
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us",
+              "@type": "Thing"
+            },
+            "name": "US",
+            "position": 2
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us/ny",
+              "@type": "Thing"
+            },
+            "name": "NY",
+            "position": 3
+          },
+          {
+            "@type": "ListItem",
+            "item": {
+              "@id": "yawningly-long-trout.pgsdemo.com/us/ny/new-york",
+              "@type": "Thing"
+            },
+            "name": "New York",
+            "position": 4
+          }
+        ]
+      }
+    ]
+  },
   "_site": {
     "name": "Example Business",
     "siteName": "Example Business Pages",
diff --git a/starter/localData/dev-location-stream__en__fd8e569c314d912412add63bb882142c.json b/starter/localData/dev-location-stream__en__fd8e569c314d912412add63bb882142c.json
deleted file mode 100644
index a7000f4b67..0000000000
--- a/starter/localData/dev-location-stream__en__fd8e569c314d912412add63bb882142c.json
+++ /dev/null
@@ -1,104 +0,0 @@
-{
-  "__": {
-    "entityPageSet": {},
-    "name": "dev-location"
-  },
-  "_site": {
-    "name": "Example Business",
-    "siteName": "Example Business Pages",
-    "copyrightMessage": "© 2025 Yext",
-    "favicon": {
-      "height": 1152,
-      "url": "https://a.mktgcdn.com/p-dev/YfHDxOszJCxQZt7PEHtzUWk8sGzV5E_q2BLXYc_fCHo/1152x1152.png",
-      "width": 1152
-    },
-    "footer": {
-      "links": [
-        {
-          "label": "Privacy Policy",
-          "link": "https://www.yext.com/privacy-policy",
-          "linkType": "URL"
-        },
-        {
-          "label": "Contact Us",
-          "link": "sumo@yext.com",
-          "linkType": "EMAIL"
-        }
-      ]
-    },
-    "header": {
-      "links": [
-        { "label": "Home", "link": "index.html", "linkType": "OTHER" },
-        {
-          "label": "More Info",
-          "link": "https://yext.com",
-          "linkType": "URL"
-        },
-        { "label": "Call Us", "link": "+12125550110", "linkType": "PHONE" }
-      ]
-    },
-    "id": "site-63590",
-    "instagramHandle": "yextinc",
-    "logo": {
-      "image": {
-        "alternateText": "The Galaxy Grill Logo",
-        "height": 1152,
-        "url": "https://a.mktgcdn.com/p-dev/YfHDxOszJCxQZt7PEHtzUWk8sGzV5E_q2BLXYc_fCHo/1152x1152.png",
-        "width": 1152
-      }
-    },
-    "meta": { "entityType": { "id": "site", "uid": 29107 }, "locale": "en" },
-    "uid": 8932936,
-    "youTubeChannelUrl": "https://www.youtube.com/c/yext"
-  },
-  "dm_directoryParents_63590_locations": [
-    { "name": "Locations Directory", "slug": "en/index.html" },
-    {
-      "name": "US",
-      "slug": "en/us",
-      "dm_addressCountryDisplayName": "United States"
-    },
-    {
-      "name": "MD",
-      "slug": "en/us/md",
-      "dm_addressCountryDisplayName": "United States",
-      "dm_addressRegionDisplayName": "Maryland"
-    },
-    {
-      "name": "North Bethesda",
-      "slug": "en/us/md/north-bethesda",
-      "dm_addressCountryDisplayName": "United States",
-      "dm_addressRegionDisplayName": "Maryland"
-    }
-  ],
-  "address": {
-    "city": "North Bethesda",
-    "countryCode": "US",
-    "line1": "12345 Parklawn Drive",
-    "line2": "4",
-    "localizedCountryName": "United States",
-    "localizedRegionName": "Maryland",
-    "postalCode": "20852",
-    "region": "MD"
-  },
-  "businessId": 1000146856,
-  "id": "parklawn_drive",
-  "locale": "en",
-  "meta": {
-    "entityType": {
-      "id": "location",
-      "uid": 0
-    },
-    "locale": "en"
-  },
-  "name": "Supernova BBQ",
-  "siteDomain": "",
-  "siteId": 0,
-  "siteInternalHostName": "",
-  "slug": "location/parklawn_drive",
-  "uid": 8745421,
-  "yextDisplayCoordinate": {
-    "latitude": 39.0606577,
-    "longitude": -77.1110885
-  }
-}
diff --git a/starter/localData/mapping.json b/starter/localData/mapping.json
index 5b1fdde59c..7780e7804a 100644
--- a/starter/localData/mapping.json
+++ b/starter/localData/mapping.json
@@ -4,8 +4,6 @@
     "dev-location-stream__en__a5ac5ff0d6330870779568c3bc865bc7.json",
     "dev-location-stream__en__8573da7e3961090ddb59214a1f01e59a.json",
     "dev-location-stream__en__cbafb9cd1c3e63d9814e236ba9181377.json",
-    "dev-location-stream__en__aa6fc9407fdca53fc4133ee078b93231.json",
-    "dev-location-stream__en__ca4c1a79172a9c40124e5cae94716adb.json",
-    "dev-location-stream__en__fd8e569c314d912412add63bb882142c.json"
+    "dev-location-stream__en__aa6fc9407fdca53fc4133ee078b93231.json"
   ]
 }
diff --git a/starter/src/templates/dev.tsx b/starter/src/templates/dev.tsx
index 24c13f3c3d..c45f7fc6d5 100644
--- a/starter/src/templates/dev.tsx
+++ b/starter/src/templates/dev.tsx
@@ -16,10 +16,10 @@ import {
   YextSchemaField,
   defaultThemeConfig,
 } from "@yext/visual-editor";
-import { buildSchema } from "../utils/buildSchema.ts";
 import tailwindConfig from "../../tailwind.config";
 import { devTemplateStream } from "../dev.config";
 import React from "react";
+import { SchemaWrapper } from "@yext/pages-components";
 
 export const config = {
   name: "dev-location",
@@ -88,7 +88,7 @@ export const getHeadConfig: GetHeadConfig<TemplateRenderProps> = ({
     ],
     other: [
       applyTheme(document, defaultThemeConfig),
-      buildSchema(document),
+      SchemaWrapper(document._schema),
     ].join("\n"),
   };
 };
diff --git a/starter/src/types/autogen.ts b/starter/src/types/autogen.ts
deleted file mode 100644
index a11806d72f..0000000000
--- a/starter/src/types/autogen.ts
+++ /dev/null
@@ -1,123 +0,0 @@
-export interface Interval {
-  start: any;
-  end: any;
-}
-
-export interface DayHour {
-  openIntervals?: Interval[];
-  isClosed?: boolean;
-}
-
-export interface HolidayHours {
-  date: string;
-  openIntervals?: Interval[];
-  isClosed?: boolean;
-  isRegularHours?: boolean;
-}
-
-export interface Hours {
-  monday?: DayHour;
-  tuesday?: DayHour;
-  wednesday?: DayHour;
-  thursday?: DayHour;
-  friday?: DayHour;
-  saturday?: DayHour;
-  sunday?: DayHour;
-  holidayHours?: HolidayHours[];
-  reopenDate?: string;
-}
-
-export interface Address {
-  line1?: string;
-  line2?: string;
-  line3?: string;
-  sublocality?: string;
-  city?: string;
-  region?: string;
-  postalCode?: string;
-  extraDescription?: string;
-  countryCode?: string;
-}
-
-export interface ImageThumbnail {
-  url: string;
-  width: number;
-  height: number;
-}
-
-export interface Image {
-  url: string;
-  width: number;
-  height: number;
-  thumbnails?: ImageThumbnail[];
-  alternateText?: string;
-}
-
-export interface ComplexImage {
-  image: Image;
-  details?: string;
-  description?: string;
-  clickthroughUrl?: string;
-}
-
-export interface Cta {
-  name?: string;
-  link?: string;
-}
-
-export interface C_hero {
-  image?: ComplexImage;
-  cta1?: Cta;
-  cta2?: Cta;
-}
-
-export interface C_deliveryPromo {
-  image?: ComplexImage;
-  title?: string;
-  description?: string;
-  cta?: Cta;
-}
-
-export interface LocationStream {
-  id: string;
-  uid: string;
-  meta: any;
-  slug: string;
-  name: string;
-  hours: Hours;
-  address: Address;
-  c_hero: C_hero;
-  c_deliveryPromo: C_deliveryPromo;
-  c_productSection: C_productSection;
-  additionalHoursText: string;
-  mainPhone: string;
-  emails: string[];
-  c_faqSection: C_faqSection;
-}
-
-/* DO NOT REMOVE BELOW CODE (not autogenerated) **/
-export interface C_productSection {
-  sectionTitle?: string;
-  linkedProducts?: LinkedProducts[];
-}
-
-export interface LinkedProducts {
-  name: string;
-  c_productPromo: string;
-  c_description?: string;
-  c_coverPhoto?: ComplexImage;
-  c_productCTA?: Cta;
-}
-
-export interface answerV2 {
-  json: object;
-}
-
-export interface linkedFAQs {
-  question: string;
-  answerV2: answerV2;
-}
-
-export interface C_faqSection {
-  linkedFAQs?: linkedFAQs[];
-}
diff --git a/starter/src/utils/buildSchema.ts b/starter/src/utils/buildSchema.ts
deleted file mode 100644
index 9c40d6b7f8..0000000000
--- a/starter/src/utils/buildSchema.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { SchemaWrapper, LocalBusiness } from "@yext/pages-components";
-
-export function buildSchema(document: Record<string, any>) {
-  const localBusiness = document.address && {
-    ...LocalBusiness(document),
-    paymentAccepted: document.paymentOptions,
-    makesOffer: document.services,
-  };
-
-  const json = {
-    "@graph": [localBusiness].filter(Boolean),
-  };
-
-  return SchemaWrapper(json);
-}
diff --git a/starter/src/utils/cn.ts b/starter/src/utils/cn.ts
deleted file mode 100644
index a5ef193506..0000000000
--- a/starter/src/utils/cn.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-import { clsx, type ClassValue } from "clsx";
-import { twMerge } from "tailwind-merge";
-
-export function cn(...inputs: ClassValue[]) {
-  return twMerge(clsx(inputs));
-}


Reviews:
user: login: mkilpatrick
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-04-28T18:22:47Z
user: login: asanehisa
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T18:47:26Z
user: login: mkilpatrick
state: DISMISSED
author_association: COLLABORATOR
submitted_at: 2025-04-28T18:51:06Z
user: login: benlife5
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T21:04:17Z
user: login: jwartofsky-yext
body: lgtm
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-04-28T21:06:42Z
user: login: mkilpatrick
state: APPROVED
author_association: COLLABORATOR
submitted_at: 2025-04-28T21:09:44Z

Review comments:
diff_hunk: @@ -64,11 +63,9 @@ export const getHeadConfig: GetHeadConfig<TemplateRenderProps> = ({
           ]
         : []),
     ],
-    other: [
-      applyAnalytics(document),
-      applyTheme(document, themeConfig),
-      buildSchema(document),
-    ].join("\n"),
+    other: [applyAnalytics(document), applyTheme(document, themeConfig)].join(
path: packages/visual-editor/src/vite-plugin/templates/main.tsx
user: login: mkilpatrick
body: How is the schema being added to the page now? We still need to add it to the DOM from the document. buildSchema isn't related to the entitySelector.
created_at: 2025-04-28T18:21:24Z
author_association: COLLABORATOR
diff_hunk: @@ -64,11 +63,9 @@ export const getHeadConfig: GetHeadConfig<TemplateRenderProps> = ({
           ]
         : []),
     ],
-    other: [
-      applyAnalytics(document),
-      applyTheme(document, themeConfig),
-      buildSchema(document),
-    ].join("\n"),
+    other: [applyAnalytics(document), applyTheme(document, themeConfig)].join(
path: packages/visual-editor/src/vite-plugin/templates/main.tsx
user: login: asanehisa
body: Oops, fixed
created_at: 2025-04-28T18:47:26Z
author_association: CONTRIBUTOR

PR comments:
user: login: mkilpatrick
created_at: 2025-04-28T18:54:12Z
body: Please break this into two PRs: one for the directory template and one for the schema changes.
author_association: COLLABORATOR
user: login: asanehisa
created_at: 2025-04-28T19:07:54Z
body: This is based off this [directory PR](https://github.com/yext/visual-editor/pull/409) so is split up, but hard to tell until [directory PR](https://github.com/yext/visual-editor/pull/409) is merged
author_association: CONTRIBUTOR