[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"verticals":3,"tag-javascript-7":44,"search-suggestions":296,"tags-all":324},[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":291},[46,80,101,122,145,163,181,202,220,238,256,274],{"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},"019fe660-48c5-70fe-a5b4-b20c5b2661e7","css-anchor-positioning","You're using Floating UI to position your tooltip. The browser does it natively now.",null,"CSS Anchor Positioning is Baseline 2026 — it lets any element declare itself an anchor and any floating element position relative to it in pure CSS. No JavaScript, no layout math, no ResizeObserver wiring.","\u002Fmedia\u002Fcovers\u002Fcss-anchor-positioning.png",5,"2026-07-18T07:59:42.250Z",309,{"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":53,"publishedAt":86,"viewCount":87,"likeCount":19,"commentCount":19,"author":88,"vertical":89,"topic":90,"tags":92,"_count":99,"playground":100,"hasQuiz":17,"hasPlayground":17},"019fe660-32b6-757d-a975-3860df795f67","immutable-array-methods","Your `.sort()` is mutating state. JavaScript finally gave you the fix.","The classic array methods — sort, reverse, splice — mutate the original array, silently breaking React state updates and surprising anyone who forgot to spread first. ES2023 added four immutable counterparts: toSorted, toReversed, toSpliced, and with.","\u002Fmedia\u002Fcovers\u002Fimmutable-array-methods.png","2026-07-15T08:22:28.270Z",277,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":75,"name":91},"JavaScript",[93,94,95,96],{"slug":75,"name":76,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":97,"name":98,"color":50},"react","React",{"assessments":78},{"slug":82},{"id":102,"slug":103,"title":104,"subtitle":50,"excerpt":105,"coverUrl":106,"locale":13,"readingMinutes":107,"publishedAt":108,"viewCount":109,"likeCount":19,"commentCount":19,"author":110,"vertical":111,"topic":112,"tags":113,"_count":120,"playground":121,"hasQuiz":17,"hasPlayground":17},"019fe660-2b2e-71fb-a0d1-fd1509765d3b","object-groupby-replace-reduce","You've been writing this `reduce` a hundred times. `Object.groupBy` does it in one.","Grouping an array by a key is one of the most common data transforms in frontend code. You've been wiring it by hand with `reduce` for years. `Object.groupBy` is the native version — no helper, no library, no ceremony.","\u002Fmedia\u002Fcovers\u002Fobject-groupby-replace-reduce.png",4,"2026-07-14T08:16:56.309Z",251,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":75,"name":91},[114,115,116,117],{"slug":75,"name":76,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":118,"name":119,"color":50},"node","Node",{"assessments":78},{"slug":103},{"id":123,"slug":124,"title":125,"subtitle":50,"excerpt":126,"coverUrl":127,"locale":13,"readingMinutes":128,"publishedAt":129,"viewCount":130,"likeCount":19,"commentCount":19,"author":131,"vertical":132,"topic":133,"tags":134,"_count":143,"playground":144,"hasQuiz":17,"hasPlayground":17},"019fe660-2335-7652-9e51-7c6f28871874","weekly-javascript-event-loop","JavaScript Event Loop Explained: The Complete Guide","Learn how the JavaScript event loop really works — call stack, microtasks, and macrotasks — with worked examples, edge cases, and a cheat sheet.","\u002Fmedia\u002Fcovers\u002Fweekly-javascript-event-loop.png",13,"2026-07-13T09:36:33.464Z",553,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":75,"name":91},[135,136,137,140],{"slug":75,"name":76,"color":50},{"slug":69,"name":70,"color":50},{"slug":138,"name":139,"color":50},"tutorial","Tutorial",{"slug":141,"name":142,"color":50},"programming","Programming",{"assessments":78},{"slug":124},{"id":146,"slug":147,"title":148,"subtitle":50,"excerpt":149,"coverUrl":150,"locale":13,"readingMinutes":53,"publishedAt":151,"viewCount":152,"likeCount":19,"commentCount":19,"author":153,"vertical":154,"topic":155,"tags":156,"_count":161,"playground":162,"hasQuiz":17,"hasPlayground":17},"019fe660-1be2-74dd-aa56-0c8fd84204fd","promise-concurrency-all-settled-any-race","You reach for `Promise.all` for every concurrent request. Here's when to use the other three.","`Promise.all` fails the moment any one request fails. `allSettled`, `any`, and `race` each solve a different concurrency problem — dashboard partial results, CDN failover, and timeouts. Here's the taxonomy.","\u002Fmedia\u002Fcovers\u002Fpromise-concurrency-all-settled-any-race.png","2026-07-13T09:36:32.501Z",230,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":75,"name":91},[157,158,159,160],{"slug":75,"name":76,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":118,"name":119,"color":50},{"assessments":78},{"slug":147},{"id":164,"slug":165,"title":166,"subtitle":50,"excerpt":167,"coverUrl":168,"locale":13,"readingMinutes":107,"publishedAt":169,"viewCount":170,"likeCount":19,"commentCount":19,"author":171,"vertical":172,"topic":173,"tags":174,"_count":179,"playground":180,"hasQuiz":17,"hasPlayground":17},"019fe660-1462-723e-9605-66ffa7e98f42","popover-api-native-popovers","Your dropdown is a div. The browser has a native popover now.","Custom dropdowns, tooltips, and menus built with stacked divs and click-outside listeners — the Popover API landed in every browser in 2024, and the baseline version is two HTML attributes.","\u002Fmedia\u002Fcovers\u002Fpopover-api-native-popovers.png","2026-07-12T08:24:42.323Z",262,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":75,"name":91},[175,176,177,178],{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":75,"name":76,"color":50},{"slug":63,"name":67,"color":50},{"assessments":78},{"slug":165},{"id":182,"slug":183,"title":184,"subtitle":50,"excerpt":185,"coverUrl":186,"locale":13,"readingMinutes":53,"publishedAt":187,"viewCount":188,"likeCount":19,"commentCount":19,"author":189,"vertical":190,"topic":191,"tags":194,"_count":200,"playground":201,"hasQuiz":17,"hasPlayground":17},"019fe660-0d25-72d6-8fd8-3cf3c3592e54","typescript-satisfies-operator","Your TypeScript config objects are losing type information. `satisfies` fixes it.","Type annotations widen your object types and erase the precise values TypeScript inferred. The `satisfies` operator validates against a type without changing what TypeScript keeps — you get the check without the widening.","\u002Fmedia\u002Fcovers\u002Ftypescript-satisfies-operator.png","2026-07-11T08:03:26.200Z",327,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":192,"name":193},"typescript","TypeScript",[195,197,198,199],{"slug":192,"name":196,"color":50},"Typescript",{"slug":69,"name":70,"color":50},{"slug":75,"name":76,"color":50},{"slug":72,"name":73,"color":50},{"assessments":78},{"slug":183},{"id":203,"slug":204,"title":205,"subtitle":50,"excerpt":206,"coverUrl":207,"locale":13,"readingMinutes":107,"publishedAt":208,"viewCount":209,"likeCount":19,"commentCount":19,"author":210,"vertical":211,"topic":212,"tags":213,"_count":218,"playground":219,"hasQuiz":17,"hasPlayground":17},"019fe660-0596-7433-9dc2-0fc620be2d0f","structuredclone-deep-clone","You've been deep-cloning objects with a JSON hack. `structuredClone` does it right.","JSON.parse(JSON.stringify(obj)) silently corrupts Dates, Maps, Sets, and undefined values. structuredClone is the native replacement — no library, no import, no surprises.","\u002Fmedia\u002Fcovers\u002Fstructuredclone-deep-clone.png","2026-07-10T09:43:33.966Z",224,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":75,"name":91},[214,215,216,217],{"slug":75,"name":76,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":118,"name":119,"color":50},{"assessments":78},{"slug":204},{"id":221,"slug":222,"title":223,"subtitle":50,"excerpt":224,"coverUrl":225,"locale":13,"readingMinutes":107,"publishedAt":226,"viewCount":227,"likeCount":19,"commentCount":19,"author":228,"vertical":229,"topic":230,"tags":231,"_count":236,"playground":237,"hasQuiz":17,"hasPlayground":17},"019fe65f-fe39-767c-9ce8-da4db5144b1d","css-nesting-sass-replaced","You kept Sass for one reason. Native CSS nesting just ended it.","CSS has supported nesting natively since 2023 — pseudo-classes, pseudo-elements, and @media queries nested inside the rules they belong to. No compiler required.","\u002Fmedia\u002Fcovers\u002Fcss-nesting-sass-replaced.png","2026-07-09T09:48:41.505Z",206,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[232,233,234,235],{"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":222},{"id":239,"slug":240,"title":241,"subtitle":50,"excerpt":242,"coverUrl":243,"locale":13,"readingMinutes":53,"publishedAt":244,"viewCount":245,"likeCount":19,"commentCount":19,"author":246,"vertical":247,"topic":248,"tags":249,"_count":254,"playground":255,"hasQuiz":17,"hasPlayground":17},"019fe65f-f67a-7038-9c0d-874d6c8ece3c","css-property-registered-custom-properties","You can't transition a CSS variable. @property says otherwise.","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","2026-07-08T08:36:23.824Z",347,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[250,251,252,253],{"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":240},{"id":257,"slug":258,"title":259,"subtitle":50,"excerpt":260,"coverUrl":261,"locale":13,"readingMinutes":53,"publishedAt":262,"viewCount":263,"likeCount":19,"commentCount":19,"author":264,"vertical":265,"topic":266,"tags":267,"_count":272,"playground":273,"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","2026-07-06T10:47:02.014Z",227,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[268,269,270,271],{"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":258},{"id":275,"slug":276,"title":277,"subtitle":50,"excerpt":278,"coverUrl":279,"locale":13,"readingMinutes":107,"publishedAt":280,"viewCount":281,"likeCount":19,"commentCount":19,"author":282,"vertical":283,"topic":284,"tags":285,"_count":290,"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","2026-07-05T09:12:47.873Z",189,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":75,"name":91},[286,287,288,289],{"slug":75,"name":76,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":97,"name":98,"color":50},{"assessments":19},{"page":292,"perPage":293,"total":294,"totalPages":295},7,12,93,8,[297,299,300,302,304,306,308,312,313,317,318,321],{"slug":69,"name":70,"articles":298},111,{"slug":75,"name":76,"articles":294},{"slug":72,"name":73,"articles":301},73,{"slug":138,"name":139,"articles":303},39,{"slug":63,"name":67,"articles":305},36,{"slug":192,"name":196,"articles":307},16,{"slug":309,"name":310,"articles":311},"performance","Performance",14,{"slug":97,"name":98,"articles":128},{"slug":314,"name":315,"articles":316},"browser","Browser",10,{"slug":118,"name":119,"articles":316},{"slug":319,"name":320,"articles":295},"html","Html",{"slug":322,"name":323,"articles":292},"accessibility","Accessibility",[325,326,327,328,329,330,331,332,333,334,335,336,337,339,342,345,348,351,354,357,360,363,366,369,372,375,378,381,384,387,390,393,396,399,402,405],{"slug":69,"name":70,"color":50,"articles":298},{"slug":75,"name":76,"color":50,"articles":294},{"slug":72,"name":73,"color":50,"articles":301},{"slug":138,"name":139,"color":50,"articles":303},{"slug":63,"name":67,"color":50,"articles":305},{"slug":192,"name":196,"color":50,"articles":307},{"slug":309,"name":310,"color":50,"articles":311},{"slug":97,"name":98,"color":50,"articles":128},{"slug":118,"name":119,"color":50,"articles":316},{"slug":314,"name":315,"color":50,"articles":316},{"slug":319,"name":320,"color":50,"articles":295},{"slug":322,"name":323,"color":50,"articles":292},{"slug":141,"name":142,"color":50,"articles":338},6,{"slug":340,"name":341,"color":50,"articles":338},"grammar","Grammar",{"slug":343,"name":344,"color":50,"articles":53},"nestjs","Nestjs",{"slug":346,"name":347,"color":50,"articles":107},"nextjs","Nextjs",{"slug":349,"name":350,"color":50,"articles":107},"apis","Apis",{"slug":352,"name":353,"color":50,"articles":43},"nuxt","Nuxt",{"slug":355,"name":356,"color":50,"articles":43},"ssr","SSR",{"slug":358,"name":359,"color":50,"articles":43},"ai","Ai",{"slug":361,"name":362,"color":50,"articles":43},"vue","Vue",{"slug":364,"name":365,"color":50,"articles":31},"security","Security",{"slug":367,"name":368,"color":50,"articles":31},"async","Async",{"slug":370,"name":371,"color":50,"articles":31},"forms","Forms",{"slug":373,"name":374,"color":50,"articles":31},"api","API",{"slug":376,"name":377,"color":50,"articles":31},"english","English",{"slug":379,"name":380,"color":50,"articles":31},"verbs","Verbs",{"slug":382,"name":383,"color":50,"articles":31},"spanish","Spanish",{"slug":385,"name":386,"color":50,"articles":31},"a1","A1",{"slug":388,"name":389,"color":50,"articles":31},"a2","A2",{"slug":391,"name":392,"color":50,"articles":31},"tenses","Tenses",{"slug":394,"name":395,"color":50,"articles":31},"turkish","Turkish",{"slug":397,"name":398,"color":50,"articles":31},"career","Career",{"slug":400,"name":401,"color":50,"articles":31},"beginners","Beginners",{"slug":403,"name":404,"color":50,"articles":31},"productivity","Productivity",{"slug":406,"name":407,"color":50,"articles":31},"discuss","Discuss"]