[{"data":1,"prerenderedAt":233},["ShallowReactive",2],{"sanity-LevEgKvCUg3Ul3GKyhTsfZIfaGswLQ-qsmdjo9-lWe4":3,"sanity-jZaOL3MTdkwQFLcmIYGOTRa8LUdQcHoMBV52VqWoM18":42},{"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","6nvKuEL9zc4dBn99tbDSIo","2026-09-15T23:28:13Z",{"_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":146,"excerpt":154,"footer":26,"layout":155,"mainImage":159,"navigation":26,"publishedAt":163,"readTime":164,"relatedPosts":165,"routeOptions":223,"seo":26,"showOnWebsite":225,"slug":228,"tags":229,"title":232},"post-structured-content","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,98,106,114,122,130,138],{"_key":63,"_type":64,"children":65,"markDefs":71,"style":72},"b0001","block",[66],{"_key":67,"_type":68,"marks":69,"text":70},"s0002","span",[],"Most content models start honestly and drift. The first few types describe things the business actually has — a product, an author, a case study. Then a designer needs a two-column band with a tinted background, and a field called backgroundVariant appears. Six months later the model is a catalogue of visual arrangements, and nobody can answer the question the CMS exists to answer: what do we publish?",[],"normal",{"_key":74,"_type":64,"children":75,"markDefs":80,"style":81},"b0003",[76],{"_key":77,"_type":68,"marks":78,"text":79},"s0004",[],"Model meaning, not arrangement",[],"h2",{"_key":83,"_type":64,"children":84,"markDefs":89,"style":72},"b0005",[85],{"_key":86,"_type":68,"marks":87,"text":88},"s0006",[],"The test is portability. If you had to publish the same content to a newsletter, an app, and a voice assistant, which fields would survive? Title, excerpt, author, body and category survive. A field named paddingTop does not. That is not a rule about tidiness — it is the difference between content you can reuse and content that only renders once.",[],{"_key":91,"_type":64,"children":92,"markDefs":97,"style":72},"b0007",[93],{"_key":94,"_type":68,"marks":95,"text":96},"s0008",[],"This does not mean layout has no home. It means layout belongs in a layout object, quarantined from the fields that carry meaning, so a redesign touches one part of the document and leaves the rest untouched.",[],{"_key":99,"_type":64,"children":100,"markDefs":105,"style":81},"b0009",[101],{"_key":102,"_type":68,"marks":103,"text":104},"s0010",[],"References beat duplication",[],{"_key":107,"_type":64,"children":108,"markDefs":113,"style":72},"b0011",[109],{"_key":110,"_type":68,"marks":111,"text":112},"s0012",[],"An author typed as a plain string is the single most common modelling shortcut, and the most expensive one to undo. The moment you want a bio, a photo, a role, or structured data authorship, that string has to become a document — and every post referencing it by name has to be migrated. Reach for a reference the first time you notice the same value being typed twice.",[],{"_key":115,"_type":64,"children":116,"markDefs":121,"style":72},"b0013",[117],{"_key":118,"_type":68,"marks":119,"text":120},"s0014",[],"The cost of a reference is one extra click for an editor. The cost of not having one is a migration, and migrations against live content are never as clean as they look in a planning document.",[],{"_key":123,"_type":64,"children":124,"markDefs":129,"style":81},"b0015",[125],{"_key":126,"_type":68,"marks":127,"text":128},"s0016",[],"Let the query do the derivation",[],{"_key":131,"_type":64,"children":132,"markDefs":137,"style":72},"b0017",[133],{"_key":134,"_type":68,"marks":135,"text":136},"s0018",[],"Reading time is a good example. It can live as an editable number, be computed in the template, or be projected by the query. Only the last option guarantees that a card in a listing and the post page itself agree, because there is exactly one implementation and the listing does not have to fetch the entire body to use it.",[],{"_key":139,"_type":64,"children":140,"markDefs":145,"style":72},"b0019",[141],{"_key":142,"_type":68,"marks":143,"text":144},"s0020",[],"Every value you derive in a component is a value some other component will derive slightly differently. Push derivation toward the data and the inconsistency has nowhere to live.",[],[147],{"_createdAt":5,"_id":148,"_rev":149,"_type":150,"_updatedAt":151,"slug":152,"title":153},"category-content-modelling","fb4cU9w5jE41W7xStm8DMV","category","2026-09-15T23:28:10Z","content-modelling","Content Modelling","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":156,"layout":157,"pageDesign":158},"post.layout.options","default","design1",{"_type":49,"alt":160,"asset":161},"Abstract blue gradient representing structured content layers",{"_ref":162,"_type":15},"image-dd16abed87c4fcb58e0c410eb2451fe86bd707e2-1600x900-jpg","2026-05-14T09:00:00.000Z",2,[166,185,203],{"_id":167,"authorProfile":168,"categories":171,"excerpt":176,"mainImage":177,"publishedAt":181,"readTime":182,"slug":183,"title":184},"post-generated-types",{"avatar":169,"name":54,"role":55},{"_type":49,"alt":50,"asset":170},{"_ref":52,"_type":15},[172,175],{"slug":173,"title":174},"developer-experience","Developer Experience",{"slug":152,"title":153},"Types written by hand describe what you believed the schema said. Types generated from it describe what the schema actually says.",{"_type":49,"alt":178,"asset":179},"Abstract cyan gradient suggesting a type graph",{"_ref":180,"_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":186,"authorProfile":187,"categories":190,"excerpt":195,"mainImage":196,"publishedAt":200,"readTime":182,"slug":201,"title":202},"post-design-tokens",{"avatar":188,"name":54,"role":55},{"_type":49,"alt":50,"asset":189},{"_ref":52,"_type":15},[191,194],{"slug":192,"title":193},"design-systems","Design Systems",{"slug":152,"title":153},"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":49,"alt":197,"asset":198},"Abstract magenta gradient representing a derived colour palette",{"_ref":199,"_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":204,"authorProfile":205,"categories":212,"excerpt":215,"mainImage":216,"publishedAt":220,"readTime":182,"slug":221,"title":222},"post-type-scale",{"avatar":206,"name":210,"role":211},{"_type":49,"alt":207,"asset":208},"Portrait of Priya Raman",{"_ref":209,"_type":15},"image-cfc7cc28fea565890fb3a5986f7d299c7704a12a-512x512-jpg","Priya Raman","Design Systems Engineer",[213,214],{"slug":192,"title":193},{"slug":152,"title":153},"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":49,"alt":217,"asset":218},"Abstract amber gradient suggesting stepped type sizes",{"_ref":219,"_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",{"_type":224,"includeInSitemap":225,"slug":226},"page.routing.options",true,{"_type":227,"current":228},"slug","structured-content-over-page-builders",[153,230,231],"Sanity","Information Architecture","Why your CMS should not know what a hero section is",1790674591694]