[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"verticals":3,"tag-webdev-12":44,"search-suggestions":294,"tags-all":327},[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,104,127,145,163,183,201,219,237,255,273],{"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-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.",null,"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",4,"2026-08-05T08:42:50.920Z",736,{"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},"javascript","JavaScript",[66,68,71,74],{"slug":63,"name":67,"color":50},"Javascript",{"slug":69,"name":70,"color":50},"webdev","Webdev",{"slug":72,"name":73,"color":50},"frontend","Frontend",{"slug":75,"name":76,"color":50},"async","Async",{"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":94,"_count":102,"playground":103,"hasQuiz":17,"hasPlayground":17},"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",1003,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":92,"name":93},"css","CSS",[95,97,98,101],{"slug":92,"name":96,"color":50},"Css",{"slug":69,"name":70,"color":50},{"slug":99,"name":100,"color":50},"performance","Performance",{"slug":72,"name":73,"color":50},{"assessments":78},{"slug":82},{"id":105,"slug":106,"title":107,"subtitle":50,"excerpt":108,"coverUrl":109,"locale":13,"readingMinutes":110,"publishedAt":111,"viewCount":112,"likeCount":19,"commentCount":19,"author":113,"vertical":114,"topic":115,"tags":118,"_count":125,"playground":126,"hasQuiz":17,"hasPlayground":17},"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",15,"2026-08-03T09:54:26.268Z",1056,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":116,"name":117},"security","Security",[119,120,121,122],{"slug":69,"name":70,"color":50},{"slug":116,"name":117,"color":50},{"slug":63,"name":67,"color":50},{"slug":123,"name":124,"color":50},"tutorial","Tutorial",{"assessments":78},{"slug":106},{"id":128,"slug":129,"title":130,"subtitle":50,"excerpt":131,"coverUrl":132,"locale":13,"readingMinutes":86,"publishedAt":133,"viewCount":134,"likeCount":19,"commentCount":19,"author":135,"vertical":136,"topic":137,"tags":138,"_count":143,"playground":144,"hasQuiz":17,"hasPlayground":17},"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",751,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[139,140,141,142],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":99,"name":100,"color":50},{"slug":72,"name":73,"color":50},{"assessments":78},{"slug":129},{"id":146,"slug":147,"title":148,"subtitle":50,"excerpt":149,"coverUrl":150,"locale":13,"readingMinutes":86,"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-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",678,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":92,"name":93},[157,158,159,160],{"slug":92,"name":96,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":63,"name":67,"color":50},{"assessments":78},{"slug":147},{"id":164,"slug":165,"title":166,"subtitle":50,"excerpt":167,"coverUrl":168,"locale":13,"readingMinutes":86,"publishedAt":169,"viewCount":170,"likeCount":19,"commentCount":19,"author":171,"vertical":172,"topic":173,"tags":174,"_count":181,"playground":182,"hasQuiz":17,"hasPlayground":17},"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",702,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[175,176,177,178],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":179,"name":180,"color":50},"typescript","Typescript",{"assessments":78},{"slug":165},{"id":184,"slug":185,"title":186,"subtitle":50,"excerpt":187,"coverUrl":188,"locale":13,"readingMinutes":86,"publishedAt":189,"viewCount":190,"likeCount":19,"commentCount":19,"author":191,"vertical":192,"topic":193,"tags":194,"_count":199,"playground":200,"hasQuiz":17,"hasPlayground":17},"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",608,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":92,"name":93},[195,196,197,198],{"slug":92,"name":96,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":63,"name":67,"color":50},{"assessments":78},{"slug":185},{"id":202,"slug":203,"title":204,"subtitle":50,"excerpt":205,"coverUrl":206,"locale":13,"readingMinutes":86,"publishedAt":207,"viewCount":208,"likeCount":19,"commentCount":19,"author":209,"vertical":210,"topic":211,"tags":212,"_count":217,"playground":218,"hasQuiz":17,"hasPlayground":17},"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",563,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[213,214,215,216],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":99,"name":100,"color":50},{"assessments":78},{"slug":203},{"id":220,"slug":221,"title":222,"subtitle":50,"excerpt":223,"coverUrl":224,"locale":13,"readingMinutes":53,"publishedAt":225,"viewCount":226,"likeCount":19,"commentCount":19,"author":227,"vertical":228,"topic":229,"tags":230,"_count":235,"playground":236,"hasQuiz":17,"hasPlayground":17},"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",555,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":92,"name":93},[231,232,233,234],{"slug":92,"name":96,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":63,"name":67,"color":50},{"assessments":78},{"slug":221},{"id":238,"slug":239,"title":240,"subtitle":50,"excerpt":241,"coverUrl":242,"locale":13,"readingMinutes":53,"publishedAt":243,"viewCount":244,"likeCount":19,"commentCount":19,"author":245,"vertical":246,"topic":247,"tags":248,"_count":253,"playground":254,"hasQuiz":17,"hasPlayground":17},"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",512,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":92,"name":93},[249,250,251,252],{"slug":92,"name":96,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":63,"name":67,"color":50},{"assessments":78},{"slug":239},{"id":256,"slug":257,"title":258,"subtitle":50,"excerpt":259,"coverUrl":260,"locale":13,"readingMinutes":53,"publishedAt":261,"viewCount":262,"likeCount":19,"commentCount":19,"author":263,"vertical":264,"topic":265,"tags":266,"_count":271,"playground":272,"hasQuiz":17,"hasPlayground":17},"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",662,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":63,"name":64},[267,268,269,270],{"slug":63,"name":67,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":99,"name":100,"color":50},{"assessments":78},{"slug":257},{"id":274,"slug":275,"title":276,"subtitle":50,"excerpt":277,"coverUrl":278,"locale":13,"readingMinutes":53,"publishedAt":279,"viewCount":280,"likeCount":19,"commentCount":19,"author":281,"vertical":282,"topic":283,"tags":284,"_count":289,"playground":290,"hasQuiz":17,"hasPlayground":17},"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",546,{"id":57,"name":58,"username":59,"avatarUrl":50,"headline":60},{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":92,"name":93},[285,286,287,288],{"slug":92,"name":96,"color":50},{"slug":69,"name":70,"color":50},{"slug":72,"name":73,"color":50},{"slug":63,"name":67,"color":50},{"assessments":78},{"slug":275},{"page":292,"perPage":292,"total":293,"totalPages":110},12,174,[295,296,298,300,302,304,306,308,312,316,320,324],{"slug":69,"name":70,"articles":293},{"slug":63,"name":67,"articles":297},141,{"slug":72,"name":73,"articles":299},96,{"slug":123,"name":124,"articles":301},71,{"slug":92,"name":96,"articles":303},51,{"slug":99,"name":100,"articles":305},30,{"slug":179,"name":180,"articles":307},25,{"slug":309,"name":310,"articles":311},"react","React",20,{"slug":313,"name":314,"articles":315},"programming","Programming",19,{"slug":317,"name":318,"articles":319},"browser","Browser",18,{"slug":321,"name":322,"articles":323},"node","Node",16,{"slug":325,"name":326,"articles":292},"html","Html",[328,329,330,331,332,333,334,335,336,337,338,339,340,344,348,351,355,359,362,365,369,372,376,377,380,383,386,389,392,393,396,399,402,405,408,411,414,417,420,423],{"slug":69,"name":70,"color":50,"articles":293},{"slug":63,"name":67,"color":50,"articles":297},{"slug":72,"name":73,"color":50,"articles":299},{"slug":123,"name":124,"color":50,"articles":301},{"slug":92,"name":96,"color":50,"articles":303},{"slug":99,"name":100,"color":50,"articles":305},{"slug":179,"name":180,"color":50,"articles":307},{"slug":309,"name":310,"color":50,"articles":311},{"slug":313,"name":314,"color":50,"articles":315},{"slug":317,"name":318,"color":50,"articles":319},{"slug":321,"name":322,"color":50,"articles":323},{"slug":325,"name":326,"color":50,"articles":292},{"slug":341,"name":342,"color":50,"articles":343},"nextjs","Nextjs",11,{"slug":345,"name":346,"color":50,"articles":347},"vue","Vue",10,{"slug":349,"name":350,"color":50,"articles":347},"accessibility","Accessibility",{"slug":352,"name":353,"color":50,"articles":354},"nestjs","Nestjs",9,{"slug":356,"name":357,"color":50,"articles":358},"nuxt","Nuxt",8,{"slug":360,"name":361,"color":50,"articles":358},"career","Career",{"slug":363,"name":364,"color":50,"articles":358},"discuss","Discuss",{"slug":366,"name":367,"color":50,"articles":368},"beginners","Beginners",7,{"slug":370,"name":371,"color":50,"articles":368},"productivity","Productivity",{"slug":373,"name":374,"color":50,"articles":375},"grammar","Grammar",6,{"slug":116,"name":117,"color":50,"articles":86},{"slug":378,"name":379,"color":50,"articles":53},"ssr","SSR",{"slug":381,"name":382,"color":50,"articles":53},"apis","Apis",{"slug":384,"name":385,"color":50,"articles":43},"ai","Ai",{"slug":387,"name":388,"color":50,"articles":43},"api","API",{"slug":390,"name":391,"color":50,"articles":43},"caching","Caching",{"slug":75,"name":76,"color":50,"articles":31},{"slug":394,"name":395,"color":50,"articles":31},"forms","Forms",{"slug":397,"name":398,"color":50,"articles":31},"dom","Dom",{"slug":400,"name":401,"color":50,"articles":31},"backend","Backend",{"slug":403,"name":404,"color":50,"articles":31},"english","English",{"slug":406,"name":407,"color":50,"articles":31},"verbs","Verbs",{"slug":409,"name":410,"color":50,"articles":31},"spanish","Spanish",{"slug":412,"name":413,"color":50,"articles":31},"a1","A1",{"slug":415,"name":416,"color":50,"articles":31},"a2","A2",{"slug":418,"name":419,"color":50,"articles":31},"tenses","Tenses",{"slug":421,"name":422,"color":50,"articles":31},"turkish","Turkish",{"slug":424,"name":425,"color":50,"articles":31},"animation","Animation"]