[{"data":1,"prerenderedAt":261},["ShallowReactive",2],{"sanity-LevEgKvCUg3Ul3GKyhTsfZIfaGswLQ-qsmdjo9-lWe4":3,"sanity-9HALqzzcfUYIv-GgVI9929fy_jf2wJdwwkP10dS7deA":42,"shiki-block-v-0-0-0-0-0-2-0-1":259,"shiki-block-v-0-0-0-0-0-2-0-2":260},{"data":4},{"_createdAt":5,"_id":6,"_rev":7,"_type":6,"_updatedAt":8,"acceptAllLink":9,"acceptNecessaryLink":18,"bannerColorSource":23,"bannerDescription":24,"bannerTitle":25,"categories":26,"declineAllLink":27,"managePreferencesLink":31,"modalColorSource":23,"modalTitle":35,"preferencesIconColorSource":23,"provider":36,"savePreferencesLink":37,"thirdPartyEmbedCode":26,"title":41},"2026-08-29T18:46:18Z","cookieSettings","C1Syut0iGaGX58H2hZvChS","2026-08-29T18:46:23Z",{"_type":10,"style":11,"title":16,"type":17},"link",{"_type":12,"stylePreset":13},"link.style",{"_ref":14,"_type":15},"link-style-primary","reference","Accept all","button",{"_type":10,"style":19,"title":22,"type":17},{"_type":12,"stylePreset":20},{"_ref":21,"_type":15},"link-style-tertiary-outline","Accept necessary","inherit","We use cookies to enhance your browsing experience and analyse our traffic. Please choose your cookie preferences below.","We use cookies",null,{"_type":10,"style":28,"title":30,"type":17},{"_type":12,"stylePreset":29},{"_ref":21,"_type":15},"Decline all",{"_type":10,"style":32,"title":34,"type":17},{"_type":12,"stylePreset":33},{"_ref":21,"_type":15},"Manage preferences","Cookie Preferences","custom",{"_type":10,"style":38,"title":40,"type":17},{"_type":12,"stylePreset":39},{"_ref":14,"_type":15},"Save preferences","Cookie Settings",{"data":43,"sourceMap":-1},[44],{"_createdAt":5,"_id":45,"_rev":7,"_type":46,"_updatedAt":8,"authorProfile":47,"authorRef":59,"body":61,"categories":160,"excerpt":171,"footer":26,"layout":172,"mainImage":176,"navigation":26,"publishedAt":180,"readTime":181,"relatedPosts":182,"routeOptions":243,"seo":249,"showOnWebsite":245,"slug":248,"tags":255,"title":258},"post-generated-types","post",{"avatar":48,"bio":53,"name":54,"role":55,"sameAs":56},{"_type":49,"alt":50,"asset":51},"image","Portrait of Avery Lin",{"_ref":52,"_type":15},"image-7d9d32f0d8cbaa44274ac31144c4acd3b6256c53-512x512-jpg","Avery designs content models for teams moving off page-builder CMSes, and writes about keeping structured content structured.","Avery Lin","Content Architect",[57,58],"https:\u002F\u002Fexample.com\u002Favery-lin","https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fexample-avery-lin",{"_ref":60,"_type":15},"author-avery-lin",[62,73,82,90,97,106,122,128,136],{"_key":63,"_type":64,"children":65,"markDefs":71,"style":72},"b0160","block",[66],{"_key":67,"_type":68,"marks":69,"text":70},"s0161","span",[],"A hand-written interface for a CMS document is a snapshot of an assumption. It was accurate when it was written and it is accurate now only if nobody has touched the schema since — which is not a property you can check.",[],"normal",{"_key":74,"_type":64,"children":75,"markDefs":80,"style":81},"b0162",[76],{"_key":77,"_type":68,"marks":78,"text":79},"s0163",[],"Regenerate rather than remember",[],"h2",{"_key":83,"_type":64,"children":84,"markDefs":89,"style":72},"b0164",[85],{"_key":86,"_type":68,"marks":87,"text":88},"s0165",[],"Generation turns the schema into the single source of truth, and makes every mismatch a build failure instead of an empty section on a live page. It is one command after any schema change:",[],{"_key":91,"_type":92,"colorSource":23,"markDefs":26,"snippet":93},"code0166","code.block",{"_type":94,"code":95,"language":96},"code","# from the studio directory\nnpm run schema:types","bash",{"_key":98,"_type":64,"children":99,"markDefs":104,"style":105},"b0167",[100],{"_key":101,"_type":68,"marks":102,"text":103},"s0168",[],"Make the registry check itself",[],"h3",{"_key":107,"_type":64,"children":108,"markDefs":121,"style":72},"b0172",[109,113,117],{"_key":110,"_type":68,"marks":111,"text":112},"s0169",[],"Generated types are worth more when something is forced to agree with them. The block registry here closes with ",{"_key":114,"_type":68,"marks":115,"text":116},"s0170",[94],"satisfies Record\u003CRegisteredWebComponentType, ComponentData>",{"_key":118,"_type":68,"marks":119,"text":120},"s0171",[],", so a typo, a stale entry after a rename, or a block with no component fails typecheck rather than rendering nothing.",[],{"_key":123,"_type":92,"colorSource":23,"markDefs":26,"snippet":124},"code0173",{"_type":94,"code":125,"filename":126,"language":127},"import type { HeroSimple, ComponentProps } from '~~\u002Ftypes'\n\n\u002F\u002F The generated type is the prop contract — a renamed schema\n\u002F\u002F field breaks the component, at build time, by name.\ninterface Props extends ComponentProps\u003CHeroSimple> {}\nconst props = defineProps\u003CProps>()","HeroSimple.vue","typescript",{"_key":129,"_type":64,"children":130,"markDefs":135,"style":81},"b0174",[131],{"_key":132,"_type":68,"marks":133,"text":134},"s0175",[],"Queries have types too",[],{"_key":137,"_type":64,"children":138,"markDefs":152,"style":72},"b0179",[139,143,148],{"_key":140,"_type":68,"marks":141,"text":142},"s0176",[],"A projection narrows a document, and the generated result type narrows with it — so a field you forgot to project is a type error at the point of use, not a blank space on the page. The ",{"_key":144,"_type":68,"marks":145,"text":147},"s0177",[146],"ann0159","typography reference page",{"_key":149,"_type":68,"marks":150,"text":151},"s0178",[]," is the same idea applied to content: one place where every thing the editor can do is visible at once.",[153],{"_key":146,"_type":154,"blank":155,"reference":156},"link.internal",false,{"_id":157,"_type":158,"url":159},"page-typography","page","typography",[161,167],{"_createdAt":5,"_id":162,"_rev":163,"_type":164,"_updatedAt":5,"slug":165,"title":166},"category-developer-experience","2d20vp0kUSy7uZjqDieLmb","category","developer-experience","Developer Experience",{"_createdAt":5,"_id":168,"_rev":163,"_type":164,"_updatedAt":5,"slug":169,"title":170},"category-content-modelling","content-modelling","Content Modelling","Types written by hand describe what you believed the schema said. Types generated from it describe what the schema actually says.",{"_type":173,"layout":174,"pageDesign":175},"post.layout.options","default","design1",{"_type":49,"alt":177,"asset":178},"Abstract cyan gradient suggesting a type graph",{"_ref":179,"_type":15},"image-17a06078263667a676c81409a6913d585588058a-1600x900-jpg","2026-08-12T09:00:00.000Z",1,[183,205,227],{"_id":184,"authorProfile":185,"categories":192,"excerpt":197,"mainImage":198,"publishedAt":202,"readTime":181,"slug":203,"title":204},"post-preview-without-token",{"avatar":186,"name":190,"role":191},{"_type":49,"alt":187,"asset":188},"Portrait of Jordan Hale",{"_ref":189,"_type":15},"image-3a10e41064c69525bf602e7eb0d241fe88c6c9f7-512x512-jpg","Jordan Hale","Front-end Engineer",[193,194],{"slug":165,"title":166},{"slug":195,"title":196},"performance","Performance","A read token in the browser bundle is readable by everyone who loads the page. Preview does not need one — the Studio is already logged in.",{"_type":49,"alt":199,"asset":200},"Abstract magenta gradient suggesting a secure channel",{"_ref":201,"_type":15},"image-9d093d7046bd2c85ee744fbbf5abd458e7e85b75-1600x900-jpg","2026-07-28T09:00:00.000Z","draft-preview-without-shipping-a-token","Draft preview without shipping a token to every visitor",{"_id":206,"authorProfile":207,"categories":214,"excerpt":219,"mainImage":220,"publishedAt":224,"readTime":181,"slug":225,"title":226},"post-scaffolding",{"avatar":208,"name":212,"role":213},{"_type":49,"alt":209,"asset":210},"Portrait of Priya Raman",{"_ref":211,"_type":15},"image-cfc7cc28fea565890fb3a5986f7d299c7704a12a-512x512-jpg","Priya Raman","Design Systems Engineer",[215,216],{"slug":165,"title":166},{"slug":217,"title":218},"design-systems","Design Systems","Any component that needs six files in five directories will be built wrong by hand eventually. Generating it is cheaper than writing the guide twice.",{"_type":49,"alt":221,"asset":222},"Abstract green gradient suggesting generated structure",{"_ref":223,"_type":15},"image-d52abf1b9836ea87c4978039efb609149c6c90de-1600x900-jpg","2026-04-08T09:00:00.000Z","a-scaffolder-is-documentation-that-runs","A scaffolder is documentation that runs",{"_id":228,"authorProfile":229,"categories":232,"excerpt":235,"mainImage":236,"publishedAt":240,"readTime":181,"slug":241,"title":242},"post-hydration-cost",{"avatar":230,"name":190,"role":191},{"_type":49,"alt":187,"asset":231},{"_ref":189,"_type":15},[233,234],{"slug":195,"title":196},{"slug":165,"title":166},"A component that fetches after it mounts has quietly moved work from your build machine onto a stranger's phone — and taken your read token with it.",{"_type":49,"alt":237,"asset":238},"Abstract blue gradient suggesting a request waterfall",{"_ref":239,"_type":15},"image-d7eee5de5f25ffeb4e27b87a0c3628c89f2cfc12-1600x900-jpg","2026-03-19T09:00:00.000Z","every-query-in-the-browser-is-a-decision","Every query in the browser is a decision you can move",{"_type":244,"includeInSitemap":245,"slug":246},"page.routing.options",true,{"_type":247,"current":248},"slug","generated-types-are-a-contract",{"_type":250,"description":251,"favicon":252,"image":26,"socialImages":253,"title":254},"seo","Why Sanity TypeGen output beats hand-written interfaces, and how to make the component registry enforce it.",{"mimeType":26,"url":26},{"facebook":26,"linkedin":26,"twitter":26},"Generated types are a contract",[256,166,257],"TypeScript","Sanity TypeGen","Generated types are a contract, not a convenience","\u003Cpre class=\"shiki shiki-themes github-light github-dark nuxion-code__pre\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">script\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> setup\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> lang\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"ts\"\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F Fetched once, at build time, into the prerendered payload.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">data\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> } \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> await\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> useSanityContent\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">BlogIndexQueryResult\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>(\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    blogIndexQuery\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F Paging and search are derived from it — no second request.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> matching\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> computed\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(() \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">=>\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    (data.value?.posts \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">??\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> []).\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">filter\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(matchesFilters)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u002F\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#22863A;--shiki-dark:#85E89D\">script\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>","\u003Cpre class=\"shiki shiki-themes github-light github-dark nuxion-code__pre\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">import\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> type\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { HeroSimple, ComponentProps } \u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">from\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> '~~\u002Ftypes'\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F The generated type is the prop contract — a renamed schema\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#6A737D;--shiki-dark:#6A737D\">\u002F\u002F field breaks the component, at build time, by name.\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">interface\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Props\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> extends\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> ComponentProps\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">HeroSimple\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">> {}\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\">const\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> props\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#D73A49;--shiki-dark:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> defineProps\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">Props\u003C\u002Fspan>\u003Cspan style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>()\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",1788029817766]