[{"data":1,"prerenderedAt":327},["ShallowReactive",2],{"sanity-LevEgKvCUg3Ul3GKyhTsfZIfaGswLQ-qsmdjo9-lWe4":3,"sanity-LU8RcBU_QLYfT3VpVyMVkaPWF5s4iLaanOAiyRuOT04":42,"sanity-Aa5JJSRbPnUGDQ0lOoJ9wUsDKCwrWUg1JAqzzyGlZ5s":102},{"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},{"_createdAt":5,"_id":44,"_rev":45,"_type":46,"_updatedAt":5,"components":47,"footer":26,"isPublished":90,"navigation":26,"path":91,"routeOptions":92,"seo":97,"showFooter":90,"showNav":90,"slug":96,"title":63},"page-blog","2d20vp0kUSy7uZjqDieLmb","page",[48,83],{"_key":49,"_type":50,"alignment":51,"content":52,"options":75,"width":82},"blog-intro","text-block","mx-auto",[53,66],{"_key":54,"_type":55,"children":56,"markDefs":64,"style":65},"b0229","block",[57],{"_key":58,"_type":59,"marks":60,"text":63},"s0228","span",[61,62],"strong","align-center","Blog",[],"h1",{"_key":67,"_type":55,"children":68,"markDefs":73,"style":74},"b0231",[69],{"_key":70,"_type":59,"marks":71,"text":72},"s0230",[62],"Notes on content modelling, performance, theming and developer experience — written while building this starter. Filter by category, or search the titles and summaries.",[],"normal",{"_type":76,"colorSource":23,"container":77,"padding":78},"section.options","contained",{"_type":79,"bottom":80,"top":81},"padding.options",0,80,"max-w-3xl",{"_key":84,"_type":85,"options":86,"title":89},"blog-index","post.index",{"_type":76,"colorSource":23,"container":77,"padding":87,"sectionId":88},{"_type":79,"bottom":81,"top":80},"posts","All posts",true,"\u002Fblog",{"_type":93,"includeInSitemap":90,"slug":94},"page.routing.options",{"_type":95,"current":96},"slug","blog",{"_type":98,"description":99,"favicon":100,"image":26,"socialImages":101,"title":63},"seo","Notes on content modelling, performance, theming and developer experience — written while building this starter.",{"mimeType":26,"url":26},{"facebook":26,"linkedin":26,"twitter":26},{"data":103,"sourceMap":-1},{"categories":104,"posts":121},[105,109,113,117],{"_id":106,"_updatedAt":5,"slug":107,"title":108},"category-content-modelling","content-modelling","Content Modelling",{"_id":110,"_updatedAt":5,"slug":111,"title":112},"category-design-systems","design-systems","Design Systems",{"_id":114,"_updatedAt":5,"slug":115,"title":116},"category-developer-experience","developer-experience","Developer Experience",{"_id":118,"_updatedAt":5,"slug":119,"title":120},"category-performance","performance","Performance",[122,144,164,184,200,215,231,247,263,279,295,311],{"_id":123,"authorProfile":124,"categories":132,"excerpt":135,"mainImage":136,"publishedAt":140,"readTime":141,"slug":142,"title":143},"post-generated-types",{"avatar":125,"name":130,"role":131},{"_type":126,"alt":127,"asset":128},"image","Portrait of Avery Lin",{"_ref":129,"_type":15},"image-7d9d32f0d8cbaa44274ac31144c4acd3b6256c53-512x512-jpg","Avery Lin","Content Architect",[133,134],{"slug":115,"title":116},{"slug":107,"title":108},"Types written by hand describe what you believed the schema said. Types generated from it describe what the schema actually says.",{"_type":126,"alt":137,"asset":138},"Abstract cyan gradient suggesting a type graph",{"_ref":139,"_type":15},"image-17a06078263667a676c81409a6913d585588058a-1600x900-jpg","2026-08-12T09:00:00.000Z",1,"generated-types-are-a-contract","Generated types are a contract, not a convenience",{"_id":145,"authorProfile":146,"categories":153,"excerpt":156,"mainImage":157,"publishedAt":161,"readTime":141,"slug":162,"title":163},"post-preview-without-token",{"avatar":147,"name":151,"role":152},{"_type":126,"alt":148,"asset":149},"Portrait of Jordan Hale",{"_ref":150,"_type":15},"image-3a10e41064c69525bf602e7eb0d241fe88c6c9f7-512x512-jpg","Jordan Hale","Front-end Engineer",[154,155],{"slug":115,"title":116},{"slug":119,"title":120},"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":126,"alt":158,"asset":159},"Abstract magenta gradient suggesting a secure channel",{"_ref":160,"_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":165,"authorProfile":166,"categories":173,"excerpt":176,"mainImage":177,"publishedAt":181,"readTime":141,"slug":182,"title":183},"post-dark-mode-axis",{"avatar":167,"name":171,"role":172},{"_type":126,"alt":168,"asset":169},"Portrait of Priya Raman",{"_ref":170,"_type":15},"image-cfc7cc28fea565890fb3a5986f7d299c7704a12a-512x512-jpg","Priya Raman","Design Systems Engineer",[174,175],{"slug":111,"title":112},{"slug":119,"title":120},"The server cannot know which colour scheme a visitor prefers. Anything you render that depends on it will hydrate differently than it painted.",{"_type":126,"alt":178,"asset":179},"Abstract indigo gradient split between light and dark",{"_ref":180,"_type":15},"image-96db9eded5277118c54a29e63593a6d24a382797-1600x900-jpg","2026-07-09T09:00:00.000Z","dark-mode-is-a-second-axis","Dark mode is a second axis, not a second stylesheet",{"_id":185,"authorProfile":186,"categories":189,"excerpt":192,"mainImage":193,"publishedAt":197,"readTime":141,"slug":198,"title":199},"post-design-tokens",{"avatar":187,"name":130,"role":131},{"_type":126,"alt":127,"asset":188},{"_ref":129,"_type":15},[190,191],{"slug":111,"title":112},{"slug":107,"title":108},"When an editor picks a brand colour, half a dozen derived values have to stay legible. Here is how to derive them once instead of hard-coding them everywhere.",{"_type":126,"alt":194,"asset":195},"Abstract magenta gradient representing a derived colour palette",{"_ref":196,"_type":15},"image-c96efd6b55a465dcb615ad80af90714207b25dbc-1600x900-jpg","2026-06-21T09:00:00.000Z","theme-colours-belong-to-the-content","Theme colours belong to the content, not the stylesheet",{"_id":201,"authorProfile":202,"categories":205,"excerpt":207,"mainImage":208,"publishedAt":212,"readTime":141,"slug":213,"title":214},"post-static-generation",{"avatar":203,"name":151,"role":152},{"_type":126,"alt":148,"asset":204},{"_ref":150,"_type":15},[206],{"slug":119,"title":120},"Prerendering makes a site fast and cheap. It also quietly bakes every assumption your code makes about the request into the HTML you ship.",{"_type":126,"alt":209,"asset":210},"Abstract green gradient suggesting speed and layered caching",{"_ref":211,"_type":15},"image-e6a24a7111f8dd00b29b9257b2a3ed4cd8d1352d-1600x900-jpg","2026-06-02T09:00:00.000Z","static-generation-is-a-caching-strategy","Static generation is a caching strategy, not an architecture",{"_id":216,"authorProfile":217,"categories":220,"excerpt":222,"mainImage":223,"publishedAt":227,"readTime":228,"slug":229,"title":230},"post-structured-content",{"avatar":218,"name":130,"role":131},{"_type":126,"alt":127,"asset":219},{"_ref":129,"_type":15},[221],{"slug":107,"title":108},"Page-shaped content models feel productive for about six weeks. Here is what to model instead, and how to tell when a field is describing meaning rather than layout.",{"_type":126,"alt":224,"asset":225},"Abstract blue gradient representing structured content layers",{"_ref":226,"_type":15},"image-dd16abed87c4fcb58e0c410eb2451fe86bd707e2-1600x900-jpg","2026-05-14T09:00:00.000Z",2,"structured-content-over-page-builders","Why your CMS should not know what a hero section is",{"_id":232,"authorProfile":233,"categories":236,"excerpt":239,"mainImage":240,"publishedAt":244,"readTime":141,"slug":245,"title":246},"post-scaffolding",{"avatar":234,"name":171,"role":172},{"_type":126,"alt":168,"asset":235},{"_ref":170,"_type":15},[237,238],{"slug":115,"title":116},{"slug":111,"title":112},"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":126,"alt":241,"asset":242},"Abstract green gradient suggesting generated structure",{"_ref":243,"_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":248,"authorProfile":249,"categories":252,"excerpt":255,"mainImage":256,"publishedAt":260,"readTime":141,"slug":261,"title":262},"post-hydration-cost",{"avatar":250,"name":151,"role":152},{"_type":126,"alt":148,"asset":251},{"_ref":150,"_type":15},[253,254],{"slug":119,"title":120},{"slug":115,"title":116},"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":126,"alt":257,"asset":258},"Abstract blue gradient suggesting a request waterfall",{"_ref":259,"_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",{"_id":264,"authorProfile":265,"categories":268,"excerpt":271,"mainImage":272,"publishedAt":276,"readTime":141,"slug":277,"title":278},"post-type-scale",{"avatar":266,"name":171,"role":172},{"_type":126,"alt":168,"asset":267},{"_ref":170,"_type":15},[269,270],{"slug":111,"title":112},{"slug":107,"title":108},"Every scale looks balanced against three words of placeholder. The test is a heading an editor actually wrote, on a phone, in two languages.",{"_type":126,"alt":273,"asset":274},"Abstract amber gradient suggesting stepped type sizes",{"_ref":275,"_type":15},"image-aa3a1dd55ed9709d36bafe8f5715c90b8906166f-1600x900-jpg","2026-02-24T09:00:00.000Z","a-type-scale-has-to-survive-real-content","A type scale has to survive real content",{"_id":280,"authorProfile":281,"categories":284,"excerpt":287,"mainImage":288,"publishedAt":292,"readTime":141,"slug":293,"title":294},"post-image-budget",{"avatar":282,"name":151,"role":152},{"_type":126,"alt":148,"asset":283},{"_ref":150,"_type":15},[285,286],{"slug":119,"title":120},{"slug":111,"title":112},"Almost every page that feels slow is slow because of its images. Everything else on the budget is rounding error by comparison.",{"_type":126,"alt":289,"asset":290},"Abstract green gradient suggesting layered image tiles",{"_ref":291,"_type":15},"image-6c0abb272e46ebd287a2e6a3e738561c7ed18a2b-1600x900-jpg","2026-01-15T09:00:00.000Z","the-image-pipeline-is-the-performance-budget","The image pipeline is the performance budget",{"_id":296,"authorProfile":297,"categories":300,"excerpt":303,"mainImage":304,"publishedAt":308,"readTime":141,"slug":309,"title":310},"post-references-not-strings",{"avatar":298,"name":130,"role":131},{"_type":126,"alt":127,"asset":299},{"_ref":129,"_type":15},[301,302],{"slug":107,"title":108},{"slug":115,"title":116},"A string is cheap to add and expensive to keep. Every duplicated value is a migration waiting for the day someone spells it differently.",{"_type":126,"alt":305,"asset":306},"Abstract teal gradient suggesting linked nodes",{"_ref":307,"_type":15},"image-e64e53386be102ea99eb285dfdd86bfddbc05fb8-1600x900-jpg","2025-11-06T09:00:00.000Z","the-reference-you-did-not-make","The reference you did not make is the migration you will",{"_id":312,"authorProfile":313,"categories":316,"excerpt":319,"mainImage":320,"publishedAt":324,"readTime":141,"slug":325,"title":326},"post-naming-for-editors",{"avatar":314,"name":171,"role":172},{"_type":126,"alt":168,"asset":315},{"_ref":170,"_type":15},[317,318],{"slug":107,"title":108},{"slug":111,"title":112},"Schema field names leak into the Studio. If they were chosen to satisfy a component prop, the person filling them in pays for it every day.",{"_type":126,"alt":321,"asset":322},"Abstract violet gradient representing labelled fields",{"_ref":323,"_type":15},"image-b10db2de4605e9a295728b4e85786db552265e02-1600x900-jpg","2025-09-18T09:00:00.000Z","name-the-field-for-the-editor","Name the field for the editor, not for the component",1788029817765]