[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"topics-dev":3,"verticals":54,"articles-dev-1---":82},[4,10,14,19,23,27,32,37,41,46,50],{"id":5,"slug":6,"name":7,"parentId":8,"description":8,"articleCount":9},"019fe637-3e06-75b8-8a2c-fc350aad7701","vue","Vue",null,0,{"id":11,"slug":12,"name":13,"parentId":8,"description":8,"articleCount":9},"019fe637-3e06-75b8-8a2d-0309c35755c6","nuxt","Nuxt",{"id":15,"slug":16,"name":17,"parentId":8,"description":8,"articleCount":18},"019fe637-3e06-75b8-8a2d-040994c0d907","typescript","TypeScript",4,{"id":20,"slug":21,"name":22,"parentId":8,"description":8,"articleCount":9},"019fe637-3e06-75b8-8a2d-0956229cd176","architecture","Architecture",{"id":24,"slug":25,"name":26,"parentId":8,"description":8,"articleCount":9},"019fe637-3e07-735d-8227-4c34039af2e0","performance","Performance",{"id":28,"slug":29,"name":30,"parentId":8,"description":8,"articleCount":31},"019fe65f-98ec-773a-8ca8-9a2e971911c1","ai","AI",1,{"id":33,"slug":34,"name":35,"parentId":8,"description":8,"articleCount":36},"019fe65f-c110-761b-931e-99a2d1280410","css","CSS",16,{"id":38,"slug":39,"name":40,"parentId":8,"description":8,"articleCount":31},"019fe65f-a1cb-74c8-b999-ff353158fce9","designsystems","Design Systems",{"id":42,"slug":43,"name":44,"parentId":8,"description":8,"articleCount":45},"019fe65f-b950-7762-bb1a-d83445281950","javascript","JavaScript",18,{"id":47,"slug":48,"name":49,"parentId":8,"description":8,"articleCount":31},"019fe65f-b134-725b-bbc7-3e3db8c68675","react","React",{"id":51,"slug":52,"name":53,"parentId":8,"description":8,"articleCount":31},"019fe660-ce9d-754e-b241-7bccad915b86","security","Security",[55,70],{"id":56,"slug":57,"name":58,"tagline":59,"description":60,"accentFrom":61,"accentTo":62,"icon":63,"defaultLocale":64,"locales":65,"features":67,"position":9},"019fe637-3d33-714b-b57f-23e163ffca0c","dev","Web Development","Build. Learn. Ship.","Practical courses, engineering-grade articles and open-source tools for people who ship.","violet-500","cyan-400","◇","en",[64,66],"fa",{"courses":68,"paths":68,"articles":68,"exams":69,"flashcards":69,"packages":68,"community":68,"certificates":68,"teams":68,"commerce":68},true,false,{"id":71,"slug":72,"name":73,"tagline":74,"description":75,"accentFrom":76,"accentTo":61,"icon":77,"defaultLocale":64,"locales":78,"features":80,"position":81},"019fe637-3dc2-754c-8657-0f175bfee7c6","lang","Languages","Learn a language the way you learn a codebase.","Structured paths, listening drills and spaced repetition that actually sticks.","amber-400","⌘",[64,66,79],"es",{"courses":68,"paths":68,"articles":69,"exams":69,"flashcards":69,"packages":69,"community":68,"certificates":69,"teams":69,"commerce":68},2,{"items":83,"meta":316},[84,113,133,154,172,189,208,226,244,262,280,298],{"id":85,"slug":86,"title":87,"subtitle":8,"excerpt":88,"coverUrl":89,"locale":64,"readingMinutes":18,"publishedAt":90,"viewCount":91,"likeCount":9,"commentCount":9,"author":92,"vertical":97,"topic":98,"tags":99,"_count":111,"playground":112,"hasQuiz":68,"hasPlayground":68},"019fe660-de51-759d-935f-dbda9e7e38b5","array-from-async-async-iterable","You're collecting async iterable results with a for-await loop. `Array.fromAsync` does it in one call.","A for-await loop that pushes into an array, or the `await Promise.all([...asyncIterable])` workaround that silently fails — `Array.fromAsync` replaces both with a single awaited call. It's Baseline 2024.","\u002Fmedia\u002Fcovers\u002Farray-from-async-async-iterable.png","2026-08-05T08:42:50.920Z",177,{"id":93,"name":94,"username":95,"avatarUrl":8,"headline":96},"019fe637-3c25-7088-9034-39c9f15dc3c8","Parsa Jiravand","parsa","Frontend engineer · building bestpractic",{"slug":57,"name":58,"accentFrom":61,"accentTo":62},{"slug":43,"name":44},[100,102,105,108],{"slug":43,"name":101,"color":8},"Javascript",{"slug":103,"name":104,"color":8},"webdev","Webdev",{"slug":106,"name":107,"color":8},"frontend","Frontend",{"slug":109,"name":110,"color":8},"async","Async",{"assessments":31},{"slug":86},{"id":114,"slug":115,"title":116,"subtitle":8,"excerpt":117,"coverUrl":118,"locale":64,"readingMinutes":119,"publishedAt":120,"viewCount":121,"likeCount":9,"commentCount":9,"author":122,"vertical":123,"topic":124,"tags":125,"_count":131,"playground":132,"hasQuiz":68,"hasPlayground":68},"019fe660-d6d5-7099-89bb-af60e48fcb28","content-visibility-skip-offscreen-rendering","Your browser renders everything, even what you can't see — `content-visibility: auto` fixes that","Browsers lay out and paint the entire page on load, including the 80% below the fold. `content-visibility: auto` tells the browser to skip that work for off-screen elements — and it's Baseline 2024.","\u002Fmedia\u002Fcovers\u002Fcontent-visibility-skip-offscreen-rendering.png",5,"2026-08-04T08:44:59.227Z",157,{"id":93,"name":94,"username":95,"avatarUrl":8,"headline":96},{"slug":57,"name":58,"accentFrom":61,"accentTo":62},{"slug":34,"name":35},[126,128,129,130],{"slug":34,"name":127,"color":8},"Css",{"slug":103,"name":104,"color":8},{"slug":25,"name":26,"color":8},{"slug":106,"name":107,"color":8},{"assessments":31},{"slug":115},{"id":134,"slug":135,"title":136,"subtitle":8,"excerpt":137,"coverUrl":138,"locale":64,"readingMinutes":139,"publishedAt":140,"viewCount":141,"likeCount":9,"commentCount":9,"author":142,"vertical":143,"topic":144,"tags":145,"_count":152,"playground":153,"hasQuiz":68,"hasPlayground":68},"019fe660-cf2a-71df-b517-8d722f92cc37","weekly-cors-explained","CORS Explained: The Complete Guide (with Cheat Sheet)","A complete guide to CORS: the same-origin policy, preflight requests, and Access-Control-Allow-Origin headers — with worked examples and a cheat sheet.","\u002Fmedia\u002Fcovers\u002Fweekly-cors-explained.png",14,"2026-08-03T09:54:26.268Z",167,{"id":93,"name":94,"username":95,"avatarUrl":8,"headline":96},{"slug":57,"name":58,"accentFrom":61,"accentTo":62},{"slug":52,"name":53},[146,147,148,149],{"slug":103,"name":104,"color":8},{"slug":52,"name":53,"color":8},{"slug":43,"name":101,"color":8},{"slug":150,"name":151,"color":8},"tutorial","Tutorial",{"assessments":31},{"slug":135},{"id":155,"slug":156,"title":157,"subtitle":8,"excerpt":158,"coverUrl":159,"locale":64,"readingMinutes":18,"publishedAt":160,"viewCount":161,"likeCount":9,"commentCount":9,"author":162,"vertical":163,"topic":164,"tags":165,"_count":170,"playground":171,"hasQuiz":68,"hasPlayground":68},"019fe660-c754-703b-80fb-2254bb102ab7","scheduler-yield-main-thread","Your UI is freezing because you never gave the browser a break","Long synchronous tasks block the main thread and make your interface unresponsive. `scheduler.yield()` is the native way to hand control back to the browser mid-task so it can paint, handle input, and resume your work exactly where it left off.","\u002Fmedia\u002Fcovers\u002Fscheduler-yield-main-thread.png","2026-08-03T09:54:25.323Z",124,{"id":93,"name":94,"username":95,"avatarUrl":8,"headline":96},{"slug":57,"name":58,"accentFrom":61,"accentTo":62},{"slug":43,"name":44},[166,167,168,169],{"slug":43,"name":101,"color":8},{"slug":103,"name":104,"color":8},{"slug":25,"name":26,"color":8},{"slug":106,"name":107,"color":8},{"assessments":31},{"slug":156},{"id":173,"slug":174,"title":175,"subtitle":8,"excerpt":176,"coverUrl":177,"locale":64,"readingMinutes":119,"publishedAt":178,"viewCount":161,"likeCount":9,"commentCount":9,"author":179,"vertical":180,"topic":181,"tags":182,"_count":187,"playground":188,"hasQuiz":68,"hasPlayground":68},"019fe660-c020-760c-b4c7-46c1465e25bd","css-light-dark-function","You're writing dark-mode colors twice. `light-dark()` fixes that.","Every `@media (prefers-color-scheme: dark)` block duplicates your color definitions. `light-dark()` lets you write both values on the same line, in the same rule, with no separate block and no build step. Baseline 2024.","\u002Fmedia\u002Fcovers\u002Fcss-light-dark-function.png","2026-08-02T08:29:56.698Z",{"id":93,"name":94,"username":95,"avatarUrl":8,"headline":96},{"slug":57,"name":58,"accentFrom":61,"accentTo":62},{"slug":34,"name":35},[183,184,185,186],{"slug":34,"name":127,"color":8},{"slug":103,"name":104,"color":8},{"slug":106,"name":107,"color":8},{"slug":43,"name":101,"color":8},{"assessments":31},{"slug":174},{"id":190,"slug":191,"title":192,"subtitle":8,"excerpt":193,"coverUrl":194,"locale":64,"readingMinutes":119,"publishedAt":195,"viewCount":196,"likeCount":9,"commentCount":9,"author":197,"vertical":198,"topic":199,"tags":200,"_count":206,"playground":207,"hasQuiz":68,"hasPlayground":68},"019fe660-b8d7-7515-892c-bd576110158c","url-parse-safe-parsing","You've been wrapping `new URL()` in try\u002Fcatch. `URL.parse()` does it natively.","Validating an untrusted URL before parsing it used to mean a try\u002Fcatch wrapper or a regex. `URL.canParse()` checks validity without constructing. `URL.parse()` parses and returns null on failure. Both are Baseline 2024 — no wrapper needed.","\u002Fmedia\u002Fcovers\u002Furl-parse-safe-parsing.png","2026-08-01T08:27:13.710Z",75,{"id":93,"name":94,"username":95,"avatarUrl":8,"headline":96},{"slug":57,"name":58,"accentFrom":61,"accentTo":62},{"slug":43,"name":44},[201,202,203,204],{"slug":43,"name":101,"color":8},{"slug":103,"name":104,"color":8},{"slug":106,"name":107,"color":8},{"slug":16,"name":205,"color":8},"Typescript",{"assessments":31},{"slug":191},{"id":209,"slug":210,"title":211,"subtitle":8,"excerpt":212,"coverUrl":213,"locale":64,"readingMinutes":119,"publishedAt":214,"viewCount":215,"likeCount":9,"commentCount":9,"author":216,"vertical":217,"topic":218,"tags":219,"_count":224,"playground":225,"hasQuiz":68,"hasPlayground":68},"019fe660-b09d-731e-b160-9e45270a5652","css-scope-native-style-scoping","CSS has no native scoping. `@scope` changes that.","BEM, CSS Modules, and scoped component styles all exist because CSS leaks — a rule written for one component can silently affect another. `@scope` gives the cascade a lower boundary so styles stay where you put them, natively, with no build step.","\u002Fmedia\u002Fcovers\u002Fcss-scope-native-style-scoping.png","2026-07-31T08:56:20.507Z",77,{"id":93,"name":94,"username":95,"avatarUrl":8,"headline":96},{"slug":57,"name":58,"accentFrom":61,"accentTo":62},{"slug":34,"name":35},[220,221,222,223],{"slug":34,"name":127,"color":8},{"slug":103,"name":104,"color":8},{"slug":106,"name":107,"color":8},{"slug":43,"name":101,"color":8},{"assessments":31},{"slug":210},{"id":227,"slug":228,"title":229,"subtitle":8,"excerpt":230,"coverUrl":231,"locale":64,"readingMinutes":119,"publishedAt":232,"viewCount":233,"likeCount":9,"commentCount":9,"author":234,"vertical":235,"topic":236,"tags":237,"_count":242,"playground":243,"hasQuiz":68,"hasPlayground":68},"019fe660-a973-77a9-9820-826bf25fd884","iterator-helpers-lazy-filter-map","Array methods are eager. Iterator helpers are lazy. Here's why that matters.","Every `.map()` and `.filter()` on an array creates a new intermediate array. Iterator helpers — built into JavaScript since 2024 — give you the same pipeline but evaluate one element at a time, with no wasted allocations.","\u002Fmedia\u002Fcovers\u002Fiterator-helpers-lazy-filter-map.png","2026-07-30T08:34:21.684Z",76,{"id":93,"name":94,"username":95,"avatarUrl":8,"headline":96},{"slug":57,"name":58,"accentFrom":61,"accentTo":62},{"slug":43,"name":44},[238,239,240,241],{"slug":43,"name":101,"color":8},{"slug":103,"name":104,"color":8},{"slug":106,"name":107,"color":8},{"slug":25,"name":26,"color":8},{"assessments":31},{"slug":228},{"id":245,"slug":246,"title":247,"subtitle":8,"excerpt":248,"coverUrl":249,"locale":64,"readingMinutes":18,"publishedAt":250,"viewCount":251,"likeCount":9,"commentCount":9,"author":252,"vertical":253,"topic":254,"tags":255,"_count":260,"playground":261,"hasQuiz":68,"hasPlayground":68},"019fe660-a1fc-740c-9df4-b60a02de8afa","css-color-mix-native-color-mixing","You reach for Sass to mix colors. `color-mix()` does it natively.","Sass's `darken()`, `lighten()`, and `mix()` functions solved real problems CSS couldn't handle for decades. `color-mix()` is the native answer, and it ships in every modern browser with no build step required.","\u002Fmedia\u002Fcovers\u002Fcss-color-mix-native-color-mixing.png","2026-07-29T08:47:34.803Z",55,{"id":93,"name":94,"username":95,"avatarUrl":8,"headline":96},{"slug":57,"name":58,"accentFrom":61,"accentTo":62},{"slug":34,"name":35},[256,257,258,259],{"slug":34,"name":127,"color":8},{"slug":103,"name":104,"color":8},{"slug":106,"name":107,"color":8},{"slug":43,"name":101,"color":8},{"assessments":31},{"slug":246},{"id":263,"slug":264,"title":265,"subtitle":8,"excerpt":266,"coverUrl":267,"locale":64,"readingMinutes":18,"publishedAt":268,"viewCount":269,"likeCount":9,"commentCount":9,"author":270,"vertical":271,"topic":272,"tags":273,"_count":278,"playground":279,"hasQuiz":68,"hasPlayground":68},"019fe660-9a9b-73dc-87cd-48744e21e671","text-wrap-balance-headline-orphans","You hand-edit headlines to avoid orphaned words. `text-wrap: balance` does it natively.","The classic fix for a headline that breaks awkwardly — a manual `\u003Cbr>`, a `&shy;`, or a max-width tweak — exists because CSS had no way to distribute line breaks evenly. `text-wrap: balance` and `text-wrap: pretty` are the native answers.","\u002Fmedia\u002Fcovers\u002Ftext-wrap-balance-headline-orphans.png","2026-07-28T08:41:41.989Z",53,{"id":93,"name":94,"username":95,"avatarUrl":8,"headline":96},{"slug":57,"name":58,"accentFrom":61,"accentTo":62},{"slug":34,"name":35},[274,275,276,277],{"slug":34,"name":127,"color":8},{"slug":103,"name":104,"color":8},{"slug":106,"name":107,"color":8},{"slug":43,"name":101,"color":8},{"assessments":31},{"slug":264},{"id":281,"slug":282,"title":283,"subtitle":8,"excerpt":284,"coverUrl":285,"locale":64,"readingMinutes":18,"publishedAt":286,"viewCount":287,"likeCount":9,"commentCount":9,"author":288,"vertical":289,"topic":290,"tags":291,"_count":296,"playground":297,"hasQuiz":68,"hasPlayground":68},"019fe660-8482-75bc-ab16-8e86f92efc09","resize-observer-element-size","You're watching `window` to detect element size changes. `ResizeObserver` watches the element itself.","A `window` resize listener only fires when the viewport changes. ResizeObserver fires whenever the element's own box changes — from content loading, parent reflow, container queries, or anything else.","\u002Fmedia\u002Fcovers\u002Fresize-observer-element-size.png","2026-07-26T08:32:44.347Z",49,{"id":93,"name":94,"username":95,"avatarUrl":8,"headline":96},{"slug":57,"name":58,"accentFrom":61,"accentTo":62},{"slug":43,"name":44},[292,293,294,295],{"slug":43,"name":101,"color":8},{"slug":103,"name":104,"color":8},{"slug":106,"name":107,"color":8},{"slug":25,"name":26,"color":8},{"assessments":31},{"slug":282},{"id":299,"slug":300,"title":301,"subtitle":8,"excerpt":302,"coverUrl":303,"locale":64,"readingMinutes":18,"publishedAt":304,"viewCount":305,"likeCount":9,"commentCount":9,"author":306,"vertical":307,"topic":308,"tags":309,"_count":314,"playground":315,"hasQuiz":68,"hasPlayground":68},"019fe660-7d17-745b-812d-b1e81a1b2b85","css-starting-style-entry-animations","You use a setTimeout to trigger CSS entry animations. `@starting-style` makes it unnecessary.","Before `@starting-style`, the moment an element entered the DOM was invisible to CSS — transitions had no 'before' state to interpolate from. The at-rule gives you one, natively, with no JavaScript required.","\u002Fmedia\u002Fcovers\u002Fcss-starting-style-entry-animations.png","2026-07-25T08:13:02.298Z",51,{"id":93,"name":94,"username":95,"avatarUrl":8,"headline":96},{"slug":57,"name":58,"accentFrom":61,"accentTo":62},{"slug":34,"name":35},[310,311,312,313],{"slug":34,"name":127,"color":8},{"slug":103,"name":104,"color":8},{"slug":106,"name":107,"color":8},{"slug":43,"name":101,"color":8},{"assessments":31},{"slug":300},{"page":31,"perPage":317,"total":318,"totalPages":18},12,42]