[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"dev":3},[4,341],{"id":5,"title":6,"body":7,"category":326,"date":327,"description":328,"extension":329,"meta":330,"navigation":54,"path":331,"readTime":332,"seo":333,"stem":334,"tags":335,"__hash__":340},"dev\u002Fdev\u002Flaravel-caching-from-memory-leaks-to-fast-apis.md","Laravel Caching: From Memory Leaks to fast APIs",{"type":8,"value":9,"toc":319},"minimark",[10,14,19,80,91,95,133,143,147,202,206,240,244,310,315],[11,12,13],"p",{},"Laravel gets called \"slow\" when people skip caching patterns that work. These strategies cut API response times from seconds to milliseconds.",[15,16,18],"h2",{"id":17},"cacheremember-cacheput","Cache::remember() > Cache::put()",[20,21,26],"pre",{"className":22,"code":23,"language":24,"meta":25,"style":25},"language-php shiki shiki-themes github-light github-dark","\u002F\u002F ❌ Wrong: Manual expiration management\nCache::put('user-posts', $posts, now()->addHour());\n$posts = Cache::get('user-posts');\n\n\u002F\u002F ✅ Right: Automatic refresh\n$posts = Cache::remember(\"user.{$user->id}.posts\", now()->addHour(), function () use ($user) {\n    return $user->posts()->with('comments')->get();\n});\n","php","",[27,28,29,37,43,49,56,62,68,74],"code",{"__ignoreMap":25},[30,31,34],"span",{"class":32,"line":33},"line",1,[30,35,36],{},"\u002F\u002F ❌ Wrong: Manual expiration management\n",[30,38,40],{"class":32,"line":39},2,[30,41,42],{},"Cache::put('user-posts', $posts, now()->addHour());\n",[30,44,46],{"class":32,"line":45},3,[30,47,48],{},"$posts = Cache::get('user-posts');\n",[30,50,52],{"class":32,"line":51},4,[30,53,55],{"emptyLinePlaceholder":54},true,"\n",[30,57,59],{"class":32,"line":58},5,[30,60,61],{},"\u002F\u002F ✅ Right: Automatic refresh\n",[30,63,65],{"class":32,"line":64},6,[30,66,67],{},"$posts = Cache::remember(\"user.{$user->id}.posts\", now()->addHour(), function () use ($user) {\n",[30,69,71],{"class":32,"line":70},7,[30,72,73],{},"    return $user->posts()->with('comments')->get();\n",[30,75,77],{"class":32,"line":76},8,[30,78,79],{},"});\n",[11,81,82,86,87,90],{},[83,84,85],"strong",{},"Why",": ",[27,88,89],{},"remember()"," guarantees fresh data on cache miss. No stale data bugs.",[15,92,94],{"id":93},"cache-tags-for-related-data","Cache Tags for Related Data",[20,96,98],{"className":22,"code":97,"language":24,"meta":25,"style":25},"\u002F\u002F Tag entire user data tree\nCache::tags(['user', \"user:{$user->id}\"])->rememberForever(\"user:{$user->id}:profile\", function () use ($user) {\n    return $user->load(['posts', 'posts.comments']);\n});\n\n\u002F\u002F Invalidate everything when user updates\nCache::tags(['user', \"user:{$user->id}\"])->flush();\n",[27,99,100,105,110,115,119,123,128],{"__ignoreMap":25},[30,101,102],{"class":32,"line":33},[30,103,104],{},"\u002F\u002F Tag entire user data tree\n",[30,106,107],{"class":32,"line":39},[30,108,109],{},"Cache::tags(['user', \"user:{$user->id}\"])->rememberForever(\"user:{$user->id}:profile\", function () use ($user) {\n",[30,111,112],{"class":32,"line":45},[30,113,114],{},"    return $user->load(['posts', 'posts.comments']);\n",[30,116,117],{"class":32,"line":51},[30,118,79],{},[30,120,121],{"class":32,"line":58},[30,122,55],{"emptyLinePlaceholder":54},[30,124,125],{"class":32,"line":64},[30,126,127],{},"\u002F\u002F Invalidate everything when user updates\n",[30,129,130],{"class":32,"line":70},[30,131,132],{},"Cache::tags(['user', \"user:{$user->id}\"])->flush();\n",[11,134,135,138,139,142],{},[83,136,137],{},"Result",": One ",[27,140,141],{},"flush()"," clears profile + posts + comments. No hunting cache keys.",[15,144,146],{"id":145},"routemodel-caching-that-survives-production","Route\u002FModel Caching That Survives Production",[20,148,150],{"className":22,"code":149,"language":24,"meta":25,"style":25},"\u002F\u002F Route caching (CLI only)\nRoute::middleware('cache.headers:public;max_age=3600')->get('\u002Fapi\u002Fposts', function () {\n    return Cache::remember('public-posts', 3600, fn() => Post::published()->get();\n});\n\n\u002F\u002F Model query caching\nPost::published()\n    ->remember(3600)\n    ->orderBy('published_at')\n    ->get();\n",[27,151,152,157,162,167,171,175,180,185,190,196],{"__ignoreMap":25},[30,153,154],{"class":32,"line":33},[30,155,156],{},"\u002F\u002F Route caching (CLI only)\n",[30,158,159],{"class":32,"line":39},[30,160,161],{},"Route::middleware('cache.headers:public;max_age=3600')->get('\u002Fapi\u002Fposts', function () {\n",[30,163,164],{"class":32,"line":45},[30,165,166],{},"    return Cache::remember('public-posts', 3600, fn() => Post::published()->get();\n",[30,168,169],{"class":32,"line":51},[30,170,79],{},[30,172,173],{"class":32,"line":58},[30,174,55],{"emptyLinePlaceholder":54},[30,176,177],{"class":32,"line":64},[30,178,179],{},"\u002F\u002F Model query caching\n",[30,181,182],{"class":32,"line":70},[30,183,184],{},"Post::published()\n",[30,186,187],{"class":32,"line":76},[30,188,189],{},"    ->remember(3600)\n",[30,191,193],{"class":32,"line":192},9,[30,194,195],{},"    ->orderBy('published_at')\n",[30,197,199],{"class":32,"line":198},10,[30,200,201],{},"    ->get();\n",[15,203,205],{"id":204},"redis-json-for-complex-objects","Redis JSON for Complex Objects",[20,207,209],{"className":22,"code":208,"language":24,"meta":25,"style":25},"\u002F\u002F Store JSON directly (faster than serialization)\nCache::store('redis')->put('dashboard-stats', json_encode($stats), 1800);\n\n\u002F\u002F Driver-specific: Redis JSON commands\nRedis::connection()->json()->set(\"user:{$user->id}\", '$', $user->toArray());\nRedis::connection()->json()->get(\"user:{$user->id}\");\n",[27,210,211,216,221,225,230,235],{"__ignoreMap":25},[30,212,213],{"class":32,"line":33},[30,214,215],{},"\u002F\u002F Store JSON directly (faster than serialization)\n",[30,217,218],{"class":32,"line":39},[30,219,220],{},"Cache::store('redis')->put('dashboard-stats', json_encode($stats), 1800);\n",[30,222,223],{"class":32,"line":45},[30,224,55],{"emptyLinePlaceholder":54},[30,226,227],{"class":32,"line":51},[30,228,229],{},"\u002F\u002F Driver-specific: Redis JSON commands\n",[30,231,232],{"class":32,"line":58},[30,233,234],{},"Redis::connection()->json()->set(\"user:{$user->id}\", '$', $user->toArray());\n",[30,236,237],{"class":32,"line":64},[30,238,239],{},"Redis::connection()->json()->get(\"user:{$user->id}\");\n",[15,241,243],{"id":242},"the-production-checklist","The Production Checklist",[20,245,247],{"className":22,"code":246,"language":24,"meta":25,"style":25},"\u002F\u002F .env\nCACHE_STORE=redis\nREDIS_CLIENT=phpredis\nSESSION_DRIVER=redis\n\n\u002F\u002F config\u002Fcache.php\n'tags' => [\n    'redis' => [\n        'driver' => 'redis',\n        'connection' => 'cache',\n    ],\n],\n",[27,248,249,254,259,264,269,273,278,283,288,293,298,304],{"__ignoreMap":25},[30,250,251],{"class":32,"line":33},[30,252,253],{},"\u002F\u002F .env\n",[30,255,256],{"class":32,"line":39},[30,257,258],{},"CACHE_STORE=redis\n",[30,260,261],{"class":32,"line":45},[30,262,263],{},"REDIS_CLIENT=phpredis\n",[30,265,266],{"class":32,"line":51},[30,267,268],{},"SESSION_DRIVER=redis\n",[30,270,271],{"class":32,"line":58},[30,272,55],{"emptyLinePlaceholder":54},[30,274,275],{"class":32,"line":64},[30,276,277],{},"\u002F\u002F config\u002Fcache.php\n",[30,279,280],{"class":32,"line":70},[30,281,282],{},"'tags' => [\n",[30,284,285],{"class":32,"line":76},[30,286,287],{},"    'redis' => [\n",[30,289,290],{"class":32,"line":192},[30,291,292],{},"        'driver' => 'redis',\n",[30,294,295],{"class":32,"line":198},[30,296,297],{},"        'connection' => 'cache',\n",[30,299,301],{"class":32,"line":300},11,[30,302,303],{},"    ],\n",[30,305,307],{"class":32,"line":306},12,[30,308,309],{},"],\n",[11,311,312],{},[83,313,314],{},"Cache smart. Ship fast.",[316,317,318],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":25,"searchDepth":39,"depth":39,"links":320},[321,322,323,324,325],{"id":17,"depth":39,"text":18},{"id":93,"depth":39,"text":94},{"id":145,"depth":39,"text":146},{"id":204,"depth":39,"text":205},{"id":242,"depth":39,"text":243},"Dev","2026-04-19","Practical caching patterns that ship faster than your uncached endpoints.","md",{},"\u002Fdev\u002Flaravel-caching-from-memory-leaks-to-fast-apis","10 min",{"title":6,"description":328},"dev\u002Flaravel-caching-from-memory-leaks-to-fast-apis",[336,337,338,339],"Laravel","Caching","Performance","Redis","X5GW_GstX-4dBwpdsLAPvI3zkuuZ0d_7hL7FL8G2Jpg",{"id":342,"title":343,"body":344,"category":973,"date":327,"description":974,"extension":329,"meta":975,"navigation":54,"path":976,"readTime":977,"seo":978,"stem":979,"tags":980,"__hash__":983},"dev\u002Fdev\u002Ftypescript-advanced-patterns.md","TypeScript Patterns That Actually Ship",{"type":8,"value":345,"toc":968},[346,354,358,538,545,549,812,819,823,955,960,965],[11,347,348,349,353],{},"TypeScript gets called verbose when people fight the type system instead of working ",[350,351,352],"em",{},"with"," it. These three patterns flipped that script for me.",[15,355,357],{"id":356},"discriminated-unions-for-api-responses","Discriminated Unions for API Responses",[20,359,363],{"className":360,"code":361,"language":362,"meta":25,"style":25},"language-typescript shiki shiki-themes github-light github-dark","type ApiResponse\u003CT> = \n  | { success: true; data: T }\n  | { success: false; error: string }\n\nconst response: ApiResponse\u003CUser> = await fetchUser()\n\nif (response.success) {\n  \u002F\u002F TypeScript knows response.data is User\n  response.data.email\n} else {\n  \u002F\u002F TypeScript knows response.error exists\n  console.error(response.error)\n}\n","typescript",[27,364,365,391,424,449,453,483,487,495,501,506,517,522,532],{"__ignoreMap":25},[30,366,367,371,375,379,382,385,388],{"class":32,"line":33},[30,368,370],{"class":369},"szBVR","type",[30,372,374],{"class":373},"sScJk"," ApiResponse",[30,376,378],{"class":377},"sVt8B","\u003C",[30,380,381],{"class":373},"T",[30,383,384],{"class":377},"> ",[30,386,387],{"class":369},"=",[30,389,390],{"class":377}," \n",[30,392,393,396,399,403,406,410,413,416,418,421],{"class":32,"line":39},[30,394,395],{"class":369},"  |",[30,397,398],{"class":377}," { ",[30,400,402],{"class":401},"s4XuR","success",[30,404,405],{"class":369},":",[30,407,409],{"class":408},"sj4cs"," true",[30,411,412],{"class":377},"; ",[30,414,415],{"class":401},"data",[30,417,405],{"class":369},[30,419,420],{"class":373}," T",[30,422,423],{"class":377}," }\n",[30,425,426,428,430,432,434,437,439,442,444,447],{"class":32,"line":45},[30,427,395],{"class":369},[30,429,398],{"class":377},[30,431,402],{"class":401},[30,433,405],{"class":369},[30,435,436],{"class":408}," false",[30,438,412],{"class":377},[30,440,441],{"class":401},"error",[30,443,405],{"class":369},[30,445,446],{"class":408}," string",[30,448,423],{"class":377},[30,450,451],{"class":32,"line":51},[30,452,55],{"emptyLinePlaceholder":54},[30,454,455,458,461,463,465,467,470,472,474,477,480],{"class":32,"line":58},[30,456,457],{"class":369},"const",[30,459,460],{"class":408}," response",[30,462,405],{"class":369},[30,464,374],{"class":373},[30,466,378],{"class":377},[30,468,469],{"class":373},"User",[30,471,384],{"class":377},[30,473,387],{"class":369},[30,475,476],{"class":369}," await",[30,478,479],{"class":373}," fetchUser",[30,481,482],{"class":377},"()\n",[30,484,485],{"class":32,"line":64},[30,486,55],{"emptyLinePlaceholder":54},[30,488,489,492],{"class":32,"line":70},[30,490,491],{"class":369},"if",[30,493,494],{"class":377}," (response.success) {\n",[30,496,497],{"class":32,"line":76},[30,498,500],{"class":499},"sJ8bj","  \u002F\u002F TypeScript knows response.data is User\n",[30,502,503],{"class":32,"line":192},[30,504,505],{"class":377},"  response.data.email\n",[30,507,508,511,514],{"class":32,"line":198},[30,509,510],{"class":377},"} ",[30,512,513],{"class":369},"else",[30,515,516],{"class":377}," {\n",[30,518,519],{"class":32,"line":300},[30,520,521],{"class":499},"  \u002F\u002F TypeScript knows response.error exists\n",[30,523,524,527,529],{"class":32,"line":306},[30,525,526],{"class":377},"  console.",[30,528,441],{"class":373},[30,530,531],{"class":377},"(response.error)\n",[30,533,535],{"class":32,"line":534},13,[30,536,537],{"class":377},"}\n",[11,539,540,541,544],{},"No more ",[27,542,543],{},"if (response.error)"," guesswork. The compiler guards every branch.",[15,546,548],{"id":547},"generic-composables-in-vue","Generic Composables in Vue",[20,550,552],{"className":360,"code":551,"language":362,"meta":25,"style":25},"\u002F\u002F composables\u002FuseFetch.ts\nexport const useFetch = \u003CT>() => {\n  const data = ref\u003CT | null>(null)\n  const error = ref\u003Cstring | null>(null)\n  \n  const fetch = async (url: string) => {\n    const res = await fetch(url)\n    if (!res.ok) {\n      error.value = 'Failed'\n      return\n    }\n    data.value = await res.json() as T\n  }\n  \n  return { data, error, fetch }\n}\n\n\u002F\u002F Usage knows the exact return type\nconst { data } = useFetch\u003CUserProfile>()\n",[27,553,554,559,586,618,644,649,678,695,708,719,724,729,753,758,763,772,777,782,788],{"__ignoreMap":25},[30,555,556],{"class":32,"line":33},[30,557,558],{"class":499},"\u002F\u002F composables\u002FuseFetch.ts\n",[30,560,561,564,567,570,573,576,578,581,584],{"class":32,"line":39},[30,562,563],{"class":369},"export",[30,565,566],{"class":369}," const",[30,568,569],{"class":373}," useFetch",[30,571,572],{"class":369}," =",[30,574,575],{"class":377}," \u003C",[30,577,381],{"class":373},[30,579,580],{"class":377},">() ",[30,582,583],{"class":369},"=>",[30,585,516],{"class":377},[30,587,588,591,594,596,599,601,603,606,609,612,615],{"class":32,"line":45},[30,589,590],{"class":369},"  const",[30,592,593],{"class":408}," data",[30,595,572],{"class":369},[30,597,598],{"class":373}," ref",[30,600,378],{"class":377},[30,602,381],{"class":373},[30,604,605],{"class":369}," |",[30,607,608],{"class":408}," null",[30,610,611],{"class":377},">(",[30,613,614],{"class":408},"null",[30,616,617],{"class":377},")\n",[30,619,620,622,625,627,629,631,634,636,638,640,642],{"class":32,"line":51},[30,621,590],{"class":369},[30,623,624],{"class":408}," error",[30,626,572],{"class":369},[30,628,598],{"class":373},[30,630,378],{"class":377},[30,632,633],{"class":408},"string",[30,635,605],{"class":369},[30,637,608],{"class":408},[30,639,611],{"class":377},[30,641,614],{"class":408},[30,643,617],{"class":377},[30,645,646],{"class":32,"line":58},[30,647,648],{"class":377},"  \n",[30,650,651,653,656,658,661,664,667,669,671,674,676],{"class":32,"line":64},[30,652,590],{"class":369},[30,654,655],{"class":373}," fetch",[30,657,572],{"class":369},[30,659,660],{"class":369}," async",[30,662,663],{"class":377}," (",[30,665,666],{"class":401},"url",[30,668,405],{"class":369},[30,670,446],{"class":408},[30,672,673],{"class":377},") ",[30,675,583],{"class":369},[30,677,516],{"class":377},[30,679,680,683,686,688,690,692],{"class":32,"line":70},[30,681,682],{"class":369},"    const",[30,684,685],{"class":408}," res",[30,687,572],{"class":369},[30,689,476],{"class":369},[30,691,655],{"class":373},[30,693,694],{"class":377},"(url)\n",[30,696,697,700,702,705],{"class":32,"line":76},[30,698,699],{"class":369},"    if",[30,701,663],{"class":377},[30,703,704],{"class":369},"!",[30,706,707],{"class":377},"res.ok) {\n",[30,709,710,713,715],{"class":32,"line":192},[30,711,712],{"class":377},"      error.value ",[30,714,387],{"class":369},[30,716,718],{"class":717},"sZZnC"," 'Failed'\n",[30,720,721],{"class":32,"line":198},[30,722,723],{"class":369},"      return\n",[30,725,726],{"class":32,"line":300},[30,727,728],{"class":377},"    }\n",[30,730,731,734,736,738,741,744,747,750],{"class":32,"line":306},[30,732,733],{"class":377},"    data.value ",[30,735,387],{"class":369},[30,737,476],{"class":369},[30,739,740],{"class":377}," res.",[30,742,743],{"class":373},"json",[30,745,746],{"class":377},"() ",[30,748,749],{"class":369},"as",[30,751,752],{"class":373}," T\n",[30,754,755],{"class":32,"line":534},[30,756,757],{"class":377},"  }\n",[30,759,761],{"class":32,"line":760},14,[30,762,648],{"class":377},[30,764,766,769],{"class":32,"line":765},15,[30,767,768],{"class":369},"  return",[30,770,771],{"class":377}," { data, error, fetch }\n",[30,773,775],{"class":32,"line":774},16,[30,776,537],{"class":377},[30,778,780],{"class":32,"line":779},17,[30,781,55],{"emptyLinePlaceholder":54},[30,783,785],{"class":32,"line":784},18,[30,786,787],{"class":499},"\u002F\u002F Usage knows the exact return type\n",[30,789,791,793,795,797,800,802,804,806,809],{"class":32,"line":790},19,[30,792,457],{"class":369},[30,794,398],{"class":377},[30,796,415],{"class":408},[30,798,799],{"class":377}," } ",[30,801,387],{"class":369},[30,803,569],{"class":373},[30,805,378],{"class":377},[30,807,808],{"class":373},"UserProfile",[30,810,811],{"class":377},">()\n",[11,813,814,815,818],{},"20 lines upfront, zero ",[27,816,817],{},"any"," debugging later.",[15,820,822],{"id":821},"zod-at-the-boundary","Zod at the Boundary",[20,824,826],{"className":360,"code":825,"language":362,"meta":25,"style":25},"const userSchema = z.object({\n  id: z.number(),\n  email: z.string().email(),\n  name: z.string()\n})\n\nconst response = await fetch('\u002Fapi\u002Fuser')\nconst user = userSchema.parse(await response.json())\n\n\u002F\u002F Everything past this point is 100% typed\nuser.email \u002F\u002F string, guaranteed\n",[27,827,828,846,857,872,881,886,890,910,938,942,947],{"__ignoreMap":25},[30,829,830,832,835,837,840,843],{"class":32,"line":33},[30,831,457],{"class":369},[30,833,834],{"class":408}," userSchema",[30,836,572],{"class":369},[30,838,839],{"class":377}," z.",[30,841,842],{"class":373},"object",[30,844,845],{"class":377},"({\n",[30,847,848,851,854],{"class":32,"line":39},[30,849,850],{"class":377},"  id: z.",[30,852,853],{"class":373},"number",[30,855,856],{"class":377},"(),\n",[30,858,859,862,864,867,870],{"class":32,"line":45},[30,860,861],{"class":377},"  email: z.",[30,863,633],{"class":373},[30,865,866],{"class":377},"().",[30,868,869],{"class":373},"email",[30,871,856],{"class":377},[30,873,874,877,879],{"class":32,"line":51},[30,875,876],{"class":377},"  name: z.",[30,878,633],{"class":373},[30,880,482],{"class":377},[30,882,883],{"class":32,"line":58},[30,884,885],{"class":377},"})\n",[30,887,888],{"class":32,"line":64},[30,889,55],{"emptyLinePlaceholder":54},[30,891,892,894,896,898,900,902,905,908],{"class":32,"line":70},[30,893,457],{"class":369},[30,895,460],{"class":408},[30,897,572],{"class":369},[30,899,476],{"class":369},[30,901,655],{"class":373},[30,903,904],{"class":377},"(",[30,906,907],{"class":717},"'\u002Fapi\u002Fuser'",[30,909,617],{"class":377},[30,911,912,914,917,919,922,925,927,930,933,935],{"class":32,"line":76},[30,913,457],{"class":369},[30,915,916],{"class":408}," user",[30,918,572],{"class":369},[30,920,921],{"class":377}," userSchema.",[30,923,924],{"class":373},"parse",[30,926,904],{"class":377},[30,928,929],{"class":369},"await",[30,931,932],{"class":377}," response.",[30,934,743],{"class":373},[30,936,937],{"class":377},"())\n",[30,939,940],{"class":32,"line":192},[30,941,55],{"emptyLinePlaceholder":54},[30,943,944],{"class":32,"line":198},[30,945,946],{"class":499},"\u002F\u002F Everything past this point is 100% typed\n",[30,948,949,952],{"class":32,"line":300},[30,950,951],{"class":377},"user.email ",[30,953,954],{"class":499},"\u002F\u002F string, guaranteed\n",[11,956,957,959],{},[83,958,137],{},": Last Laravel + Vue project refactor eliminated 80% of runtime type errors. The compiler became my QA team.",[11,961,962],{},[83,963,964],{},"Ship faster. Type smarter.",[316,966,967],{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":25,"searchDepth":39,"depth":39,"links":969},[970,971,972],{"id":356,"depth":39,"text":357},{"id":547,"depth":39,"text":548},{"id":821,"depth":39,"text":822},"TypeScript","Three techniques that cut Vue + Laravel API bugs by 80%—no verbosity, just results.",{},"\u002Fdev\u002Ftypescript-advanced-patterns","10 min read",{"title":343,"description":974},"dev\u002Ftypescript-advanced-patterns",[973,981,336,982],"Vue","API","WQ5r26dYx0WOWNZq1U-ZFhbuE74Mfz7o_qGgpE44oKM"]