[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"verticals":3,"tag-frontend-8":44,"search-suggestions":283,"tags-all":320},[4,20,32],{"id":5,"slug":6,"name":7,"tagline":8,"description":9,"accentFrom":10,"accentTo":11,"icon":12,"defaultLocale":13,"locales":14,"features":16,"position":19},"019fe637-3d33-714b-b57f-23e163ffca0c","dev","Web Development","Read it. Run it. Prove it.","A post a day on modern web development — most with an editable playground and a quiz that explains every answer. Free, no account needed.","violet-500","cyan-400","◇","en",[13,15],"fa",{"courses":17,"paths":17,"articles":17,"exams":18,"flashcards":18,"packages":17,"community":17,"certificates":17,"teams":17,"commerce":17},true,false,0,{"id":21,"slug":22,"name":23,"tagline":24,"description":25,"accentFrom":26,"accentTo":10,"icon":27,"defaultLocale":13,"locales":28,"features":30,"position":31},"019fe637-3dc2-754c-8657-0f175bfee7c6","lang","Languages","Learn a language the way you learn a codebase.","Grammar explained the way good documentation explains an API — one idea at a time, each with a quiz.","amber-400","⌘",[13,15,29],"es",{"courses":18,"paths":18,"articles":17,"exams":18,"flashcards":17,"packages":18,"community":17,"certificates":17,"teams":18,"commerce":18},2,{"id":33,"slug":34,"name":35,"tagline":36,"description":37,"accentFrom":38,"accentTo":39,"icon":40,"defaultLocale":13,"locales":41,"features":42,"position":43},"7b3c16f2-931d-410e-802e-e1fa4edab7de","soft","Soft Skills","The half of the job nobody wrote documentation for.","Weekly, on the parts of working life that decide more than your code does — first weeks, meetings, interviews, promotions, and the people around you. Written from what actually happens, and recorded as a podcast you can listen to on the walk.","emerald-400","teal-300","◉",[13],{"courses":18,"paths":18,"articles":17,"exams":18,"flashcards":18,"packages":18,"community":17,"certificates":18,"teams":18,"commerce":18},3,{"items":45,"meta":279},[46,80,99,120,137,154,171,188,205,222,239,261],{"id":47,"slug":48,"title":49,"subtitle":50,"excerpt":51,"coverUrl":52,"locale":13,"readingMinutes":53,"publishedAt":54,"viewCount":55,"likeCount":19,"commentCount":19,"author":56,"vertical":61,"topic":62,"tags":65,"_count":77,"playground":79,"hasQuiz":17,"hasPlayground":17},"019fe65f-f67a-7038-9c0d-874d6c8ece3c","css-property-registered-custom-properties","You can't transition a CSS variable. @property says otherwise.",null,"CSS custom properties are string substitution — the browser doesn't know a number from a color. Register one with @property and it gains a real type, an initial value, and the ability to animate.","\u002Fmedia\u002Fcovers\u002Fcss-property-registered-custom-properties.png",5,"2026-07-08T08:36:23.824Z",614,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},"019fe637-3c25-7088-9034-39c9f15dc3c8","Parsa Jiravand","parsa","Frontend engineer · building bestpractic",{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},"css","CSS",[66,68,71,74],{"slug":63,"name":67,"color":50},"Css",{"slug":69,"name":70,"color":50},"webdev","Webdev",{"slug":72,"name":73,"color":50},"frontend","Frontend",{"slug":75,"name":76,"color":50},"javascript","Javascript",{"assessments":78},1,{"slug":48},{"id":81,"slug":82,"title":83,"subtitle":50,"excerpt":84,"coverUrl":85,"locale":13,"readingMinutes":86,"publishedAt":87,"viewCount":88,"likeCount":19,"commentCount":19,"author":89,"vertical":90,"topic":91,"tags":92,"_count":97,"playground":98,"hasQuiz":17,"hasPlayground":17},"019fe65f-ef22-765a-97c7-cdfdbb168024","scroll-driven-animations","Your scroll listener is doing CSS's job","Reading progress bars, reveal-on-scroll effects, parallax — you've been writing these in JavaScript. CSS scroll-driven animations bind them directly to scroll position, off the main thread, in a handful of lines.","\u002Fmedia\u002Fcovers\u002Fscroll-driven-animations.png",6,"2026-07-06T10:47:02.014Z",455,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[93,94,95,96],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"assessments":78},{"slug":82},{"id":100,"slug":101,"title":102,"subtitle":50,"excerpt":103,"coverUrl":104,"locale":13,"readingMinutes":105,"publishedAt":106,"viewCount":107,"likeCount":19,"commentCount":19,"author":108,"vertical":109,"topic":110,"tags":112,"_count":119,"playground":50,"hasQuiz":18,"hasPlayground":18},"019fe65f-e7b8-7175-a185-34775c370bcf","abort-controller-async-cancellation","Your fetch() Is Still Running After the User Left","Stale requests, race conditions in search boxes, state updates on unmounted components — these are all the same bug: async work you forgot to cancel. AbortController is the fix.","\u002Fmedia\u002Fcovers\u002Fabort-controller-async-cancellation.png",4,"2026-07-05T09:12:47.873Z",319,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":75,"name":111},"JavaScript",[113,114,115,116],{"slug":75,"name":76,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":117,"name":118,"color":50},"react","React",{"assessments":19},{"id":121,"slug":122,"title":123,"subtitle":50,"excerpt":124,"coverUrl":125,"locale":13,"readingMinutes":53,"publishedAt":126,"viewCount":127,"likeCount":19,"commentCount":19,"author":128,"vertical":129,"topic":130,"tags":131,"_count":136,"playground":50,"hasQuiz":18,"hasPlayground":18},"019fe65f-e05c-77bb-b8a3-cb8dbdc99346","css-layer-architecture","You reached for !important again. @layer is the real fix.","When a third-party reset beats your styles and your own utilities lose to an ancient nested rule, the problem isn't your selectors. It's that your stylesheet has no architecture. @layer adds one.","\u002Fmedia\u002Fcovers\u002Fcss-layer-architecture.png","2026-07-04T08:44:02.193Z",175,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[132,133,134,135],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"assessments":19},{"id":138,"slug":139,"title":140,"subtitle":50,"excerpt":141,"coverUrl":142,"locale":13,"readingMinutes":53,"publishedAt":143,"viewCount":144,"likeCount":19,"commentCount":19,"author":145,"vertical":146,"topic":147,"tags":148,"_count":153,"playground":50,"hasQuiz":18,"hasPlayground":18},"019fe65f-d8d6-73ed-b26b-18726a494914","view-transitions-native-page-transitions","The page transition you pay a library for is now free","You reach for Framer Motion or GSAP to make navigation feel smooth. The View Transitions API does the same thing natively — and the starting price is a single CSS rule.","\u002Fmedia\u002Fcovers\u002Fview-transitions-native-page-transitions.png","2026-07-03T09:26:36.534Z",187,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[149,150,151,152],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"assessments":19},{"id":155,"slug":156,"title":157,"subtitle":50,"excerpt":158,"coverUrl":159,"locale":13,"readingMinutes":105,"publishedAt":160,"viewCount":161,"likeCount":19,"commentCount":19,"author":162,"vertical":163,"topic":164,"tags":165,"_count":170,"playground":50,"hasQuiz":18,"hasPlayground":18},"019fe65f-d19a-709a-855e-54178d886feb","has-selector-condition-evaluator",":has() isn't a parent selector. It deletes JavaScript.","Everyone calls :has() the parent selector. That framing is too small — it's a condition evaluator that obsoletes a whole category of class-toggling JS, and it's in every browser today.","\u002Fmedia\u002Fcovers\u002Fhas-selector-condition-evaluator.png","2026-07-02T07:18:03.500Z",235,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[166,167,168,169],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"assessments":19},{"id":172,"slug":173,"title":174,"subtitle":50,"excerpt":175,"coverUrl":176,"locale":13,"readingMinutes":105,"publishedAt":177,"viewCount":178,"likeCount":19,"commentCount":19,"author":179,"vertical":180,"topic":181,"tags":182,"_count":187,"playground":50,"hasQuiz":18,"hasPlayground":18},"019fe65f-c9aa-70db-8ac8-df39bed8061b","optimistic-updates-stop-waiting-for-the-server","Optimistic Updates: Stop Making Your Save Button Wait for the Server","Every click that spins for a server round-trip is a choice you made. Optimistic updates remove the wait — but the rollback is where almost every implementation quietly breaks.","\u002Fmedia\u002Fcovers\u002Foptimistic-updates-stop-waiting-for-the-server.png","2026-07-01T07:42:41.462Z",250,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":75,"name":111},[183,184,185,186],{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"slug":117,"name":118,"color":50},{"assessments":19},{"id":189,"slug":190,"title":191,"subtitle":50,"excerpt":192,"coverUrl":193,"locale":13,"readingMinutes":53,"publishedAt":194,"viewCount":195,"likeCount":19,"commentCount":19,"author":196,"vertical":197,"topic":198,"tags":199,"_count":204,"playground":50,"hasQuiz":18,"hasPlayground":18},"019fe65f-c193-7159-96ba-bff62b34e53d","container-queries-responsive-primitive","Your card breaks in the sidebar. Here's the real fix.","A component that looks perfect in the main column falls apart in a sidebar — and the viewport width says everything's fine. The bug isn't your CSS. It's the question your CSS is asking.","\u002Fmedia\u002Fcovers\u002Fcontainer-queries-responsive-primitive.png","2026-06-30T07:30:01.218Z",198,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[200,201,202,203],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"assessments":19},{"id":206,"slug":207,"title":208,"subtitle":50,"excerpt":209,"coverUrl":210,"locale":13,"readingMinutes":105,"publishedAt":211,"viewCount":212,"likeCount":19,"commentCount":19,"author":213,"vertical":214,"topic":215,"tags":216,"_count":221,"playground":50,"hasQuiz":18,"hasPlayground":18},"019fe65f-b9de-72a8-8656-ee81360dbd99","url-as-state-manager","The URL Is Your Best State Manager","You're storing filter state, search queries, and pagination in useState — and losing it every time someone refreshes. The URL already does this better.","\u002Fmedia\u002Fcovers\u002Furl-as-state-manager.png","2026-06-29T07:59:09.726Z",318,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":75,"name":111},[217,218,219,220],{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"slug":117,"name":118,"color":50},{"assessments":19},{"id":223,"slug":224,"title":225,"subtitle":50,"excerpt":226,"coverUrl":227,"locale":13,"readingMinutes":43,"publishedAt":228,"viewCount":229,"likeCount":19,"commentCount":19,"author":230,"vertical":231,"topic":232,"tags":233,"_count":238,"playground":50,"hasQuiz":18,"hasPlayground":18},"019fe65f-b1ba-7644-b327-4118cffd7d22","server-components-mental-model","Server Components Without the Hype: A Mental Model That Sticks","RSC isn't 'SSR 2.0' and it isn't magic. Here's the one distinction that makes the whole model click.","\u002Fmedia\u002Fcovers\u002Fserver-components-mental-model.png","2026-06-28T09:41:35.140Z",239,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":117,"name":118},[234,235,236,237],{"slug":117,"name":118,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"assessments":19},{"id":240,"slug":241,"title":242,"subtitle":50,"excerpt":243,"coverUrl":244,"locale":13,"readingMinutes":43,"publishedAt":245,"viewCount":246,"likeCount":19,"commentCount":19,"author":247,"vertical":248,"topic":249,"tags":252,"_count":260,"playground":50,"hasQuiz":18,"hasPlayground":18},"019fe65f-a25a-702f-b8a0-ae60efb61964","design-system-api-for-machines","Your Design System Is Now an API for Machines","Component libraries used to be for humans. Now they're the rails an AI plans against — and that changes how you should build them.","\u002Fmedia\u002Fcovers\u002Fdesign-system-api-for-machines.png","2026-06-26T07:29:19.042Z",231,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":250,"name":251},"designsystems","Design Systems",[253,254,255,257],{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":250,"name":256,"color":50},"Designsystems",{"slug":258,"name":259,"color":50},"ai","Ai",{"assessments":19},{"id":262,"slug":263,"title":264,"subtitle":50,"excerpt":265,"coverUrl":266,"locale":13,"readingMinutes":53,"publishedAt":267,"viewCount":268,"likeCount":19,"commentCount":19,"author":269,"vertical":270,"topic":271,"tags":273,"_count":278,"playground":50,"hasQuiz":18,"hasPlayground":18},"019fe65f-9991-7098-a2e8-28d741366ffa","frontend-future-ai","The Frontend Is Becoming a Conversation: Where UI Engineering Goes Next","Frontend stacks consolidated, the rendering wars cooled off, and AI quietly changed what a frontend engineer actually does all day. Here's where it's heading.","\u002Fmedia\u002Fcovers\u002Ffrontend-future-ai.png","2026-06-25T12:27:00.662Z",295,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":258,"name":272},"AI",[274,275,276,277],{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":258,"name":259,"color":50},{"slug":75,"name":76,"color":50},{"assessments":19},{"page":280,"perPage":281,"total":282,"totalPages":280},8,12,96,[284,286,288,289,293,295,299,303,305,309,313,317],{"slug":69,"name":70,"articles":285},174,{"slug":75,"name":76,"articles":287},141,{"slug":72,"name":73,"articles":282},{"slug":290,"name":291,"articles":292},"tutorial","Tutorial",71,{"slug":63,"name":67,"articles":294},51,{"slug":296,"name":297,"articles":298},"performance","Performance",30,{"slug":300,"name":301,"articles":302},"typescript","Typescript",25,{"slug":117,"name":118,"articles":304},20,{"slug":306,"name":307,"articles":308},"programming","Programming",19,{"slug":310,"name":311,"articles":312},"browser","Browser",18,{"slug":314,"name":315,"articles":316},"node","Node",16,{"slug":318,"name":319,"articles":281},"html","Html",[321,322,323,324,325,326,327,328,329,330,331,332,333,337,341,344,348,351,354,357,361,364,367,370,373,376,377,380,383,386,389,392,395,398,401,404,407,410,413,416],{"slug":69,"name":70,"color":50,"articles":285},{"slug":75,"name":76,"color":50,"articles":287},{"slug":72,"name":73,"color":50,"articles":282},{"slug":290,"name":291,"color":50,"articles":292},{"slug":63,"name":67,"color":50,"articles":294},{"slug":296,"name":297,"color":50,"articles":298},{"slug":300,"name":301,"color":50,"articles":302},{"slug":117,"name":118,"color":50,"articles":304},{"slug":306,"name":307,"color":50,"articles":308},{"slug":310,"name":311,"color":50,"articles":312},{"slug":314,"name":315,"color":50,"articles":316},{"slug":318,"name":319,"color":50,"articles":281},{"slug":334,"name":335,"color":50,"articles":336},"nextjs","Nextjs",11,{"slug":338,"name":339,"color":50,"articles":340},"vue","Vue",10,{"slug":342,"name":343,"color":50,"articles":340},"accessibility","Accessibility",{"slug":345,"name":346,"color":50,"articles":347},"nestjs","Nestjs",9,{"slug":349,"name":350,"color":50,"articles":280},"nuxt","Nuxt",{"slug":352,"name":353,"color":50,"articles":280},"career","Career",{"slug":355,"name":356,"color":50,"articles":280},"discuss","Discuss",{"slug":358,"name":359,"color":50,"articles":360},"beginners","Beginners",7,{"slug":362,"name":363,"color":50,"articles":360},"productivity","Productivity",{"slug":365,"name":366,"color":50,"articles":86},"grammar","Grammar",{"slug":368,"name":369,"color":50,"articles":53},"security","Security",{"slug":371,"name":372,"color":50,"articles":105},"ssr","SSR",{"slug":374,"name":375,"color":50,"articles":105},"apis","Apis",{"slug":258,"name":259,"color":50,"articles":43},{"slug":378,"name":379,"color":50,"articles":43},"api","API",{"slug":381,"name":382,"color":50,"articles":43},"caching","Caching",{"slug":384,"name":385,"color":50,"articles":31},"async","Async",{"slug":387,"name":388,"color":50,"articles":31},"forms","Forms",{"slug":390,"name":391,"color":50,"articles":31},"dom","Dom",{"slug":393,"name":394,"color":50,"articles":31},"backend","Backend",{"slug":396,"name":397,"color":50,"articles":31},"english","English",{"slug":399,"name":400,"color":50,"articles":31},"verbs","Verbs",{"slug":402,"name":403,"color":50,"articles":31},"spanish","Spanish",{"slug":405,"name":406,"color":50,"articles":31},"a1","A1",{"slug":408,"name":409,"color":50,"articles":31},"a2","A2",{"slug":411,"name":412,"color":50,"articles":31},"tenses","Tenses",{"slug":414,"name":415,"color":50,"articles":31},"turkish","Turkish",{"slug":417,"name":418,"color":50,"articles":31},"animation","Animation"]