[{"data":1,"prerenderedAt":6984},["ShallowReactive",2],{"profile-data":3,"blog-post-\u002Fblog\u002F45-nuxt-swr-set-cookie-leak":58,"related-posts-\u002Fblog\u002F45-nuxt-swr-set-cookie-leak":755},{"id":4,"title":5,"avatar":6,"description":7,"experience":8,"extension":18,"heroHeadline":19,"meta":20,"name":21,"social":22,"stem":35,"whatIDo":36,"__hash__":57},"profile\u002Fprofile.yml","Senior Software Engineer","\u002Fmubaidr.png","13+ years shipping web applications, SaaS platforms, AI-powered tools, browser extensions, and cloud-native systems across startups and enterprise. Currently building Rental Platform. Open-source habit.",[9,12,15],{"label":10,"value":11},"Years","13+",{"label":13,"value":14},"Projects Shipped","50+",{"label":16,"value":17},"Domains","SaaS, AI, FinTech, E-commerce","yml","Building production systems that scale; from SaaS platforms to AI-powered tools.",{},"Muhammad Ubaid R.",[23,27,31],{"name":24,"url":25,"icon":26},"GitHub","https:\u002F\u002Fgithub.com\u002Fmubaidr","i-ph-github-logo",{"name":28,"url":29,"icon":30},"LinkedIn","https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fmubaidr","i-ph-linkedin-logo",{"name":32,"url":33,"icon":34},"X","https:\u002F\u002Fx.com\u002Fmubaidr","i-ph-x-logo","profile",[37,41,45,49,53],{"field":38,"icon":39,"description":40},"Full Stack Development","i-ph-stack","End-to-end across frontend and backend. Vue, Nuxt, React, Node, Python.",{"field":42,"icon":43,"description":44},"AI-Powered Tools & Extensions","i-ph-puzzle-piece","Intelligent tools and browser extensions. LLM integrations, RAG pipelines, AI UX.",{"field":46,"icon":47,"description":48},"Architecture & DevOps","i-ph-gear-six","Scalable system design. CI\u002FCD, observability, containerized deployments.",{"field":50,"icon":51,"description":52},"Team Leadership","i-ph-users-three","Agile delivery. Cross-functional coordination. Technical mentoring.",{"field":54,"icon":55,"description":56},"Open Source","i-ph-git-branch","Active contributor and maintainer. Community-driven tooling.","eUG4oiV4oT_76VBKt0TeTxj8S2Ggzv_gWu_gx0lo9-E",{"id":59,"title":60,"abstract":61,"author":62,"authorUrl":63,"body":64,"date":732,"dateUpdated":732,"description":733,"excerpt":734,"extension":735,"featured":438,"headline":60,"image":734,"meta":736,"navigation":438,"ogImage":734,"path":738,"seo":739,"series":734,"seriesDescription":734,"seriesOrder":734,"socialImage":740,"stem":746,"tags":747,"__hash__":754},"blog\u002Fblog\u002F45-nuxt-swr-set-cookie-leak.md","How I Finally Enabled SWR on My Nuxt + Laravel App","Diagnosing and fixing a Set-Cookie header leak in Nuxt SSR that prevented safe use of SWR caching with a Laravel backend. Covers the root cause, the two-line fix, and the verification steps that made enabling SWR safe.","mubaidr","https:\u002F\u002Fmubaidr.js.org",{"type":65,"value":66,"toc":721},"minimark",[67,71,75,106,113,117,127,138,279,286,290,293,298,316,537,540,544,561,565,568,622,626,629,699,703,709,712,717],[68,69,60],"h2",{"id":70},"how-i-finally-enabled-swr-on-my-nuxt-laravel-app",[72,73,74],"p",{},"I've been running a Nuxt 4 frontend with a Laravel 12 backend for a rental marketplace. For over a year, SWR caching on public pages sat commented out in my config:",[76,77,82],"pre",{"className":78,"code":79,"language":80,"meta":81,"style":81},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Important: SWR breaks authenticaiton, somehow.\n\u002F\u002F Because cached requests and old cookie behviour.\n\u002F\u002F Must not enable until we have some solid fix ready\n","ts","",[83,84,85,94,100],"code",{"__ignoreMap":81},[86,87,90],"span",{"class":88,"line":89},"line",1,[86,91,93],{"class":92},"sHwdD","\u002F\u002F Important: SWR breaks authenticaiton, somehow.\n",[86,95,97],{"class":88,"line":96},2,[86,98,99],{"class":92},"\u002F\u002F Because cached requests and old cookie behviour.\n",[86,101,103],{"class":88,"line":102},3,[86,104,105],{"class":92},"\u002F\u002F Must not enable until we have some solid fix ready\n",[72,107,108,109,112],{},"I finally traced it. The issue was real — my SSR API client was blindly forwarding every ",[83,110,111],{},"Set-Cookie"," header from the Laravel backend to the browser. On SWR routes, those cookies got baked into the cached HTML and leaked to the next visitor.",[68,114,116],{"id":115},"the-problem","The Problem",[72,118,119,120,123,124,126],{},"My ",[83,121,122],{},"useApi.ts"," does something pretty standard for Nuxt + external API setups: during SSR, it forwards all cookies from the incoming request to the backend, then relays all ",[83,125,111],{}," headers back to the client response. This is how session cookies get relayed when the browser talks to the Nuxt origin, not Laravel directly.",[72,128,129,130,132,133,137],{},"The problem: on an SWR-cached page, Nitro regenerates the cache by running SSR. If that SSR makes any API call that returns a ",[83,131,111],{}," header, that cookie gets relayed into the response — and then ",[134,135,136],"strong",{},"cached and served to every subsequent visitor",".",[76,139,141],{"className":78,"code":140,"language":80,"meta":81,"style":81},"\u002F\u002F The old code — forwards Set-Cookie on EVERY SSR response\nif (import.meta.server && event) {\n  const setCookies = response.headers.getSetCookie()\n  for (const c of setCookies) {\n    appendResponseHeader(event, \"set-cookie\", c)\n  }\n}\n",[83,142,143,148,181,211,235,267,273],{"__ignoreMap":81},[86,144,145],{"class":88,"line":89},[86,146,147],{"class":92},"\u002F\u002F The old code — forwards Set-Cookie on EVERY SSR response\n",[86,149,150,154,158,161,164,167,169,172,175,178],{"class":88,"line":96},[86,151,153],{"class":152},"s7zQu","if",[86,155,157],{"class":156},"sTEyZ"," (",[86,159,160],{"class":152},"import",[86,162,137],{"class":163},"sMK4o",[86,165,166],{"class":156},"meta",[86,168,137],{"class":163},[86,170,171],{"class":156},"server ",[86,173,174],{"class":163},"&&",[86,176,177],{"class":156}," event) ",[86,179,180],{"class":163},"{\n",[86,182,183,187,190,193,196,198,201,203,207],{"class":88,"line":102},[86,184,186],{"class":185},"spNyl","  const",[86,188,189],{"class":156}," setCookies",[86,191,192],{"class":163}," =",[86,194,195],{"class":156}," response",[86,197,137],{"class":163},[86,199,200],{"class":156},"headers",[86,202,137],{"class":163},[86,204,206],{"class":205},"s2Zo4","getSetCookie",[86,208,210],{"class":209},"swJcz","()\n",[86,212,214,217,219,222,225,228,230,233],{"class":88,"line":213},4,[86,215,216],{"class":152},"  for",[86,218,157],{"class":209},[86,220,221],{"class":185},"const",[86,223,224],{"class":156}," c",[86,226,227],{"class":163}," of",[86,229,189],{"class":156},[86,231,232],{"class":209},") ",[86,234,180],{"class":163},[86,236,238,241,244,247,250,253,257,260,262,264],{"class":88,"line":237},5,[86,239,240],{"class":205},"    appendResponseHeader",[86,242,243],{"class":209},"(",[86,245,246],{"class":156},"event",[86,248,249],{"class":163},",",[86,251,252],{"class":163}," \"",[86,254,256],{"class":255},"sfazB","set-cookie",[86,258,259],{"class":163},"\"",[86,261,249],{"class":163},[86,263,224],{"class":156},[86,265,266],{"class":209},")\n",[86,268,270],{"class":88,"line":269},6,[86,271,272],{"class":163},"  }\n",[86,274,276],{"class":88,"line":275},7,[86,277,278],{"class":163},"}\n",[72,280,281,282,285],{},"Even on public pages where no auth calls happen during SSR, the blanket relay means ",[134,283,284],{},"any"," future endpoint that returns a cookie — session rotation, CSRF tokens, rate limiting — would silently leak into the SWR cache. It was a ticking time bomb.",[68,287,289],{"id":288},"the-fix","The Fix",[72,291,292],{},"Two changes. That's it.",[294,295,297],"h3",{"id":296},"_1-skip-set-cookie-forwarding-on-cached-routes","1. Skip Set-Cookie forwarding on cached routes",[72,299,300,301,303,304,307,308,311,312,315],{},"In ",[83,302,122],{},", check Nitro's ",[83,305,306],{},"event.context.routeRules"," before forwarding. If the route has ",[83,309,310],{},"swr"," or ",[83,313,314],{},"isr",", don't relay the cookies:",[76,317,319],{"className":78,"code":318,"language":80,"meta":81,"style":81},"if (import.meta.server && event) {\n  const rules = event.context.routeRules as Record\u003Cstring, unknown> | undefined\n  const isCachedRoute = rules && (\"swr\" in rules || \"isr\" in rules)\n\n  if (!isCachedRoute) {\n    const setCookies = response.headers.getSetCookie()\n    for (const c of setCookies) {\n      appendResponseHeader(event, \"set-cookie\", c)\n    }\n  }\n}\n",[83,320,321,343,392,434,440,457,478,497,521,527,532],{"__ignoreMap":81},[86,322,323,325,327,329,331,333,335,337,339,341],{"class":88,"line":89},[86,324,153],{"class":152},[86,326,157],{"class":156},[86,328,160],{"class":152},[86,330,137],{"class":163},[86,332,166],{"class":156},[86,334,137],{"class":163},[86,336,171],{"class":156},[86,338,174],{"class":163},[86,340,177],{"class":156},[86,342,180],{"class":163},[86,344,345,347,350,352,355,357,360,362,365,368,372,375,378,380,383,386,389],{"class":88,"line":96},[86,346,186],{"class":185},[86,348,349],{"class":156}," rules",[86,351,192],{"class":163},[86,353,354],{"class":156}," event",[86,356,137],{"class":163},[86,358,359],{"class":156},"context",[86,361,137],{"class":163},[86,363,364],{"class":156},"routeRules",[86,366,367],{"class":152}," as",[86,369,371],{"class":370},"sBMFI"," Record",[86,373,374],{"class":163},"\u003C",[86,376,377],{"class":370},"string",[86,379,249],{"class":163},[86,381,382],{"class":370}," unknown",[86,384,385],{"class":163},">",[86,387,388],{"class":163}," |",[86,390,391],{"class":370}," undefined\n",[86,393,394,396,399,401,403,406,408,410,412,414,417,419,422,424,426,428,430,432],{"class":88,"line":102},[86,395,186],{"class":185},[86,397,398],{"class":156}," isCachedRoute",[86,400,192],{"class":163},[86,402,349],{"class":156},[86,404,405],{"class":163}," &&",[86,407,157],{"class":209},[86,409,259],{"class":163},[86,411,310],{"class":255},[86,413,259],{"class":163},[86,415,416],{"class":163}," in",[86,418,349],{"class":156},[86,420,421],{"class":163}," ||",[86,423,252],{"class":163},[86,425,314],{"class":255},[86,427,259],{"class":163},[86,429,416],{"class":163},[86,431,349],{"class":156},[86,433,266],{"class":209},[86,435,436],{"class":88,"line":213},[86,437,439],{"emptyLinePlaceholder":438},true,"\n",[86,441,442,445,447,450,453,455],{"class":88,"line":237},[86,443,444],{"class":152},"  if",[86,446,157],{"class":209},[86,448,449],{"class":163},"!",[86,451,452],{"class":156},"isCachedRoute",[86,454,232],{"class":209},[86,456,180],{"class":163},[86,458,459,462,464,466,468,470,472,474,476],{"class":88,"line":269},[86,460,461],{"class":185},"    const",[86,463,189],{"class":156},[86,465,192],{"class":163},[86,467,195],{"class":156},[86,469,137],{"class":163},[86,471,200],{"class":156},[86,473,137],{"class":163},[86,475,206],{"class":205},[86,477,210],{"class":209},[86,479,480,483,485,487,489,491,493,495],{"class":88,"line":275},[86,481,482],{"class":152},"    for",[86,484,157],{"class":209},[86,486,221],{"class":185},[86,488,224],{"class":156},[86,490,227],{"class":163},[86,492,189],{"class":156},[86,494,232],{"class":209},[86,496,180],{"class":163},[86,498,500,503,505,507,509,511,513,515,517,519],{"class":88,"line":499},8,[86,501,502],{"class":205},"      appendResponseHeader",[86,504,243],{"class":209},[86,506,246],{"class":156},[86,508,249],{"class":163},[86,510,252],{"class":163},[86,512,256],{"class":255},[86,514,259],{"class":163},[86,516,249],{"class":163},[86,518,224],{"class":156},[86,520,266],{"class":209},[86,522,524],{"class":88,"line":523},9,[86,525,526],{"class":163},"    }\n",[86,528,530],{"class":88,"line":529},10,[86,531,272],{"class":163},[86,533,535],{"class":88,"line":534},11,[86,536,278],{"class":163},[72,538,539],{},"Non-cached routes (authenticated pages, account, admin) still get the full cookie relay. SWR routes get a clean, cookie-free response.",[294,541,543],{"id":542},"_2-uncomment-the-swr-routes","2. Uncomment the SWR routes",[76,545,549],{"className":546,"code":547,"language":548,"meta":81,"style":81},"language-diff shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","- \u002F\u002F ...swrRouteRules,\n+ ...swrRouteRules,\n","diff",[83,550,551,556],{"__ignoreMap":81},[86,552,553],{"class":88,"line":89},[86,554,555],{},"- \u002F\u002F ...swrRouteRules,\n",[86,557,558],{"class":88,"line":96},[86,559,560],{},"+ ...swrRouteRules,\n",[68,562,564],{"id":563},"why-it-was-safe-to-enable","Why It Was Safe to Enable",[72,566,567],{},"Before flipping the switch, I verified three things:",[569,570,571,590,602],"ol",{},[572,573,574,581,582,585,586,589],"li",{},[134,575,576,577,580],{},"Middleware short-circuits on ",[83,578,579],{},"auth: false"," routes."," My auth middleware calls ",[83,583,584],{},"validateServerSideAuth()",", but when ",[83,587,588],{},"definePageMeta({ auth: false })"," is set, it returns immediately — no cookie reads, no API calls on the server side.",[572,591,592,598,599,601],{},[134,593,594,595,137],{},"The header is ",[83,596,597],{},"\u003CClientOnly>"," Auth-dependent UI (login buttons, user avatar) is wrapped in ",[83,600,597],{}," with a skeleton fallback. No user data ends up in the cached HTML.",[572,603,604,607,608,611,612,611,615,618,619,621],{},[134,605,606],{},"Public endpoints don't set cookies."," I verified: ",[83,609,610],{},"\u002Fv1\u002Fpublic\u002Fsettings",", ",[83,613,614],{},"\u002Fv1\u002Fpublic\u002Fproperties\u002F{id}",[83,616,617],{},"\u002Famenities\u002Favailable"," — zero ",[83,620,111],{}," headers. The guard is belt and suspenders.",[68,623,625],{"id":624},"references","References",[72,627,628],{},"The Nuxt team has been clear about this across several issues:",[630,631,632,649,659,677,689],"ul",{},[572,633,634,644,645],{},[134,635,636,643],{},[637,638,642],"a",{"href":639,"rel":640},"https:\u002F\u002Fgithub.com\u002Fnuxt\u002Fnuxt\u002Fissues\u002F31733",[641],"nofollow","Daniel Roe on Set-Cookie in cached routes",":"," ",[646,647,648],"em",{},"\"Cookies\u002Fheaders are not supported when caching routes (as the response needs to be cacheable).\"",[572,650,651,658],{},[134,652,653,643],{},[637,654,657],{"href":655,"rel":656},"https:\u002F\u002Fgithub.com\u002Fnuxt\u002Fnuxt\u002Fissues\u002F28527",[641],"SWR cache saving Set-Cookie was a bug"," Fixed upstream in Nitro v3\u002Focache — Nuxt 5 no longer stores or replays Set-Cookie for SWR routes. But if you're on Nuxt 4, you need to handle it yourself.",[572,660,661,668,669,672,673,676],{},[134,662,663,643],{},[637,664,667],{"href":665,"rel":666},"https:\u002F\u002Fgithub.com\u002Fatinux\u002Fnuxt-auth-utils\u002Fissues\u002F311",[641],"nuxt-auth-utils #311"," Same scenario — SWR route shows ",[83,670,671],{},"loggedIn=false",". Their fix: client-side session fetch via ",[83,674,675],{},"app:mounted"," hook.",[572,678,679,644,686],{},[134,680,681,643],{},[637,682,685],{"href":683,"rel":684},"https:\u002F\u002Fgithub.com\u002Fnuxt\u002Fnuxt\u002Fdiscussions\u002F20014",[641],"Nuxt Discussion #20014",[646,687,688],{},"\"Those cached pages are meant to be stateless as they will be sent to anyone who visits that page.\"",[572,690,691,698],{},[134,692,693,643],{},[637,694,697],{"href":695,"rel":696},"https:\u002F\u002Fgithub.com\u002Fnuxt\u002Fnuxt\u002Fissues\u002F13096",[641],"Nuxt #13096"," The foundational design decision — Set-Cookie forwarding from SSR API calls is opt-in, not default, for exactly this reason.",[68,700,702],{"id":701},"what-id-tell-myself-a-year-ago","What I'd Tell Myself a Year Ago",[72,704,705,706,708],{},"The \"somehow\" in the comment was the problem. The fix is a two-line guard. If you're staring at a commented-out SWR config with a vague \"it breaks auth\" note — check your ",[83,707,111],{}," relay. That's probably it.",[710,711],"hr",{},[72,713,714],{},[646,715,716],{},"Built with Nuxt 4.5+, Laravel 12, and a year of unnecessary fear.",[718,719,720],"style",{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"title":81,"searchDepth":96,"depth":96,"links":722},[723,724,725,729,730,731],{"id":70,"depth":96,"text":60},{"id":115,"depth":96,"text":116},{"id":288,"depth":96,"text":289,"children":726},[727,728],{"id":296,"depth":102,"text":297},{"id":542,"depth":102,"text":543},{"id":563,"depth":96,"text":564},{"id":624,"depth":96,"text":625},{"id":701,"depth":96,"text":702},"2026-09-12","Tracing a Set-Cookie leak in Nuxt SSR that broke SWR caching — the fix was a two-line guard, not a framework change.",null,"md",{"readingTime":737},"5 min read","\u002Fblog\u002F45-nuxt-swr-set-cookie-leak",{"title":60,"description":733},{"src":741,"mime":742,"alt":743,"width":744,"height":745},"\u002Fimg\u002Fblog\u002F45-nuxt-swr-set-cookie-leak\u002Fbanner.svg","svg","SWR cache Set-Cookie leak diagram showing Nuxt SSR forwarding Laravel cookies into cached responses",1200,630,"blog\u002F45-nuxt-swr-set-cookie-leak",[748,749,750,751,752,111,753],"Nuxt","Laravel","SWR","Caching","SSR","Performance","bYKItdSRCNszH9g9moQZ1_IqS01jGMOFPZWHdP0x0ww",[756,1286,4147],{"id":757,"title":758,"abstract":734,"author":62,"authorUrl":734,"body":759,"date":1257,"dateUpdated":1258,"description":1259,"excerpt":734,"extension":735,"featured":438,"headline":734,"image":734,"meta":1260,"navigation":438,"ogImage":734,"path":1273,"seo":1274,"series":1275,"seriesDescription":1276,"seriesOrder":213,"socialImage":1277,"stem":1280,"tags":1281,"__hash__":1285},"blog\u002Fblog\u002F16-nuxt-4-ssr-performance-optimization.md","Nuxt 4 SSR Performance Optimization: Complete Guide to Core Web Vitals",{"type":65,"value":760,"toc":1239},[761,765,771,776,790,793,796,800,803,818,822,826,829,993,997,1014,1018,1021,1025,1028,1031,1035,1039,1045,1049,1052,1072,1075,1079,1086,1106,1112,1116,1119,1154,1157,1161,1164,1196,1199,1201,1205,1208,1211,1216,1236],[68,762,764],{"id":763},"nuxt-4-ssr-performance-optimization","Nuxt 4 SSR Performance Optimization",[72,766,767,770],{},[134,768,769],{},"Last updated:"," February 2026",[72,772,773],{},[134,774,775],{},"What changed in this update:",[630,777,778,781,784,787],{},[572,779,780],{},"Enhanced with Core Web Vitals optimization strategies",[572,782,783],{},"Added detailed caching configuration examples",[572,785,786],{},"Expanded monitoring and measurement section",[572,788,789],{},"Updated for Nuxt 4.0+ latest features",[72,791,792],{},"Server-side rendering (SSR) is one of Nuxt's most powerful features, delivering fast initial page loads and excellent SEO out of the box. However, as applications grow, optimizing SSR performance becomes crucial for maintaining sub-second response times and ensuring a smooth user experience.",[72,794,795],{},"After deploying multiple Nuxt 4 applications to production, I've identified key strategies that consistently deliver measurable performance improvements.",[68,797,799],{"id":798},"understanding-nuxt-4-ssr-architecture","Understanding Nuxt 4 SSR Architecture",[72,801,802],{},"Nuxt 4 introduces several architectural improvements that impact SSR performance. The framework now uses Nitro as its server engine, which provides better caching mechanisms, more efficient rendering pipelines, and improved hydration strategies. The key to optimization lies in understanding how data flows through the SSR process: server receives request → fetches data → renders HTML → sends to client → client hydrates Vue application. Each stage presents optimization opportunities.",[72,804,805,806,809,810,813,814,817],{},"The most common performance bottleneck I've encountered is data fetching. In Nuxt 4, ",[83,807,808],{},"useAsyncData"," and ",[83,811,812],{},"useFetch"," are optimized for SSR, but improper usage can lead to unnecessary server round trips. The golden rule is to fetch data as close to where it's needed as possible and leverage Nuxt's built-in caching. For example, fetching global site configuration in ",[83,815,816],{},"app.vue"," with a long cache time prevents repeated database queries on every page request.",[68,819,821],{"id":820},"essential-optimization-strategies","Essential Optimization Strategies",[294,823,825],{"id":824},"implement-smart-caching","Implement Smart Caching",[72,827,828],{},"Caching is the most impactful optimization technique. Nuxt 4 provides multiple caching layers that work together to reduce server load. Route-level caching stores rendered HTML for static or semi-static content, while data caching memoizes API responses. For a blog site like this one, caching individual blog posts for 24 hours and the homepage for 5 minutes reduces server load by over 80%.",[76,830,834],{"className":831,"code":832,"language":833,"meta":81,"style":81},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F In nuxt.config.ts\nexport default defineNuxtConfig({\n  routeRules: {\n    \"\u002Fblog\u002F**\": { isr: 86400 }, \u002F\u002F 24 hours\n    \"\u002F\": { isr: 300 }, \u002F\u002F 5 minutes\n    \"\u002Fapi\u002F**\": {\n      cors: true,\n      headers: { \"Cache-Control\": \"public, max-age=3600\" },\n    },\n  },\n})\n","typescript",[83,835,836,841,856,866,896,921,934,948,976,981,986],{"__ignoreMap":81},[86,837,838],{"class":88,"line":89},[86,839,840],{"class":92},"\u002F\u002F In nuxt.config.ts\n",[86,842,843,846,849,852,854],{"class":88,"line":96},[86,844,845],{"class":152},"export",[86,847,848],{"class":152}," default",[86,850,851],{"class":205}," defineNuxtConfig",[86,853,243],{"class":156},[86,855,180],{"class":163},[86,857,858,861,863],{"class":88,"line":102},[86,859,860],{"class":209},"  routeRules",[86,862,643],{"class":163},[86,864,865],{"class":163}," {\n",[86,867,868,871,874,876,878,881,884,886,890,893],{"class":88,"line":213},[86,869,870],{"class":163},"    \"",[86,872,873],{"class":209},"\u002Fblog\u002F**",[86,875,259],{"class":163},[86,877,643],{"class":163},[86,879,880],{"class":163}," {",[86,882,883],{"class":209}," isr",[86,885,643],{"class":163},[86,887,889],{"class":888},"sbssI"," 86400",[86,891,892],{"class":163}," },",[86,894,895],{"class":92}," \u002F\u002F 24 hours\n",[86,897,898,900,903,905,907,909,911,913,916,918],{"class":88,"line":237},[86,899,870],{"class":163},[86,901,902],{"class":209},"\u002F",[86,904,259],{"class":163},[86,906,643],{"class":163},[86,908,880],{"class":163},[86,910,883],{"class":209},[86,912,643],{"class":163},[86,914,915],{"class":888}," 300",[86,917,892],{"class":163},[86,919,920],{"class":92}," \u002F\u002F 5 minutes\n",[86,922,923,925,928,930,932],{"class":88,"line":269},[86,924,870],{"class":163},[86,926,927],{"class":209},"\u002Fapi\u002F**",[86,929,259],{"class":163},[86,931,643],{"class":163},[86,933,865],{"class":163},[86,935,936,939,941,945],{"class":88,"line":275},[86,937,938],{"class":209},"      cors",[86,940,643],{"class":163},[86,942,944],{"class":943},"sfNiH"," true",[86,946,947],{"class":163},",\n",[86,949,950,953,955,957,959,962,964,966,968,971,973],{"class":88,"line":499},[86,951,952],{"class":209},"      headers",[86,954,643],{"class":163},[86,956,880],{"class":163},[86,958,252],{"class":163},[86,960,961],{"class":209},"Cache-Control",[86,963,259],{"class":163},[86,965,643],{"class":163},[86,967,252],{"class":163},[86,969,970],{"class":255},"public, max-age=3600",[86,972,259],{"class":163},[86,974,975],{"class":163}," },\n",[86,977,978],{"class":88,"line":523},[86,979,980],{"class":163},"    },\n",[86,982,983],{"class":88,"line":529},[86,984,985],{"class":163},"  },\n",[86,987,988,991],{"class":88,"line":534},[86,989,990],{"class":163},"}",[86,992,266],{"class":156},[294,994,996],{"id":995},"optimize-data-fetching-patterns","Optimize Data Fetching Patterns",[72,998,999,1000,1002,1003,1006,1007,809,1010,1013],{},"Proper data fetching patterns significantly impact SSR performance. Always use ",[83,1001,808],{}," with a unique key to enable request deduplication. When fetching multiple independent data sources, use ",[83,1004,1005],{},"Promise.all"," to parallelize requests instead of awaiting them sequentially. Additionally, leverage ",[83,1008,1009],{},"pick",[83,1011,1012],{},"transform"," options to minimize payload size—sending only the data you need reduces both network transfer and processing time.",[294,1015,1017],{"id":1016},"leverage-static-generation-where-possible","Leverage Static Generation Where Possible",[72,1019,1020],{},"Not every page needs full SSR. Nuxt 4's hybrid rendering allows you to choose the optimal rendering strategy per route. Marketing pages, documentation, and blog posts work perfectly with static generation or incremental static regeneration (ISR). Reserve full SSR for pages with highly dynamic content like user dashboards or real-time data displays. This approach dramatically reduces server load while maintaining the benefits of server rendering for SEO.",[68,1022,1024],{"id":1023},"measuring-and-monitoring-performance","Measuring and Monitoring Performance",[72,1026,1027],{},"Optimization without measurement is guesswork. Implement comprehensive monitoring to track SSR performance metrics. Key metrics to watch include Time to First Byte (TTFB), First Contentful Paint (FCP), and server response times. Nuxt 4 integrates seamlessly with monitoring tools like Sentry and DataDog, providing real-time insights into performance bottlenecks.",[72,1029,1030],{},"Set up performance budgets in your CI\u002FCD pipeline to catch regressions early. For example, fail the build if TTFB increases by more than 100ms compared to the previous deployment. This proactive approach prevents performance degradation from accumulating over time.",[68,1032,1034],{"id":1033},"faq-nuxt-4-ssr-performance","FAQ: Nuxt 4 SSR Performance",[294,1036,1038],{"id":1037},"what-is-the-most-impactful-ssr-optimization-for-nuxt-4","What is the most impactful SSR optimization for Nuxt 4?",[72,1040,1041,1044],{},[134,1042,1043],{},"Caching is the highest-impact optimization."," Implementing route-level caching with ISR (Incremental Static Regeneration) can reduce server load by 80% or more. For a blog or content site, cache pages for 5-60 minutes and API responses for 1-24 hours depending on how frequently data changes.",[294,1046,1048],{"id":1047},"how-do-i-improve-core-web-vitals-with-nuxt-4","How do I improve Core Web Vitals with Nuxt 4?",[72,1050,1051],{},"Focus on these key areas:",[630,1053,1054,1060,1066],{},[572,1055,1056,1059],{},[134,1057,1058],{},"LCP (Largest Contentful Paint)",": Use ISR, optimize images, implement smart caching",[572,1061,1062,1065],{},[134,1063,1064],{},"FID (First Input Delay)",": Code splitting, reduce JavaScript bundle size",[572,1067,1068,1071],{},[134,1069,1070],{},"CLS (Cumulative Layout Shift)",": Reserve space for images and dynamic content, use skeleton loaders",[72,1073,1074],{},"Nuxt 4's hybrid rendering and Nitro caching make achieving good Core Web Vitals significantly easier than previous versions.",[294,1076,1078],{"id":1077},"should-i-use-ssr-or-static-generation-for-my-nuxt-app","Should I use SSR or static generation for my Nuxt app?",[72,1080,1081,1082,1085],{},"Use ",[134,1083,1084],{},"hybrid rendering"," based on page requirements:",[630,1087,1088,1094,1100],{},[572,1089,1090,1093],{},[134,1091,1092],{},"Static generation (prerender)",": Blog posts, documentation, marketing pages",[572,1095,1096,1099],{},[134,1097,1098],{},"ISR (Incremental Static Regeneration)",": Homepage, category pages, product listings",[572,1101,1102,1105],{},[134,1103,1104],{},"Full SSR",": User dashboards, real-time data, personalized content",[72,1107,1108,1109,1111],{},"Nuxt 4's ",[83,1110,364],{}," make it easy to mix strategies in a single application.",[294,1113,1115],{"id":1114},"why-is-my-nuxt-app-slow-despite-using-ssr","Why is my Nuxt app slow despite using SSR?",[72,1117,1118],{},"Common causes:",[569,1120,1121,1127,1136,1142,1148],{},[572,1122,1123,1126],{},[134,1124,1125],{},"No caching",": Every request hits the server",[572,1128,1129,1132,1133,1135],{},[134,1130,1131],{},"Sequential data fetching",": Not using ",[83,1134,1005],{}," for parallel requests",[572,1137,1138,1141],{},[134,1139,1140],{},"Over-fetching",": Loading more data than needed",[572,1143,1144,1147],{},[134,1145,1146],{},"Large bundles",": Not code splitting effectively",[572,1149,1150,1153],{},[134,1151,1152],{},"Database bottlenecks",": Missing database query optimization",[72,1155,1156],{},"Start by implementing caching—it typically provides 50-80% performance improvement.",[294,1158,1160],{"id":1159},"how-do-i-monitor-ssr-performance-in-production","How do I monitor SSR performance in production?",[72,1162,1163],{},"Use these tools and metrics:",[630,1165,1166,1172,1178,1184,1190],{},[572,1167,1168,1171],{},[134,1169,1170],{},"Nuxt DevTools",": Local development performance",[572,1173,1174,1177],{},[134,1175,1176],{},"Sentry",": Error tracking and performance monitoring",[572,1179,1180,1183],{},[134,1181,1182],{},"Google Analytics 4",": Real user monitoring (RUM)",[572,1185,1186,1189],{},[134,1187,1188],{},"Lighthouse CI",": Automated performance budgets in CI\u002FCD",[572,1191,1192,1195],{},[134,1193,1194],{},"Nitro server logs",": TTFB and server response times",[72,1197,1198],{},"Key metrics to track: TTFB \u003C200ms, LCP \u003C2.5s, FID \u003C100ms, CLS \u003C0.1.",[710,1200],{},[68,1202,1204],{"id":1203},"conclusion","Conclusion",[72,1206,1207],{},"Optimizing Nuxt 4 SSR performance is an iterative process that requires understanding the framework's architecture, implementing smart caching strategies, and continuously monitoring results. The strategies outlined here—smart caching, optimized data fetching, hybrid rendering, and comprehensive monitoring—have consistently delivered 50-80% performance improvements in production applications.",[72,1209,1210],{},"Start with the highest-impact optimizations (caching and static generation), measure the results, and iterate based on real-world performance data. Your users—and search engines—will thank you.",[72,1212,1213],{},[134,1214,1215],{},"Related Reading:",[630,1217,1218,1224,1230],{},[572,1219,1220],{},[637,1221,1223],{"href":1222},"\u002Fblog\u002F22-nuxt-3-to-4-migration-guide-2026","Nuxt 3 to Nuxt 4 Migration Guide",[572,1225,1226],{},[637,1227,1229],{"href":1228},"\u002Fblog\u002F23-ai-seo-developer-blog-guide-2026","AI SEO for Developer Blogs",[572,1231,1232],{},[637,1233,1235],{"href":1234},"\u002Fblog\u002F24-nuxt-4-edge-computing-guide","Edge Computing with Nuxt 4",[718,1237,1238],{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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":81,"searchDepth":96,"depth":96,"links":1240},[1241,1242,1243,1248,1249,1256],{"id":763,"depth":96,"text":764},{"id":798,"depth":96,"text":799},{"id":820,"depth":96,"text":821,"children":1244},[1245,1246,1247],{"id":824,"depth":102,"text":825},{"id":995,"depth":102,"text":996},{"id":1016,"depth":102,"text":1017},{"id":1023,"depth":96,"text":1024},{"id":1033,"depth":96,"text":1034,"children":1250},[1251,1252,1253,1254,1255],{"id":1037,"depth":102,"text":1038},{"id":1047,"depth":102,"text":1048},{"id":1077,"depth":102,"text":1078},{"id":1114,"depth":102,"text":1115},{"id":1159,"depth":102,"text":1160},{"id":1203,"depth":96,"text":1204},"2026-02-22","2026-02-25","Master Nuxt 4 SSR performance with proven strategies for Core Web Vitals optimization. Learn caching, data fetching, hybrid rendering, and monitoring for lightning-fast page loads.",{"readingTime":1261,"keywords":1262},"10 min read",[1263,1264,1265,1266,1267,1268,1269,1270,1271,1272],"nuxt 4 performance","core web vitals nuxt","nuxt lighthouse score","ssr optimization","nuxt caching strategies","nuxt 4 speed","vue ssr performance","nuxt nitro caching","web vitals optimization","nuxt 4 best practices","\u002Fblog\u002F16-nuxt-4-ssr-performance-optimization",{"title":758,"description":1259},"Modern Development","Exploring cutting-edge development practices and tools",{"src":1278,"mime":742,"alt":1279,"width":744,"height":745},"\u002Fimg\u002Fblog\u002F16-nuxt-4-ssr-performance-optimization\u002Fbanner.svg","Nuxt 4 SSR Performance Optimization - Lightning-fast page loads with speedometer and lightning bolt icons on green gradient background","blog\u002F16-nuxt-4-ssr-performance-optimization",[748,1282,752,753,1283,1284],"Vue.js","Optimization","Core Web Vitals","XhRUZiLhn6SJsObNSFfkCf0T1Lb4RVB7phsNfmDX75E",{"id":1287,"title":1288,"abstract":1289,"author":62,"authorUrl":63,"body":1290,"date":4128,"dateUpdated":4128,"description":4129,"excerpt":734,"extension":735,"featured":438,"headline":1288,"image":734,"meta":4130,"navigation":438,"ogImage":734,"path":4132,"seo":4133,"series":4134,"seriesDescription":4135,"seriesOrder":102,"socialImage":4136,"stem":4140,"tags":4141,"__hash__":4146},"blog\u002Fblog\u002F39-execution-systems-first-not-features.md","I Stopped Building Features First - I Now Design Execution Systems First","A shift from feature-driven development to system-driven execution design, with practical patterns from Laravel, Nuxt, and AI systems.",{"type":65,"value":1291,"toc":4114},[1292,1295,1298,1301,1304,1308,1311,1337,1340,1343,1347,1351,1354,1357,1494,1497,1501,1504,1507,1510,1513,1804,2523,2526,2530,2533,2536,2539,2877,3568,3571,3575,3578,3581,3595,3598,3601,3621,3931,3934,3938,4049,4052,4056,4059,4062,4079,4082,4085,4089,4092,4095,4098,4102,4105,4108,4111],[68,1293,1288],{"id":1294},"i-stopped-building-features-first-i-now-design-execution-systems-first",[72,1296,1297],{},"Three years ago, I spent two months building a billing feature for a Laravel SaaS application. On paper, it was straightforward: tiered subscriptions, usage-based metering, invoice generation. The client approved the spec. I built the features. Everything worked.",[72,1299,1300],{},"Then the first edge case hit. A customer upgraded mid-cycle, received a prorated invoice, downgraded the next day, and the system double-charged them. The fix required tracing through five controllers, three event listeners, and a tangled web of Eloquent callbacks to understand the full execution path. What looked like six clean features was actually one broken system. The root cause was never the billing logic - it was the execution flow. I had modeled features, not flows. I had built isolated pieces without designing the sequence, state transitions, and failure recovery that connected them.",[72,1302,1303],{},"That project took three times longer than estimated, not because the features were complex, but because the execution system was an afterthought. I learned a hard lesson: building features first is the fastest path to technical debt. Designing the execution system first is the fastest path to maintainable software.",[68,1305,1307],{"id":1306},"what-execution-systems-first-means-in-practice","What \"Execution Systems First\" Means in Practice",[72,1309,1310],{},"An execution system is the invisible skeleton that turns user intent into completed outcomes. It is not a feature list, a component tree, or a database schema. It is the orchestration layer that defines:",[630,1312,1313,1319,1325,1331],{},[572,1314,1315,1318],{},[134,1316,1317],{},"Flow",": The sequence of steps that transform input into output",[572,1320,1321,1324],{},[134,1322,1323],{},"State",": What data persists between steps and how transitions happen",[572,1326,1327,1330],{},[134,1328,1329],{},"Failure handling",": What happens when a step errors, times out, or produces invalid data",[572,1332,1333,1336],{},[134,1334,1335],{},"Task boundaries",": Where one responsibility ends and another begins",[72,1338,1339],{},"Most teams design features as a list of user stories and acceptance criteria. Each story gets built independently. The execution system emerges accidentally from the accumulation of these pieces. By the time anyone notices the fragmentation, the coupling is already baked in.",[72,1341,1342],{},"Designing execution systems first flips this. Before writing a single line of application code, I map the flow diagram, define the state machine, and decompose the work into units that match the execution path rather than the UI surface area. Features become leaves on an existing tree rather than trees with their own root systems.",[68,1344,1346],{"id":1345},"three-pillars-of-execution-system-design","Three Pillars of Execution System Design",[294,1348,1350],{"id":1349},"_1-execution-flow-design","1. Execution Flow Design",[72,1352,1353],{},"Flow design answers one question: what is the complete path from trigger to outcome, including every branch and failure mode?",[72,1355,1356],{},"For the billing system that failed me, the flow would have revealed the mid-cycle upgrade edge case immediately. A proper flow diagram exposes every transition, every state, and every decision point before implementation begins.",[76,1358,1362],{"className":1359,"code":1360,"language":1361,"meta":81,"style":81},"language-mermaid shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","graph TD\n    A[Customer Action Triggered] --> B{Action Type?}\n    B -->|Subscribe| C[Create Subscription\u003Cbr\u002F>Set Active State]\n    B -->|Upgrade Tier| D[Calculate Proration]\n    B -->|Downgrade Tier| E[Schedule Tier Change\u003Cbr\u002F>Maintain Current Until Period End]\n    B -->|Cancel| F[Run Cancellation Flow]\n\n    C --> G[Generate Invoice]\n    D --> H{Credit Exists?}\n    H -->|Yes| I[Apply Credit\u003Cbr\u002F>Generate Net Invoice]\n    H -->|No| J[Generate Pro-rated Invoice]\n    I --> K[Update Subscription State]\n    J --> K\n    E --> L[Set Pending Tier\u003Cbr\u002F>Active Tier Unchanged]\n    F --> M[Stop Recurring\u003Cbr\u002F>Process Final Invoice]\n\n    K --> N[Send Notification]\n    L --> N\n    M --> N\n    N --> O[Log Audit Trail]\n\n    style D fill:#4a6,color:#fff\n    style E fill:#a64,color:#fff\n    style H fill:#47a,color:#fff\n","mermaid",[83,1363,1364,1369,1374,1379,1384,1389,1394,1398,1403,1408,1413,1418,1424,1430,1436,1442,1447,1453,1459,1465,1471,1476,1482,1488],{"__ignoreMap":81},[86,1365,1366],{"class":88,"line":89},[86,1367,1368],{},"graph TD\n",[86,1370,1371],{"class":88,"line":96},[86,1372,1373],{},"    A[Customer Action Triggered] --> B{Action Type?}\n",[86,1375,1376],{"class":88,"line":102},[86,1377,1378],{},"    B -->|Subscribe| C[Create Subscription\u003Cbr\u002F>Set Active State]\n",[86,1380,1381],{"class":88,"line":213},[86,1382,1383],{},"    B -->|Upgrade Tier| D[Calculate Proration]\n",[86,1385,1386],{"class":88,"line":237},[86,1387,1388],{},"    B -->|Downgrade Tier| E[Schedule Tier Change\u003Cbr\u002F>Maintain Current Until Period End]\n",[86,1390,1391],{"class":88,"line":269},[86,1392,1393],{},"    B -->|Cancel| F[Run Cancellation Flow]\n",[86,1395,1396],{"class":88,"line":275},[86,1397,439],{"emptyLinePlaceholder":438},[86,1399,1400],{"class":88,"line":499},[86,1401,1402],{},"    C --> G[Generate Invoice]\n",[86,1404,1405],{"class":88,"line":523},[86,1406,1407],{},"    D --> H{Credit Exists?}\n",[86,1409,1410],{"class":88,"line":529},[86,1411,1412],{},"    H -->|Yes| I[Apply Credit\u003Cbr\u002F>Generate Net Invoice]\n",[86,1414,1415],{"class":88,"line":534},[86,1416,1417],{},"    H -->|No| J[Generate Pro-rated Invoice]\n",[86,1419,1421],{"class":88,"line":1420},12,[86,1422,1423],{},"    I --> K[Update Subscription State]\n",[86,1425,1427],{"class":88,"line":1426},13,[86,1428,1429],{},"    J --> K\n",[86,1431,1433],{"class":88,"line":1432},14,[86,1434,1435],{},"    E --> L[Set Pending Tier\u003Cbr\u002F>Active Tier Unchanged]\n",[86,1437,1439],{"class":88,"line":1438},15,[86,1440,1441],{},"    F --> M[Stop Recurring\u003Cbr\u002F>Process Final Invoice]\n",[86,1443,1445],{"class":88,"line":1444},16,[86,1446,439],{"emptyLinePlaceholder":438},[86,1448,1450],{"class":88,"line":1449},17,[86,1451,1452],{},"    K --> N[Send Notification]\n",[86,1454,1456],{"class":88,"line":1455},18,[86,1457,1458],{},"    L --> N\n",[86,1460,1462],{"class":88,"line":1461},19,[86,1463,1464],{},"    M --> N\n",[86,1466,1468],{"class":88,"line":1467},20,[86,1469,1470],{},"    N --> O[Log Audit Trail]\n",[86,1472,1474],{"class":88,"line":1473},21,[86,1475,439],{"emptyLinePlaceholder":438},[86,1477,1479],{"class":88,"line":1478},22,[86,1480,1481],{},"    style D fill:#4a6,color:#fff\n",[86,1483,1485],{"class":88,"line":1484},23,[86,1486,1487],{},"    style E fill:#a64,color:#fff\n",[86,1489,1491],{"class":88,"line":1490},24,[86,1492,1493],{},"    style H fill:#47a,color:#fff\n",[72,1495,1496],{},"This is a simplified version of what I now draw before any billing project starts. The branching at the upgrade and downgrade paths reveals the exact edge case that sank the original project. The state transitions are explicit. The failure paths are visible.",[294,1498,1500],{"id":1499},"_2-state-management-architecture","2. State Management Architecture",[72,1502,1503],{},"Every execution system has state. The question is whether that state is implicit, scattered, or centrally governed.",[72,1505,1506],{},"Implicit state lives in variables scattered across controllers, callbacks, and session data. It is the default approach in most frameworks because it requires no upfront design. It is also the fastest route to bugs that only appear under specific sequences of actions.",[72,1508,1509],{},"Centralized state management uses an explicit state machine or event-sourced store. Every transition is recorded. Every state is queryable. The execution system can be paused, inspected, and resumed at any point.",[72,1511,1512],{},"For Laravel applications, I use a state machine pattern built on Eloquent enums and a dedicated state machine service:",[76,1514,1518],{"className":1515,"code":1516,"language":1517,"meta":81,"style":81},"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F\u002F Before: feature-first billing with scattered state\nclass SubscriptionController extends Controller\n{\n    public function upgrade(Request $request, Subscription $subscription)\n    {\n        \u002F\u002F State lives in multiple places\n        $subscription->plan_id = $request->plan_id;\n        $subscription->save();\n\n        \u002F\u002F Proration logic embedded in controller\n        $credit = $this->calculateProrationCredit($subscription);\n        if ($credit > 0) {\n            $subscription->credit_balance += $credit;\n            $subscription->save();\n        }\n\n        \u002F\u002F Notification coupled to controller logic\n        $subscription->user->notify(new UpgradeConfirmation($subscription));\n\n        return redirect()->route('subscription.show', $subscription);\n    }\n}\n","php",[83,1519,1520,1525,1539,1543,1577,1582,1587,1615,1629,1633,1638,1661,1681,1703,1715,1720,1724,1729,1760,1764,1796,1800],{"__ignoreMap":81},[86,1521,1522],{"class":88,"line":89},[86,1523,1524],{"class":92},"\u002F\u002F Before: feature-first billing with scattered state\n",[86,1526,1527,1530,1533,1536],{"class":88,"line":96},[86,1528,1529],{"class":185},"class",[86,1531,1532],{"class":370}," SubscriptionController",[86,1534,1535],{"class":185}," extends",[86,1537,1538],{"class":370}," Controller\n",[86,1540,1541],{"class":88,"line":102},[86,1542,180],{"class":163},[86,1544,1545,1548,1551,1554,1556,1559,1562,1565,1567,1570,1572,1575],{"class":88,"line":213},[86,1546,1547],{"class":185},"    public",[86,1549,1550],{"class":185}," function",[86,1552,1553],{"class":205}," upgrade",[86,1555,243],{"class":163},[86,1557,1558],{"class":370},"Request",[86,1560,1561],{"class":163}," $",[86,1563,1564],{"class":156},"request",[86,1566,249],{"class":163},[86,1568,1569],{"class":370}," Subscription",[86,1571,1561],{"class":163},[86,1573,1574],{"class":156},"subscription",[86,1576,266],{"class":163},[86,1578,1579],{"class":88,"line":237},[86,1580,1581],{"class":163},"    {\n",[86,1583,1584],{"class":88,"line":269},[86,1585,1586],{"class":92},"        \u002F\u002F State lives in multiple places\n",[86,1588,1589,1592,1594,1597,1600,1603,1605,1607,1609,1612],{"class":88,"line":275},[86,1590,1591],{"class":163},"        $",[86,1593,1574],{"class":156},[86,1595,1596],{"class":163},"->",[86,1598,1599],{"class":156},"plan_id ",[86,1601,1602],{"class":163},"=",[86,1604,1561],{"class":163},[86,1606,1564],{"class":156},[86,1608,1596],{"class":163},[86,1610,1611],{"class":156},"plan_id",[86,1613,1614],{"class":163},";\n",[86,1616,1617,1619,1621,1623,1626],{"class":88,"line":499},[86,1618,1591],{"class":163},[86,1620,1574],{"class":156},[86,1622,1596],{"class":163},[86,1624,1625],{"class":205},"save",[86,1627,1628],{"class":163},"();\n",[86,1630,1631],{"class":88,"line":523},[86,1632,439],{"emptyLinePlaceholder":438},[86,1634,1635],{"class":88,"line":529},[86,1636,1637],{"class":92},"        \u002F\u002F Proration logic embedded in controller\n",[86,1639,1640,1642,1645,1647,1650,1653,1656,1658],{"class":88,"line":534},[86,1641,1591],{"class":163},[86,1643,1644],{"class":156},"credit ",[86,1646,1602],{"class":163},[86,1648,1649],{"class":163}," $this->",[86,1651,1652],{"class":205},"calculateProrationCredit",[86,1654,1655],{"class":163},"($",[86,1657,1574],{"class":156},[86,1659,1660],{"class":163},");\n",[86,1662,1663,1666,1669,1671,1673,1676,1679],{"class":88,"line":1420},[86,1664,1665],{"class":152},"        if",[86,1667,1668],{"class":163}," ($",[86,1670,1644],{"class":156},[86,1672,385],{"class":163},[86,1674,1675],{"class":888}," 0",[86,1677,1678],{"class":163},")",[86,1680,865],{"class":163},[86,1682,1683,1686,1688,1690,1693,1696,1698,1701],{"class":88,"line":1426},[86,1684,1685],{"class":163},"            $",[86,1687,1574],{"class":156},[86,1689,1596],{"class":163},[86,1691,1692],{"class":156},"credit_balance ",[86,1694,1695],{"class":163},"+=",[86,1697,1561],{"class":163},[86,1699,1700],{"class":156},"credit",[86,1702,1614],{"class":163},[86,1704,1705,1707,1709,1711,1713],{"class":88,"line":1432},[86,1706,1685],{"class":163},[86,1708,1574],{"class":156},[86,1710,1596],{"class":163},[86,1712,1625],{"class":205},[86,1714,1628],{"class":163},[86,1716,1717],{"class":88,"line":1438},[86,1718,1719],{"class":163},"        }\n",[86,1721,1722],{"class":88,"line":1444},[86,1723,439],{"emptyLinePlaceholder":438},[86,1725,1726],{"class":88,"line":1449},[86,1727,1728],{"class":92},"        \u002F\u002F Notification coupled to controller logic\n",[86,1730,1731,1733,1735,1737,1740,1742,1745,1747,1750,1753,1755,1757],{"class":88,"line":1455},[86,1732,1591],{"class":163},[86,1734,1574],{"class":156},[86,1736,1596],{"class":163},[86,1738,1739],{"class":156},"user",[86,1741,1596],{"class":163},[86,1743,1744],{"class":205},"notify",[86,1746,243],{"class":163},[86,1748,1749],{"class":888},"new",[86,1751,1752],{"class":370}," UpgradeConfirmation",[86,1754,1655],{"class":163},[86,1756,1574],{"class":156},[86,1758,1759],{"class":163},"));\n",[86,1761,1762],{"class":88,"line":1461},[86,1763,439],{"emptyLinePlaceholder":438},[86,1765,1766,1769,1772,1775,1778,1780,1783,1786,1788,1790,1792,1794],{"class":88,"line":1467},[86,1767,1768],{"class":152},"        return",[86,1770,1771],{"class":205}," redirect",[86,1773,1774],{"class":163},"()->",[86,1776,1777],{"class":205},"route",[86,1779,243],{"class":163},[86,1781,1782],{"class":163},"'",[86,1784,1785],{"class":255},"subscription.show",[86,1787,1782],{"class":163},[86,1789,249],{"class":163},[86,1791,1561],{"class":163},[86,1793,1574],{"class":156},[86,1795,1660],{"class":163},[86,1797,1798],{"class":88,"line":1473},[86,1799,526],{"class":163},[86,1801,1802],{"class":88,"line":1478},[86,1803,278],{"class":163},[76,1805,1807],{"className":1515,"code":1806,"language":1517,"meta":81,"style":81},"\u002F\u002F After: execution system with explicit state machine\n\nenum SubscriptionState: string\n{\n    case Active = 'active';\n    case PendingDowngrade = 'pending_downgrade';\n    case PendingUpgrade = 'pending_upgrade';\n    case Canceled = 'canceled';\n    case PastDue = 'past_due';\n}\n\nclass SubscriptionExecutionService\n{\n    public function __construct(\n        private SubscriptionStateMachine $stateMachine,\n        private ProrationService $proration,\n        private InvoiceService $invoices,\n        private NotificationService $notifications,\n    ) {}\n\n    public function executeTierChange(\n        Subscription $subscription,\n        Tier $newTier,\n        ChangeDirection $direction\n    ): ExecutionResult {\n        \u002F\u002F Validates transition is legal in current state\n        $this->stateMachine->assertCanTransitionTo(\n            $subscription,\n            $direction === ChangeDirection::Upgrade\n                ? SubscriptionState::PendingUpgrade\n                : SubscriptionState::PendingDowngrade\n        );\n\n        \u002F\u002F Calculates proration as a pure function\n        $proration = $this->proration->calculate(\n            $subscription,\n            $newTier,\n            $direction\n        );\n\n        \u002F\u002F Applies state transition atomically\n        $result = DB::transaction(function () use (\n            $subscription, $newTier, $proration, $direction\n        ) {\n            $updated = $this->stateMachine->transition(\n                $subscription,\n                $direction === ChangeDirection::Upgrade\n                    ? SubscriptionState::PendingUpgrade\n                    : SubscriptionState::PendingDowngrade\n            );\n\n            $invoice = $this->invoices->generate(\n                $updated,\n                $proration\n            );\n\n            return new ExecutionResult($updated, $invoice, $proration);\n        });\n\n        \u002F\u002F Notification is a side-effect, not business logic\n        $this->notifications->tierChanged($result);\n\n        return $result;\n    }\n}\n",[83,1808,1809,1814,1818,1831,1835,1855,1873,1891,1909,1927,1931,1935,1942,1946,1958,1973,1987,2001,2015,2023,2027,2038,2049,2061,2071,2082,2088,2103,2112,2132,2145,2158,2164,2169,2175,2196,2205,2214,2221,2226,2231,2237,2269,2293,2301,2322,2332,2347,2359,2371,2377,2382,2403,2413,2421,2426,2431,2461,2467,2472,2478,2497,2502,2513,2518],{"__ignoreMap":81},[86,1810,1811],{"class":88,"line":89},[86,1812,1813],{"class":92},"\u002F\u002F After: execution system with explicit state machine\n",[86,1815,1816],{"class":88,"line":96},[86,1817,439],{"emptyLinePlaceholder":438},[86,1819,1820,1823,1826,1828],{"class":88,"line":102},[86,1821,1822],{"class":185},"enum",[86,1824,1825],{"class":370}," SubscriptionState",[86,1827,643],{"class":163},[86,1829,1830],{"class":888}," string\n",[86,1832,1833],{"class":88,"line":213},[86,1834,180],{"class":163},[86,1836,1837,1840,1843,1845,1848,1851,1853],{"class":88,"line":237},[86,1838,1839],{"class":185},"    case",[86,1841,1842],{"class":156}," Active ",[86,1844,1602],{"class":163},[86,1846,1847],{"class":163}," '",[86,1849,1850],{"class":255},"active",[86,1852,1782],{"class":163},[86,1854,1614],{"class":163},[86,1856,1857,1859,1862,1864,1866,1869,1871],{"class":88,"line":269},[86,1858,1839],{"class":185},[86,1860,1861],{"class":156}," PendingDowngrade ",[86,1863,1602],{"class":163},[86,1865,1847],{"class":163},[86,1867,1868],{"class":255},"pending_downgrade",[86,1870,1782],{"class":163},[86,1872,1614],{"class":163},[86,1874,1875,1877,1880,1882,1884,1887,1889],{"class":88,"line":275},[86,1876,1839],{"class":185},[86,1878,1879],{"class":156}," PendingUpgrade ",[86,1881,1602],{"class":163},[86,1883,1847],{"class":163},[86,1885,1886],{"class":255},"pending_upgrade",[86,1888,1782],{"class":163},[86,1890,1614],{"class":163},[86,1892,1893,1895,1898,1900,1902,1905,1907],{"class":88,"line":499},[86,1894,1839],{"class":185},[86,1896,1897],{"class":156}," Canceled ",[86,1899,1602],{"class":163},[86,1901,1847],{"class":163},[86,1903,1904],{"class":255},"canceled",[86,1906,1782],{"class":163},[86,1908,1614],{"class":163},[86,1910,1911,1913,1916,1918,1920,1923,1925],{"class":88,"line":523},[86,1912,1839],{"class":185},[86,1914,1915],{"class":156}," PastDue ",[86,1917,1602],{"class":163},[86,1919,1847],{"class":163},[86,1921,1922],{"class":255},"past_due",[86,1924,1782],{"class":163},[86,1926,1614],{"class":163},[86,1928,1929],{"class":88,"line":529},[86,1930,278],{"class":163},[86,1932,1933],{"class":88,"line":534},[86,1934,439],{"emptyLinePlaceholder":438},[86,1936,1937,1939],{"class":88,"line":1420},[86,1938,1529],{"class":185},[86,1940,1941],{"class":370}," SubscriptionExecutionService\n",[86,1943,1944],{"class":88,"line":1426},[86,1945,180],{"class":163},[86,1947,1948,1950,1952,1955],{"class":88,"line":1432},[86,1949,1547],{"class":185},[86,1951,1550],{"class":185},[86,1953,1954],{"class":205}," __construct",[86,1956,1957],{"class":163},"(\n",[86,1959,1960,1963,1966,1968,1971],{"class":88,"line":1438},[86,1961,1962],{"class":185},"        private",[86,1964,1965],{"class":370}," SubscriptionStateMachine",[86,1967,1561],{"class":163},[86,1969,1970],{"class":156},"stateMachine",[86,1972,947],{"class":163},[86,1974,1975,1977,1980,1982,1985],{"class":88,"line":1444},[86,1976,1962],{"class":185},[86,1978,1979],{"class":370}," ProrationService",[86,1981,1561],{"class":163},[86,1983,1984],{"class":156},"proration",[86,1986,947],{"class":163},[86,1988,1989,1991,1994,1996,1999],{"class":88,"line":1449},[86,1990,1962],{"class":185},[86,1992,1993],{"class":370}," InvoiceService",[86,1995,1561],{"class":163},[86,1997,1998],{"class":156},"invoices",[86,2000,947],{"class":163},[86,2002,2003,2005,2008,2010,2013],{"class":88,"line":1455},[86,2004,1962],{"class":185},[86,2006,2007],{"class":370}," NotificationService",[86,2009,1561],{"class":163},[86,2011,2012],{"class":156},"notifications",[86,2014,947],{"class":163},[86,2016,2017,2020],{"class":88,"line":1461},[86,2018,2019],{"class":163},"    )",[86,2021,2022],{"class":163}," {}\n",[86,2024,2025],{"class":88,"line":1467},[86,2026,439],{"emptyLinePlaceholder":438},[86,2028,2029,2031,2033,2036],{"class":88,"line":1473},[86,2030,1547],{"class":185},[86,2032,1550],{"class":185},[86,2034,2035],{"class":205}," executeTierChange",[86,2037,1957],{"class":163},[86,2039,2040,2043,2045,2047],{"class":88,"line":1478},[86,2041,2042],{"class":370},"        Subscription",[86,2044,1561],{"class":163},[86,2046,1574],{"class":156},[86,2048,947],{"class":163},[86,2050,2051,2054,2056,2059],{"class":88,"line":1484},[86,2052,2053],{"class":370},"        Tier",[86,2055,1561],{"class":163},[86,2057,2058],{"class":156},"newTier",[86,2060,947],{"class":163},[86,2062,2063,2066,2068],{"class":88,"line":1490},[86,2064,2065],{"class":370},"        ChangeDirection",[86,2067,1561],{"class":163},[86,2069,2070],{"class":156},"direction\n",[86,2072,2074,2077,2080],{"class":88,"line":2073},25,[86,2075,2076],{"class":163},"    ):",[86,2078,2079],{"class":370}," ExecutionResult",[86,2081,865],{"class":163},[86,2083,2085],{"class":88,"line":2084},26,[86,2086,2087],{"class":92},"        \u002F\u002F Validates transition is legal in current state\n",[86,2089,2091,2094,2096,2098,2101],{"class":88,"line":2090},27,[86,2092,2093],{"class":163},"        $this->",[86,2095,1970],{"class":156},[86,2097,1596],{"class":163},[86,2099,2100],{"class":205},"assertCanTransitionTo",[86,2102,1957],{"class":163},[86,2104,2106,2108,2110],{"class":88,"line":2105},28,[86,2107,1685],{"class":163},[86,2109,1574],{"class":156},[86,2111,947],{"class":163},[86,2113,2115,2117,2120,2123,2126,2129],{"class":88,"line":2114},29,[86,2116,1685],{"class":163},[86,2118,2119],{"class":156},"direction ",[86,2121,2122],{"class":163},"===",[86,2124,2125],{"class":370}," ChangeDirection",[86,2127,2128],{"class":163},"::",[86,2130,2131],{"class":156},"Upgrade\n",[86,2133,2135,2138,2140,2142],{"class":88,"line":2134},30,[86,2136,2137],{"class":163},"                ?",[86,2139,1825],{"class":370},[86,2141,2128],{"class":163},[86,2143,2144],{"class":156},"PendingUpgrade\n",[86,2146,2148,2151,2153,2155],{"class":88,"line":2147},31,[86,2149,2150],{"class":163},"                :",[86,2152,1825],{"class":370},[86,2154,2128],{"class":163},[86,2156,2157],{"class":156},"PendingDowngrade\n",[86,2159,2161],{"class":88,"line":2160},32,[86,2162,2163],{"class":163},"        );\n",[86,2165,2167],{"class":88,"line":2166},33,[86,2168,439],{"emptyLinePlaceholder":438},[86,2170,2172],{"class":88,"line":2171},34,[86,2173,2174],{"class":92},"        \u002F\u002F Calculates proration as a pure function\n",[86,2176,2178,2180,2183,2185,2187,2189,2191,2194],{"class":88,"line":2177},35,[86,2179,1591],{"class":163},[86,2181,2182],{"class":156},"proration ",[86,2184,1602],{"class":163},[86,2186,1649],{"class":163},[86,2188,1984],{"class":156},[86,2190,1596],{"class":163},[86,2192,2193],{"class":205},"calculate",[86,2195,1957],{"class":163},[86,2197,2199,2201,2203],{"class":88,"line":2198},36,[86,2200,1685],{"class":163},[86,2202,1574],{"class":156},[86,2204,947],{"class":163},[86,2206,2208,2210,2212],{"class":88,"line":2207},37,[86,2209,1685],{"class":163},[86,2211,2058],{"class":156},[86,2213,947],{"class":163},[86,2215,2217,2219],{"class":88,"line":2216},38,[86,2218,1685],{"class":163},[86,2220,2070],{"class":156},[86,2222,2224],{"class":88,"line":2223},39,[86,2225,2163],{"class":163},[86,2227,2229],{"class":88,"line":2228},40,[86,2230,439],{"emptyLinePlaceholder":438},[86,2232,2234],{"class":88,"line":2233},41,[86,2235,2236],{"class":92},"        \u002F\u002F Applies state transition atomically\n",[86,2238,2240,2242,2245,2247,2250,2252,2255,2257,2260,2263,2266],{"class":88,"line":2239},42,[86,2241,1591],{"class":163},[86,2243,2244],{"class":156},"result ",[86,2246,1602],{"class":163},[86,2248,2249],{"class":370}," DB",[86,2251,2128],{"class":163},[86,2253,2254],{"class":205},"transaction",[86,2256,243],{"class":163},[86,2258,2259],{"class":185},"function",[86,2261,2262],{"class":163}," ()",[86,2264,2265],{"class":888}," use",[86,2267,2268],{"class":163}," (\n",[86,2270,2272,2274,2276,2278,2280,2282,2284,2286,2288,2290],{"class":88,"line":2271},43,[86,2273,1685],{"class":163},[86,2275,1574],{"class":156},[86,2277,249],{"class":163},[86,2279,1561],{"class":163},[86,2281,2058],{"class":156},[86,2283,249],{"class":163},[86,2285,1561],{"class":163},[86,2287,1984],{"class":156},[86,2289,249],{"class":163},[86,2291,2292],{"class":156}," $direction\n",[86,2294,2296,2299],{"class":88,"line":2295},44,[86,2297,2298],{"class":163},"        )",[86,2300,865],{"class":163},[86,2302,2304,2306,2309,2311,2313,2315,2317,2320],{"class":88,"line":2303},45,[86,2305,1685],{"class":163},[86,2307,2308],{"class":156},"updated ",[86,2310,1602],{"class":163},[86,2312,1649],{"class":163},[86,2314,1970],{"class":156},[86,2316,1596],{"class":163},[86,2318,2319],{"class":205},"transition",[86,2321,1957],{"class":163},[86,2323,2325,2328,2330],{"class":88,"line":2324},46,[86,2326,2327],{"class":163},"                $",[86,2329,1574],{"class":156},[86,2331,947],{"class":163},[86,2333,2335,2337,2339,2341,2343,2345],{"class":88,"line":2334},47,[86,2336,2327],{"class":163},[86,2338,2119],{"class":156},[86,2340,2122],{"class":163},[86,2342,2125],{"class":370},[86,2344,2128],{"class":163},[86,2346,2131],{"class":156},[86,2348,2350,2353,2355,2357],{"class":88,"line":2349},48,[86,2351,2352],{"class":163},"                    ?",[86,2354,1825],{"class":370},[86,2356,2128],{"class":163},[86,2358,2144],{"class":156},[86,2360,2362,2365,2367,2369],{"class":88,"line":2361},49,[86,2363,2364],{"class":163},"                    :",[86,2366,1825],{"class":370},[86,2368,2128],{"class":163},[86,2370,2157],{"class":156},[86,2372,2374],{"class":88,"line":2373},50,[86,2375,2376],{"class":163},"            );\n",[86,2378,2380],{"class":88,"line":2379},51,[86,2381,439],{"emptyLinePlaceholder":438},[86,2383,2385,2387,2390,2392,2394,2396,2398,2401],{"class":88,"line":2384},52,[86,2386,1685],{"class":163},[86,2388,2389],{"class":156},"invoice ",[86,2391,1602],{"class":163},[86,2393,1649],{"class":163},[86,2395,1998],{"class":156},[86,2397,1596],{"class":163},[86,2399,2400],{"class":205},"generate",[86,2402,1957],{"class":163},[86,2404,2406,2408,2411],{"class":88,"line":2405},53,[86,2407,2327],{"class":163},[86,2409,2410],{"class":156},"updated",[86,2412,947],{"class":163},[86,2414,2416,2418],{"class":88,"line":2415},54,[86,2417,2327],{"class":163},[86,2419,2420],{"class":156},"proration\n",[86,2422,2424],{"class":88,"line":2423},55,[86,2425,2376],{"class":163},[86,2427,2429],{"class":88,"line":2428},56,[86,2430,439],{"emptyLinePlaceholder":438},[86,2432,2434,2437,2440,2442,2444,2446,2448,2450,2453,2455,2457,2459],{"class":88,"line":2433},57,[86,2435,2436],{"class":152},"            return",[86,2438,2439],{"class":888}," new",[86,2441,2079],{"class":370},[86,2443,1655],{"class":163},[86,2445,2410],{"class":156},[86,2447,249],{"class":163},[86,2449,1561],{"class":163},[86,2451,2452],{"class":156},"invoice",[86,2454,249],{"class":163},[86,2456,1561],{"class":163},[86,2458,1984],{"class":156},[86,2460,1660],{"class":163},[86,2462,2464],{"class":88,"line":2463},58,[86,2465,2466],{"class":163},"        });\n",[86,2468,2470],{"class":88,"line":2469},59,[86,2471,439],{"emptyLinePlaceholder":438},[86,2473,2475],{"class":88,"line":2474},60,[86,2476,2477],{"class":92},"        \u002F\u002F Notification is a side-effect, not business logic\n",[86,2479,2481,2483,2485,2487,2490,2492,2495],{"class":88,"line":2480},61,[86,2482,2093],{"class":163},[86,2484,2012],{"class":156},[86,2486,1596],{"class":163},[86,2488,2489],{"class":205},"tierChanged",[86,2491,1655],{"class":163},[86,2493,2494],{"class":156},"result",[86,2496,1660],{"class":163},[86,2498,2500],{"class":88,"line":2499},62,[86,2501,439],{"emptyLinePlaceholder":438},[86,2503,2505,2507,2509,2511],{"class":88,"line":2504},63,[86,2506,1768],{"class":152},[86,2508,1561],{"class":163},[86,2510,2494],{"class":156},[86,2512,1614],{"class":163},[86,2514,2516],{"class":88,"line":2515},64,[86,2517,526],{"class":163},[86,2519,2521],{"class":88,"line":2520},65,[86,2522,278],{"class":163},[72,2524,2525],{},"The before version is shorter. It is also untestable without HTTP mocks, un-resumable if it fails mid-execution, and dangerous to modify because state is scattered across the controller body. The after version is longer but each piece is isolated. The state machine enforces valid transitions. The proration logic is a pure function. The persistence happens inside a transaction. Notifications are decoupled side effects.",[294,2527,2529],{"id":2528},"_3-task-decomposition","3. Task Decomposition",[72,2531,2532],{},"Execution systems decompose work into tasks. The mistake most teams make is decomposing along feature boundaries - one task per UI component, one task per API endpoint. This produces tasks that are coupled to presentation, not to execution.",[72,2534,2535],{},"I decompose along failure boundaries instead. A task should represent a unit of work that can succeed or fail independently. If a task fails, the system should be able to retry it, skip it, or route around it without restarting the entire execution.",[72,2537,2538],{},"For Nuxt applications, this maps to composable design:",[76,2540,2542],{"className":831,"code":2541,"language":833,"meta":81,"style":81},"\u002F\u002F Feature-first: one composable handles everything\nexport function useCheckout() {\n  const { data, error, execute } = useFetch(\"\u002Fapi\u002Fcheckout\", {\n    immediate: false,\n  })\n\n  async function checkout(cart: Cart) {\n    const validation = validateCart(cart)\n    if (!validation.valid) throw new Error(validation.error)\n\n    const order = await createOrder(cart)\n    const payment = await processPayment(order)\n    if (!payment.success) {\n      await cancelOrder(order.id)\n      throw new Error(payment.error)\n    }\n\n    await sendConfirmation(order, payment)\n    return order\n  }\n\n  return { data, error, checkout }\n}\n",[83,2543,2544,2549,2563,2603,2615,2622,2626,2651,2669,2707,2711,2732,2753,2773,2792,2811,2815,2819,2837,2845,2849,2853,2873],{"__ignoreMap":81},[86,2545,2546],{"class":88,"line":89},[86,2547,2548],{"class":92},"\u002F\u002F Feature-first: one composable handles everything\n",[86,2550,2551,2553,2555,2558,2561],{"class":88,"line":96},[86,2552,845],{"class":152},[86,2554,1550],{"class":185},[86,2556,2557],{"class":205}," useCheckout",[86,2559,2560],{"class":163},"()",[86,2562,865],{"class":163},[86,2564,2565,2567,2569,2572,2574,2577,2579,2582,2585,2587,2590,2592,2594,2597,2599,2601],{"class":88,"line":102},[86,2566,186],{"class":185},[86,2568,880],{"class":163},[86,2570,2571],{"class":156}," data",[86,2573,249],{"class":163},[86,2575,2576],{"class":156}," error",[86,2578,249],{"class":163},[86,2580,2581],{"class":156}," execute",[86,2583,2584],{"class":163}," }",[86,2586,192],{"class":163},[86,2588,2589],{"class":205}," useFetch",[86,2591,243],{"class":209},[86,2593,259],{"class":163},[86,2595,2596],{"class":255},"\u002Fapi\u002Fcheckout",[86,2598,259],{"class":163},[86,2600,249],{"class":163},[86,2602,865],{"class":163},[86,2604,2605,2608,2610,2613],{"class":88,"line":213},[86,2606,2607],{"class":209},"    immediate",[86,2609,643],{"class":163},[86,2611,2612],{"class":943}," false",[86,2614,947],{"class":163},[86,2616,2617,2620],{"class":88,"line":237},[86,2618,2619],{"class":163},"  }",[86,2621,266],{"class":209},[86,2623,2624],{"class":88,"line":269},[86,2625,439],{"emptyLinePlaceholder":438},[86,2627,2628,2631,2633,2636,2638,2642,2644,2647,2649],{"class":88,"line":275},[86,2629,2630],{"class":185},"  async",[86,2632,1550],{"class":185},[86,2634,2635],{"class":205}," checkout",[86,2637,243],{"class":163},[86,2639,2641],{"class":2640},"sHdIc","cart",[86,2643,643],{"class":163},[86,2645,2646],{"class":370}," Cart",[86,2648,1678],{"class":163},[86,2650,865],{"class":163},[86,2652,2653,2655,2658,2660,2663,2665,2667],{"class":88,"line":499},[86,2654,461],{"class":185},[86,2656,2657],{"class":156}," validation",[86,2659,192],{"class":163},[86,2661,2662],{"class":205}," validateCart",[86,2664,243],{"class":209},[86,2666,2641],{"class":156},[86,2668,266],{"class":209},[86,2670,2671,2674,2676,2678,2681,2683,2686,2688,2691,2693,2696,2698,2700,2702,2705],{"class":88,"line":523},[86,2672,2673],{"class":152},"    if",[86,2675,157],{"class":209},[86,2677,449],{"class":163},[86,2679,2680],{"class":156},"validation",[86,2682,137],{"class":163},[86,2684,2685],{"class":156},"valid",[86,2687,232],{"class":209},[86,2689,2690],{"class":152},"throw",[86,2692,2439],{"class":163},[86,2694,2695],{"class":205}," Error",[86,2697,243],{"class":209},[86,2699,2680],{"class":156},[86,2701,137],{"class":163},[86,2703,2704],{"class":156},"error",[86,2706,266],{"class":209},[86,2708,2709],{"class":88,"line":529},[86,2710,439],{"emptyLinePlaceholder":438},[86,2712,2713,2715,2718,2720,2723,2726,2728,2730],{"class":88,"line":534},[86,2714,461],{"class":185},[86,2716,2717],{"class":156}," order",[86,2719,192],{"class":163},[86,2721,2722],{"class":152}," await",[86,2724,2725],{"class":205}," createOrder",[86,2727,243],{"class":209},[86,2729,2641],{"class":156},[86,2731,266],{"class":209},[86,2733,2734,2736,2739,2741,2743,2746,2748,2751],{"class":88,"line":1420},[86,2735,461],{"class":185},[86,2737,2738],{"class":156}," payment",[86,2740,192],{"class":163},[86,2742,2722],{"class":152},[86,2744,2745],{"class":205}," processPayment",[86,2747,243],{"class":209},[86,2749,2750],{"class":156},"order",[86,2752,266],{"class":209},[86,2754,2755,2757,2759,2761,2764,2766,2769,2771],{"class":88,"line":1426},[86,2756,2673],{"class":152},[86,2758,157],{"class":209},[86,2760,449],{"class":163},[86,2762,2763],{"class":156},"payment",[86,2765,137],{"class":163},[86,2767,2768],{"class":156},"success",[86,2770,232],{"class":209},[86,2772,180],{"class":163},[86,2774,2775,2778,2781,2783,2785,2787,2790],{"class":88,"line":1432},[86,2776,2777],{"class":152},"      await",[86,2779,2780],{"class":205}," cancelOrder",[86,2782,243],{"class":209},[86,2784,2750],{"class":156},[86,2786,137],{"class":163},[86,2788,2789],{"class":156},"id",[86,2791,266],{"class":209},[86,2793,2794,2797,2799,2801,2803,2805,2807,2809],{"class":88,"line":1438},[86,2795,2796],{"class":152},"      throw",[86,2798,2439],{"class":163},[86,2800,2695],{"class":205},[86,2802,243],{"class":209},[86,2804,2763],{"class":156},[86,2806,137],{"class":163},[86,2808,2704],{"class":156},[86,2810,266],{"class":209},[86,2812,2813],{"class":88,"line":1444},[86,2814,526],{"class":163},[86,2816,2817],{"class":88,"line":1449},[86,2818,439],{"emptyLinePlaceholder":438},[86,2820,2821,2824,2827,2829,2831,2833,2835],{"class":88,"line":1455},[86,2822,2823],{"class":152},"    await",[86,2825,2826],{"class":205}," sendConfirmation",[86,2828,243],{"class":209},[86,2830,2750],{"class":156},[86,2832,249],{"class":163},[86,2834,2738],{"class":156},[86,2836,266],{"class":209},[86,2838,2839,2842],{"class":88,"line":1461},[86,2840,2841],{"class":152},"    return",[86,2843,2844],{"class":156}," order\n",[86,2846,2847],{"class":88,"line":1467},[86,2848,272],{"class":163},[86,2850,2851],{"class":88,"line":1473},[86,2852,439],{"emptyLinePlaceholder":438},[86,2854,2855,2858,2860,2862,2864,2866,2868,2870],{"class":88,"line":1478},[86,2856,2857],{"class":152},"  return",[86,2859,880],{"class":163},[86,2861,2571],{"class":156},[86,2863,249],{"class":163},[86,2865,2576],{"class":156},[86,2867,249],{"class":163},[86,2869,2635],{"class":156},[86,2871,2872],{"class":163}," }\n",[86,2874,2875],{"class":88,"line":1484},[86,2876,278],{"class":163},[76,2878,2880],{"className":831,"code":2879,"language":833,"meta":81,"style":81},"\u002F\u002F System-first: decomposed into failure-independent tasks\nexport function useCheckoutSystem() {\n  const step = ref\u003CCheckoutStep>(\"idle\")\n  const executionId = ref\u003Cstring | null>(null)\n\n  const tasks = {\n    validate: useTask(\"checkout.validate\", validateCart),\n    createOrder: useTask(\"checkout.createOrder\", createOrder),\n    processPayment: useTask(\"checkout.processPayment\", processPayment),\n    confirm: useTask(\"checkout.confirm\", sendConfirmation),\n  }\n\n  async function checkout(cart: Cart): Promise\u003CExecutionResult> {\n    executionId.value = generateId()\n    step.value = \"validating\"\n\n    \u002F\u002F Each task runs independently, with its own state and recovery\n    const validation = await tasks.validate.run(cart)\n    if (!validation.ok) return fail(validation.error)\n\n    step.value = \"creating_order\"\n    const order = await tasks.createOrder.run(validation.data)\n    if (!order.ok) return fail(order.error)\n\n    step.value = \"processing_payment\"\n    const payment = await tasks.processPayment.run(order.data)\n    if (!payment.ok) {\n      \u002F\u002F Payment failed but order is already created - handle independently\n      await tasks.compensate(\"createOrder\", order.data.id).run()\n      return fail(payment.error)\n    }\n\n    step.value = \"confirming\"\n    await tasks.confirm.run(order.data)\n\n    step.value = \"completed\"\n    return success(order.data, payment.data)\n  }\n\n  return { checkout, step, executionId, tasks }\n}\n",[83,2881,2882,2887,2900,2930,2959,2963,2974,3001,3027,3053,3079,3083,3087,3118,3135,3154,3158,3163,3191,3224,3228,3245,3277,3307,3311,3328,3359,3377,3382,3421,3438,3442,3446,3463,3488,3492,3509,3534,3538,3542,3564],{"__ignoreMap":81},[86,2883,2884],{"class":88,"line":89},[86,2885,2886],{"class":92},"\u002F\u002F System-first: decomposed into failure-independent tasks\n",[86,2888,2889,2891,2893,2896,2898],{"class":88,"line":96},[86,2890,845],{"class":152},[86,2892,1550],{"class":185},[86,2894,2895],{"class":205}," useCheckoutSystem",[86,2897,2560],{"class":163},[86,2899,865],{"class":163},[86,2901,2902,2904,2907,2909,2912,2914,2917,2919,2921,2923,2926,2928],{"class":88,"line":102},[86,2903,186],{"class":185},[86,2905,2906],{"class":156}," step",[86,2908,192],{"class":163},[86,2910,2911],{"class":205}," ref",[86,2913,374],{"class":163},[86,2915,2916],{"class":370},"CheckoutStep",[86,2918,385],{"class":163},[86,2920,243],{"class":209},[86,2922,259],{"class":163},[86,2924,2925],{"class":255},"idle",[86,2927,259],{"class":163},[86,2929,266],{"class":209},[86,2931,2932,2934,2937,2939,2941,2943,2945,2947,2950,2952,2954,2957],{"class":88,"line":213},[86,2933,186],{"class":185},[86,2935,2936],{"class":156}," executionId",[86,2938,192],{"class":163},[86,2940,2911],{"class":205},[86,2942,374],{"class":163},[86,2944,377],{"class":370},[86,2946,388],{"class":163},[86,2948,2949],{"class":370}," null",[86,2951,385],{"class":163},[86,2953,243],{"class":209},[86,2955,2956],{"class":163},"null",[86,2958,266],{"class":209},[86,2960,2961],{"class":88,"line":237},[86,2962,439],{"emptyLinePlaceholder":438},[86,2964,2965,2967,2970,2972],{"class":88,"line":269},[86,2966,186],{"class":185},[86,2968,2969],{"class":156}," tasks",[86,2971,192],{"class":163},[86,2973,865],{"class":163},[86,2975,2976,2979,2981,2984,2986,2988,2991,2993,2995,2997,2999],{"class":88,"line":275},[86,2977,2978],{"class":209},"    validate",[86,2980,643],{"class":163},[86,2982,2983],{"class":205}," useTask",[86,2985,243],{"class":209},[86,2987,259],{"class":163},[86,2989,2990],{"class":255},"checkout.validate",[86,2992,259],{"class":163},[86,2994,249],{"class":163},[86,2996,2662],{"class":156},[86,2998,1678],{"class":209},[86,3000,947],{"class":163},[86,3002,3003,3006,3008,3010,3012,3014,3017,3019,3021,3023,3025],{"class":88,"line":499},[86,3004,3005],{"class":209},"    createOrder",[86,3007,643],{"class":163},[86,3009,2983],{"class":205},[86,3011,243],{"class":209},[86,3013,259],{"class":163},[86,3015,3016],{"class":255},"checkout.createOrder",[86,3018,259],{"class":163},[86,3020,249],{"class":163},[86,3022,2725],{"class":156},[86,3024,1678],{"class":209},[86,3026,947],{"class":163},[86,3028,3029,3032,3034,3036,3038,3040,3043,3045,3047,3049,3051],{"class":88,"line":523},[86,3030,3031],{"class":209},"    processPayment",[86,3033,643],{"class":163},[86,3035,2983],{"class":205},[86,3037,243],{"class":209},[86,3039,259],{"class":163},[86,3041,3042],{"class":255},"checkout.processPayment",[86,3044,259],{"class":163},[86,3046,249],{"class":163},[86,3048,2745],{"class":156},[86,3050,1678],{"class":209},[86,3052,947],{"class":163},[86,3054,3055,3058,3060,3062,3064,3066,3069,3071,3073,3075,3077],{"class":88,"line":529},[86,3056,3057],{"class":209},"    confirm",[86,3059,643],{"class":163},[86,3061,2983],{"class":205},[86,3063,243],{"class":209},[86,3065,259],{"class":163},[86,3067,3068],{"class":255},"checkout.confirm",[86,3070,259],{"class":163},[86,3072,249],{"class":163},[86,3074,2826],{"class":156},[86,3076,1678],{"class":209},[86,3078,947],{"class":163},[86,3080,3081],{"class":88,"line":534},[86,3082,272],{"class":163},[86,3084,3085],{"class":88,"line":1420},[86,3086,439],{"emptyLinePlaceholder":438},[86,3088,3089,3091,3093,3095,3097,3099,3101,3103,3106,3109,3111,3114,3116],{"class":88,"line":1426},[86,3090,2630],{"class":185},[86,3092,1550],{"class":185},[86,3094,2635],{"class":205},[86,3096,243],{"class":163},[86,3098,2641],{"class":2640},[86,3100,643],{"class":163},[86,3102,2646],{"class":370},[86,3104,3105],{"class":163},"):",[86,3107,3108],{"class":370}," Promise",[86,3110,374],{"class":163},[86,3112,3113],{"class":370},"ExecutionResult",[86,3115,385],{"class":163},[86,3117,865],{"class":163},[86,3119,3120,3123,3125,3128,3130,3133],{"class":88,"line":1432},[86,3121,3122],{"class":156},"    executionId",[86,3124,137],{"class":163},[86,3126,3127],{"class":156},"value",[86,3129,192],{"class":163},[86,3131,3132],{"class":205}," generateId",[86,3134,210],{"class":209},[86,3136,3137,3140,3142,3144,3146,3148,3151],{"class":88,"line":1438},[86,3138,3139],{"class":156},"    step",[86,3141,137],{"class":163},[86,3143,3127],{"class":156},[86,3145,192],{"class":163},[86,3147,252],{"class":163},[86,3149,3150],{"class":255},"validating",[86,3152,3153],{"class":163},"\"\n",[86,3155,3156],{"class":88,"line":1444},[86,3157,439],{"emptyLinePlaceholder":438},[86,3159,3160],{"class":88,"line":1449},[86,3161,3162],{"class":92},"    \u002F\u002F Each task runs independently, with its own state and recovery\n",[86,3164,3165,3167,3169,3171,3173,3175,3177,3180,3182,3185,3187,3189],{"class":88,"line":1455},[86,3166,461],{"class":185},[86,3168,2657],{"class":156},[86,3170,192],{"class":163},[86,3172,2722],{"class":152},[86,3174,2969],{"class":156},[86,3176,137],{"class":163},[86,3178,3179],{"class":156},"validate",[86,3181,137],{"class":163},[86,3183,3184],{"class":205},"run",[86,3186,243],{"class":209},[86,3188,2641],{"class":156},[86,3190,266],{"class":209},[86,3192,3193,3195,3197,3199,3201,3203,3206,3208,3211,3214,3216,3218,3220,3222],{"class":88,"line":1461},[86,3194,2673],{"class":152},[86,3196,157],{"class":209},[86,3198,449],{"class":163},[86,3200,2680],{"class":156},[86,3202,137],{"class":163},[86,3204,3205],{"class":156},"ok",[86,3207,232],{"class":209},[86,3209,3210],{"class":152},"return",[86,3212,3213],{"class":205}," fail",[86,3215,243],{"class":209},[86,3217,2680],{"class":156},[86,3219,137],{"class":163},[86,3221,2704],{"class":156},[86,3223,266],{"class":209},[86,3225,3226],{"class":88,"line":1467},[86,3227,439],{"emptyLinePlaceholder":438},[86,3229,3230,3232,3234,3236,3238,3240,3243],{"class":88,"line":1473},[86,3231,3139],{"class":156},[86,3233,137],{"class":163},[86,3235,3127],{"class":156},[86,3237,192],{"class":163},[86,3239,252],{"class":163},[86,3241,3242],{"class":255},"creating_order",[86,3244,3153],{"class":163},[86,3246,3247,3249,3251,3253,3255,3257,3259,3262,3264,3266,3268,3270,3272,3275],{"class":88,"line":1478},[86,3248,461],{"class":185},[86,3250,2717],{"class":156},[86,3252,192],{"class":163},[86,3254,2722],{"class":152},[86,3256,2969],{"class":156},[86,3258,137],{"class":163},[86,3260,3261],{"class":156},"createOrder",[86,3263,137],{"class":163},[86,3265,3184],{"class":205},[86,3267,243],{"class":209},[86,3269,2680],{"class":156},[86,3271,137],{"class":163},[86,3273,3274],{"class":156},"data",[86,3276,266],{"class":209},[86,3278,3279,3281,3283,3285,3287,3289,3291,3293,3295,3297,3299,3301,3303,3305],{"class":88,"line":1484},[86,3280,2673],{"class":152},[86,3282,157],{"class":209},[86,3284,449],{"class":163},[86,3286,2750],{"class":156},[86,3288,137],{"class":163},[86,3290,3205],{"class":156},[86,3292,232],{"class":209},[86,3294,3210],{"class":152},[86,3296,3213],{"class":205},[86,3298,243],{"class":209},[86,3300,2750],{"class":156},[86,3302,137],{"class":163},[86,3304,2704],{"class":156},[86,3306,266],{"class":209},[86,3308,3309],{"class":88,"line":1490},[86,3310,439],{"emptyLinePlaceholder":438},[86,3312,3313,3315,3317,3319,3321,3323,3326],{"class":88,"line":2073},[86,3314,3139],{"class":156},[86,3316,137],{"class":163},[86,3318,3127],{"class":156},[86,3320,192],{"class":163},[86,3322,252],{"class":163},[86,3324,3325],{"class":255},"processing_payment",[86,3327,3153],{"class":163},[86,3329,3330,3332,3334,3336,3338,3340,3342,3345,3347,3349,3351,3353,3355,3357],{"class":88,"line":2084},[86,3331,461],{"class":185},[86,3333,2738],{"class":156},[86,3335,192],{"class":163},[86,3337,2722],{"class":152},[86,3339,2969],{"class":156},[86,3341,137],{"class":163},[86,3343,3344],{"class":156},"processPayment",[86,3346,137],{"class":163},[86,3348,3184],{"class":205},[86,3350,243],{"class":209},[86,3352,2750],{"class":156},[86,3354,137],{"class":163},[86,3356,3274],{"class":156},[86,3358,266],{"class":209},[86,3360,3361,3363,3365,3367,3369,3371,3373,3375],{"class":88,"line":2090},[86,3362,2673],{"class":152},[86,3364,157],{"class":209},[86,3366,449],{"class":163},[86,3368,2763],{"class":156},[86,3370,137],{"class":163},[86,3372,3205],{"class":156},[86,3374,232],{"class":209},[86,3376,180],{"class":163},[86,3378,3379],{"class":88,"line":2105},[86,3380,3381],{"class":92},"      \u002F\u002F Payment failed but order is already created - handle independently\n",[86,3383,3384,3386,3388,3390,3393,3395,3397,3399,3401,3403,3405,3407,3409,3411,3413,3415,3417,3419],{"class":88,"line":2114},[86,3385,2777],{"class":152},[86,3387,2969],{"class":156},[86,3389,137],{"class":163},[86,3391,3392],{"class":205},"compensate",[86,3394,243],{"class":209},[86,3396,259],{"class":163},[86,3398,3261],{"class":255},[86,3400,259],{"class":163},[86,3402,249],{"class":163},[86,3404,2717],{"class":156},[86,3406,137],{"class":163},[86,3408,3274],{"class":156},[86,3410,137],{"class":163},[86,3412,2789],{"class":156},[86,3414,1678],{"class":209},[86,3416,137],{"class":163},[86,3418,3184],{"class":205},[86,3420,210],{"class":209},[86,3422,3423,3426,3428,3430,3432,3434,3436],{"class":88,"line":2134},[86,3424,3425],{"class":152},"      return",[86,3427,3213],{"class":205},[86,3429,243],{"class":209},[86,3431,2763],{"class":156},[86,3433,137],{"class":163},[86,3435,2704],{"class":156},[86,3437,266],{"class":209},[86,3439,3440],{"class":88,"line":2147},[86,3441,526],{"class":163},[86,3443,3444],{"class":88,"line":2160},[86,3445,439],{"emptyLinePlaceholder":438},[86,3447,3448,3450,3452,3454,3456,3458,3461],{"class":88,"line":2166},[86,3449,3139],{"class":156},[86,3451,137],{"class":163},[86,3453,3127],{"class":156},[86,3455,192],{"class":163},[86,3457,252],{"class":163},[86,3459,3460],{"class":255},"confirming",[86,3462,3153],{"class":163},[86,3464,3465,3467,3469,3471,3474,3476,3478,3480,3482,3484,3486],{"class":88,"line":2171},[86,3466,2823],{"class":152},[86,3468,2969],{"class":156},[86,3470,137],{"class":163},[86,3472,3473],{"class":156},"confirm",[86,3475,137],{"class":163},[86,3477,3184],{"class":205},[86,3479,243],{"class":209},[86,3481,2750],{"class":156},[86,3483,137],{"class":163},[86,3485,3274],{"class":156},[86,3487,266],{"class":209},[86,3489,3490],{"class":88,"line":2177},[86,3491,439],{"emptyLinePlaceholder":438},[86,3493,3494,3496,3498,3500,3502,3504,3507],{"class":88,"line":2198},[86,3495,3139],{"class":156},[86,3497,137],{"class":163},[86,3499,3127],{"class":156},[86,3501,192],{"class":163},[86,3503,252],{"class":163},[86,3505,3506],{"class":255},"completed",[86,3508,3153],{"class":163},[86,3510,3511,3513,3516,3518,3520,3522,3524,3526,3528,3530,3532],{"class":88,"line":2207},[86,3512,2841],{"class":152},[86,3514,3515],{"class":205}," success",[86,3517,243],{"class":209},[86,3519,2750],{"class":156},[86,3521,137],{"class":163},[86,3523,3274],{"class":156},[86,3525,249],{"class":163},[86,3527,2738],{"class":156},[86,3529,137],{"class":163},[86,3531,3274],{"class":156},[86,3533,266],{"class":209},[86,3535,3536],{"class":88,"line":2216},[86,3537,272],{"class":163},[86,3539,3540],{"class":88,"line":2223},[86,3541,439],{"emptyLinePlaceholder":438},[86,3543,3544,3546,3548,3550,3552,3554,3556,3558,3560,3562],{"class":88,"line":2228},[86,3545,2857],{"class":152},[86,3547,880],{"class":163},[86,3549,2635],{"class":156},[86,3551,249],{"class":163},[86,3553,2906],{"class":156},[86,3555,249],{"class":163},[86,3557,2936],{"class":156},[86,3559,249],{"class":163},[86,3561,2969],{"class":156},[86,3563,2872],{"class":163},[86,3565,3566],{"class":88,"line":2233},[86,3567,278],{"class":163},[72,3569,3570],{},"The system-first version reveals the execution boundaries. Payment can fail independently of order creation. The compensation task reverses only what needs reversing. The step state is inspectable, which means the UI can render progress deterministically and the backend can resume interrupted checkouts.",[68,3572,3574],{"id":3573},"real-example-laravel-saas-project","Real Example: Laravel SaaS Project",[72,3576,3577],{},"A client came to me with a Laravel application that managed compliance document workflows. Businesses uploaded documents, assigned reviewers, tracked review cycles, and generated audit trails. The existing codebase had twelve controllers, thirty-four event listeners, and an undocumented webhook handler that occasionally sent duplicate notifications.",[72,3579,3580],{},"The original architecture was feature-first:",[630,3582,3583,3586,3589,3592],{},[572,3584,3585],{},"Document upload feature with its own controller and validation",[572,3587,3588],{},"Reviewer assignment with its own controller and notification logic",[572,3590,3591],{},"Review cycle tracking scattered across three model observers",[572,3593,3594],{},"Audit trail implemented as an afterthought in a middleware",[72,3596,3597],{},"Every feature worked in isolation. The system failed under real conditions because the execution flow crossed feature boundaries. A reviewer rejecting a document should have triggered a reassignment flow. Instead, it logged a status change and sent an email, but the document remained in a dangling half-reviewed state because the next step was never defined.",[72,3599,3600],{},"I rebuilt the system using an execution-first approach:",[569,3602,3603,3609,3615],{},[572,3604,3605,3608],{},[134,3606,3607],{},"Flow diagram first",": Mapped the complete document lifecycle from upload to final approval, including reject loops, deadline escalations, and withdrawal mid-review",[572,3610,3611,3614],{},[134,3612,3613],{},"State machine",": Defined five document states (Draft, In Review, Changes Requested, Approved, Archived) with explicit transition rules",[572,3616,3617,3620],{},[134,3618,3619],{},"Task decomposition",": Each transition became a task with its own compensation logic",[76,3622,3624],{"className":1515,"code":3623,"language":1517,"meta":81,"style":81},"class DocumentExecutionService\n{\n    public function __construct(\n        private DocumentStateMachine $states,\n        private ReviewAssignmentService $assignments,\n        private EscalationService $escalations,\n        private AuditService $audit,\n    ) {}\n\n    public function rejectDocument(\n        Document $document,\n        Review $review,\n        string $reason\n    ): ExecutionResult {\n        \u002F\u002F State transition determines what happens next, not a controller\n        return $this->states->transition($document, DocumentState::ChangesRequested)\n            ->then(fn() => $this->assignments->reassign($document, $review->reviewer))\n            ->then(fn() => $this->escalations->resetDeadline($document))\n            ->onFailure(fn($step) => $this->audit->logFailure($document, $step))\n            ->execute();\n    }\n}\n",[83,3625,3626,3633,3637,3647,3661,3675,3689,3703,3709,3713,3724,3736,3748,3758,3766,3771,3799,3844,3873,3914,3923,3927],{"__ignoreMap":81},[86,3627,3628,3630],{"class":88,"line":89},[86,3629,1529],{"class":185},[86,3631,3632],{"class":370}," DocumentExecutionService\n",[86,3634,3635],{"class":88,"line":96},[86,3636,180],{"class":163},[86,3638,3639,3641,3643,3645],{"class":88,"line":102},[86,3640,1547],{"class":185},[86,3642,1550],{"class":185},[86,3644,1954],{"class":205},[86,3646,1957],{"class":163},[86,3648,3649,3651,3654,3656,3659],{"class":88,"line":213},[86,3650,1962],{"class":185},[86,3652,3653],{"class":370}," DocumentStateMachine",[86,3655,1561],{"class":163},[86,3657,3658],{"class":156},"states",[86,3660,947],{"class":163},[86,3662,3663,3665,3668,3670,3673],{"class":88,"line":237},[86,3664,1962],{"class":185},[86,3666,3667],{"class":370}," ReviewAssignmentService",[86,3669,1561],{"class":163},[86,3671,3672],{"class":156},"assignments",[86,3674,947],{"class":163},[86,3676,3677,3679,3682,3684,3687],{"class":88,"line":269},[86,3678,1962],{"class":185},[86,3680,3681],{"class":370}," EscalationService",[86,3683,1561],{"class":163},[86,3685,3686],{"class":156},"escalations",[86,3688,947],{"class":163},[86,3690,3691,3693,3696,3698,3701],{"class":88,"line":275},[86,3692,1962],{"class":185},[86,3694,3695],{"class":370}," AuditService",[86,3697,1561],{"class":163},[86,3699,3700],{"class":156},"audit",[86,3702,947],{"class":163},[86,3704,3705,3707],{"class":88,"line":499},[86,3706,2019],{"class":163},[86,3708,2022],{"class":163},[86,3710,3711],{"class":88,"line":523},[86,3712,439],{"emptyLinePlaceholder":438},[86,3714,3715,3717,3719,3722],{"class":88,"line":529},[86,3716,1547],{"class":185},[86,3718,1550],{"class":185},[86,3720,3721],{"class":205}," rejectDocument",[86,3723,1957],{"class":163},[86,3725,3726,3729,3731,3734],{"class":88,"line":534},[86,3727,3728],{"class":370},"        Document",[86,3730,1561],{"class":163},[86,3732,3733],{"class":156},"document",[86,3735,947],{"class":163},[86,3737,3738,3741,3743,3746],{"class":88,"line":1420},[86,3739,3740],{"class":370},"        Review",[86,3742,1561],{"class":163},[86,3744,3745],{"class":156},"review",[86,3747,947],{"class":163},[86,3749,3750,3753,3755],{"class":88,"line":1426},[86,3751,3752],{"class":888},"        string",[86,3754,1561],{"class":163},[86,3756,3757],{"class":156},"reason\n",[86,3759,3760,3762,3764],{"class":88,"line":1432},[86,3761,2076],{"class":163},[86,3763,2079],{"class":370},[86,3765,865],{"class":163},[86,3767,3768],{"class":88,"line":1438},[86,3769,3770],{"class":92},"        \u002F\u002F State transition determines what happens next, not a controller\n",[86,3772,3773,3775,3777,3779,3781,3783,3785,3787,3789,3792,3794,3797],{"class":88,"line":1444},[86,3774,1768],{"class":152},[86,3776,1649],{"class":163},[86,3778,3658],{"class":156},[86,3780,1596],{"class":163},[86,3782,2319],{"class":205},[86,3784,1655],{"class":163},[86,3786,3733],{"class":156},[86,3788,249],{"class":163},[86,3790,3791],{"class":370}," DocumentState",[86,3793,2128],{"class":163},[86,3795,3796],{"class":156},"ChangesRequested",[86,3798,266],{"class":163},[86,3800,3801,3804,3807,3809,3812,3814,3817,3819,3821,3823,3826,3828,3830,3832,3834,3836,3838,3841],{"class":88,"line":1449},[86,3802,3803],{"class":163},"            ->",[86,3805,3806],{"class":205},"then",[86,3808,243],{"class":163},[86,3810,3811],{"class":185},"fn",[86,3813,2560],{"class":163},[86,3815,3816],{"class":163}," =>",[86,3818,1649],{"class":163},[86,3820,3672],{"class":156},[86,3822,1596],{"class":163},[86,3824,3825],{"class":205},"reassign",[86,3827,1655],{"class":163},[86,3829,3733],{"class":156},[86,3831,249],{"class":163},[86,3833,1561],{"class":163},[86,3835,3745],{"class":156},[86,3837,1596],{"class":163},[86,3839,3840],{"class":156},"reviewer",[86,3842,3843],{"class":163},"))\n",[86,3845,3846,3848,3850,3852,3854,3856,3858,3860,3862,3864,3867,3869,3871],{"class":88,"line":1455},[86,3847,3803],{"class":163},[86,3849,3806],{"class":205},[86,3851,243],{"class":163},[86,3853,3811],{"class":185},[86,3855,2560],{"class":163},[86,3857,3816],{"class":163},[86,3859,1649],{"class":163},[86,3861,3686],{"class":156},[86,3863,1596],{"class":163},[86,3865,3866],{"class":205},"resetDeadline",[86,3868,1655],{"class":163},[86,3870,3733],{"class":156},[86,3872,3843],{"class":163},[86,3874,3875,3877,3880,3882,3884,3886,3889,3891,3893,3895,3897,3899,3902,3904,3906,3908,3910,3912],{"class":88,"line":1461},[86,3876,3803],{"class":163},[86,3878,3879],{"class":205},"onFailure",[86,3881,243],{"class":163},[86,3883,3811],{"class":185},[86,3885,1655],{"class":163},[86,3887,3888],{"class":156},"step",[86,3890,1678],{"class":163},[86,3892,3816],{"class":163},[86,3894,1649],{"class":163},[86,3896,3700],{"class":156},[86,3898,1596],{"class":163},[86,3900,3901],{"class":205},"logFailure",[86,3903,1655],{"class":163},[86,3905,3733],{"class":156},[86,3907,249],{"class":163},[86,3909,1561],{"class":163},[86,3911,3888],{"class":156},[86,3913,3843],{"class":163},[86,3915,3916,3918,3921],{"class":88,"line":1467},[86,3917,3803],{"class":163},[86,3919,3920],{"class":205},"execute",[86,3922,1628],{"class":163},[86,3924,3925],{"class":88,"line":1473},[86,3926,526],{"class":163},[86,3928,3929],{"class":88,"line":1478},[86,3930,278],{"class":163},[72,3932,3933],{},"The result was not smaller - the codebase grew by about 15% - but the number of production incidents dropped by 80%. The execution system made the implicit explicit, and explicit systems are debuggable.",[68,3935,3937],{"id":3936},"tradeoff-table-feature-first-vs-system-first","Tradeoff Table: Feature-First vs System-First",[3939,3940,3941,3957],"table",{},[3942,3943,3944],"thead",{},[3945,3946,3947,3951,3954],"tr",{},[3948,3949,3950],"th",{},"Dimension",[3948,3952,3953],{},"Feature-First",[3948,3955,3956],{},"System-First",[3958,3959,3960,3972,3983,3994,4005,4016,4027,4038],"tbody",{},[3945,3961,3962,3966,3969],{},[3963,3964,3965],"td",{},"Time to first feature",[3963,3967,3968],{},"Faster (days instead of weeks)",[3963,3970,3971],{},"Slower initial investment",[3945,3973,3974,3977,3980],{},[3963,3975,3976],{},"Time to ten features",[3963,3978,3979],{},"Slowing down as coupling grows",[3963,3981,3982],{},"Accelerating as patterns reuse",[3945,3984,3985,3988,3991],{},[3963,3986,3987],{},"Edge case handling",[3963,3989,3990],{},"Reactive, patch-by-patch",[3963,3992,3993],{},"Proactive, defined in flow design",[3945,3995,3996,3999,4002],{},[3963,3997,3998],{},"Rework cost per change",[3963,4000,4001],{},"High - changes ripple across scattered state",[3963,4003,4004],{},"Low - changes are confined to task boundaries",[3945,4006,4007,4010,4013],{},[3963,4008,4009],{},"Onboarding new developers",[3963,4011,4012],{},"Steep - implicit flows must be traced",[3963,4014,4015],{},"Shallow - flow diagram is the documentation",[3945,4017,4018,4021,4024],{},[3963,4019,4020],{},"Failure recovery",[3963,4022,4023],{},"Manual - operators must reconstruct state",[3963,4025,4026],{},"Automatic or assisted - state machine knows position",[3945,4028,4029,4032,4035],{},[3963,4030,4031],{},"Testing strategy",[3963,4033,4034],{},"End-to-end only, slow and brittle",[3963,4036,4037],{},"Task-level unit tests + system integration tests",[3945,4039,4040,4043,4046],{},[3963,4041,4042],{},"Refactoring confidence",[3963,4044,4045],{},"Low - afraid to touch tangled state",[3963,4047,4048],{},"High - state transitions are contractually defined",[72,4050,4051],{},"The time-to-market tradeoff is real. System-first costs more upfront. In my experience, the breakeven point is around the fifth feature. Beyond that, system-first pulls ahead and the gap widens with every addition.",[68,4053,4055],{"id":4054},"how-this-applies-to-ai-systems","How This Applies to AI Systems",[72,4057,4058],{},"This principle becomes critical in AI systems. An AI agent without an execution system is a single prompt call - it generates a response and stops. Production AI systems need multi-step execution with state persistence, failure recovery, and deterministic observability.",[72,4060,4061],{},"The gem-orchestrator system in the Gem Team framework is an execution system first and an AI tool second. Its phase detection, agent routing, wave-based execution, and structured retry loops mirror the same three pillars:",[630,4063,4064,4069,4074],{},[572,4065,4066,4068],{},[134,4067,1317],{},": The phase pipeline - detect phase, route to specialist, execute wave, synthesize results",[572,4070,4071,4073],{},[134,4072,1323],{},": Persistent execution context that survives individual agent calls",[572,4075,4076,4078],{},[134,4077,3619],{},": Each agent handles one phase, one deliverable, one failure boundary",[72,4080,4081],{},"When I see teams building AI agents by chaining prompts together, I see the same pattern that caused the billing system to fail. They are building features - prompt templates, tool integrations, output parsers - without designing the execution system that sequences, governs, and recovers them.",[72,4083,4084],{},"An AI agent's execution system answers the same questions as any other system: what is the flow, what is the state, where are the failure boundaries. The fact that the executor is an LLM rather than a PHP controller does not change the architectural requirement.",[68,4086,4088],{"id":4087},"consulting-signal-sell-system-design-not-feature-delivery","Consulting Signal: Sell System Design, Not Feature Delivery",[72,4090,4091],{},"I changed my consulting practice because of this lesson. When a potential client asks me to build a feature, I ask about the execution system first. Not to upsell, but to assess whether the feature will survive its first edge case.",[72,4093,4094],{},"If the response is \"We need user authentication, so build login, registration, and password reset,\" that is feature-first thinking. The execution system question is: what happens when a social login fails to create a profile, or when a password reset races with an account deletion request, or when a session expires mid-checkout?",[72,4096,4097],{},"Selling system design means the deliverable is not a list of working features. It is an execution system that happens to deliver those features as a byproduct. Clients who understand this are the ones who come back for follow-on work because the foundation does not need rewriting every six months.",[68,4099,4101],{"id":4100},"closing","Closing",[72,4103,4104],{},"I still ship features. The difference is that I no longer design them first. I design the execution system - the flow, the state machine, the task boundaries - and the features emerge from that foundation.",[72,4106,4107],{},"The billing project that took three times longer taught me that the code is never the bottleneck. The bottleneck is invisible structure. Every edge case that surprises you in production was already visible in the execution flow you did not draw. Every tangled refactoring session was baked in the moment you decided to build features instead of systems.",[72,4109,4110],{},"Design the execution system first. Your future self, debugging at 2 AM after a failed deployment, will not thank you. But you will have fewer of those 2 AM sessions to begin with.",[718,4112,4113],{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":81,"searchDepth":96,"depth":96,"links":4115},[4116,4117,4118,4123,4124,4125,4126,4127],{"id":1294,"depth":96,"text":1288},{"id":1306,"depth":96,"text":1307},{"id":1345,"depth":96,"text":1346,"children":4119},[4120,4121,4122],{"id":1349,"depth":102,"text":1350},{"id":1499,"depth":102,"text":1500},{"id":2528,"depth":102,"text":2529},{"id":3573,"depth":96,"text":3574},{"id":3936,"depth":96,"text":3937},{"id":4054,"depth":96,"text":4055},{"id":4087,"depth":96,"text":4088},{"id":4100,"depth":96,"text":4101},"2026-05-11","Feature-first development leads to technical debt. Designing execution systems first - flows, state, task decomposition - produces better software with less rework.",{"readingTime":4131},"11 min read","\u002Fblog\u002F39-execution-systems-first-not-features",{"title":1288,"description":4129},"AI Systems Engineering","Building production-grade AI systems that scale beyond demos",{"src":4137,"mime":742,"alt":4138,"width":744,"height":4139},"\u002Fimg\u002Fblog\u002F39-execution-systems-first-not-features\u002Fbanner.svg","Execution system architecture showing flow design, state management, and task decomposition layers",680,"blog\u002F39-execution-systems-first-not-features",[4142,4143,4144,749,748,4145],"Architecture","Software Design","Execution Systems","Development Practices","SXBdbszkV6tqDiQQzhPOkc2FqpppzH9VKOxMoDrItcw",{"id":4148,"title":4149,"abstract":734,"author":62,"authorUrl":734,"body":4150,"date":6967,"dateUpdated":6967,"description":6968,"excerpt":734,"extension":735,"featured":438,"headline":734,"image":734,"meta":6969,"navigation":438,"ogImage":734,"path":6971,"seo":6972,"series":6973,"seriesDescription":6974,"seriesOrder":89,"socialImage":6975,"stem":6978,"tags":6979,"__hash__":6983},"blog\u002Fblog\u002F30-ai-seo-developer-guide-2026.md","AI-Powered SEO in 2026: Complete Developer's Guide",{"type":65,"value":4151,"toc":6916},[4152,4155,4158,4162,4166,4169,4195,4199,4225,4229,4233,4458,4462,4770,4774,4994,4998,5002,5008,5144,5148,5153,5173,5177,5182,5273,5277,5281,5354,5358,5426,5430,5562,5566,5570,5678,5682,5875,5879,6095,6099,6103,6169,6173,6228,6232,6279,6283,6287,6359,6363,6477,6481,6538,6542,6546,6626,6630,6740,6744,6781,6785,6789,6809,6813,6833,6837,6857,6861,6865,6897,6899,6902,6905,6907,6913],[68,4153,4149],{"id":4154},"ai-powered-seo-in-2026-complete-developers-guide",[72,4156,4157],{},"SEO has fundamentally changed. In 2026, search engines use AI to understand content, and AI tools help optimize for search. This guide covers everything developers need to know about AI-powered SEO, from schema markup to Core Web Vitals optimization.",[68,4159,4161],{"id":4160},"the-new-seo-landscape-in-2026","The New SEO Landscape in 2026",[294,4163,4165],{"id":4164},"ai-search-engines","AI Search Engines",[72,4167,4168],{},"Modern search uses AI to understand intent:",[630,4170,4171,4177,4183,4189],{},[572,4172,4173,4176],{},[134,4174,4175],{},"Google SGE"," (Search Generative Experience)",[572,4178,4179,4182],{},[134,4180,4181],{},"Bing Chat"," with GPT-4",[572,4184,4185,4188],{},[134,4186,4187],{},"Perplexity"," AI search",[572,4190,4191,4194],{},[134,4192,4193],{},"You.com"," AI-powered results",[294,4196,4198],{"id":4197},"what-changed","What Changed?",[569,4200,4201,4207,4213,4219],{},[572,4202,4203,4206],{},[134,4204,4205],{},"Semantic Understanding",": AI understands context, not just keywords",[572,4208,4209,4212],{},[134,4210,4211],{},"Content Quality",": Depth and accuracy matter more than ever",[572,4214,4215,4218],{},[134,4216,4217],{},"User Experience",": Core Web Vitals are ranking factors",[572,4220,4221,4224],{},[134,4222,4223],{},"Structured Data",": Schema markup is essential for AI comprehension",[68,4226,4228],{"id":4227},"technical-seo-fundamentals","Technical SEO Fundamentals",[294,4230,4232],{"id":4231},"_1-server-side-rendering-ssr","1. Server-Side Rendering (SSR)",[76,4234,4236],{"className":831,"code":4235,"language":833,"meta":81,"style":81},"\u002F\u002F Nuxt 4 - Automatic SSR\nexport default defineNuxtComponent({\n  async setup() {\n    const { data: post } = await useFetch(\"\u002Fapi\u002Fblog\u002Fpost\")\n\n    \u002F\u002F SEO metadata\n    useSeoMeta({\n      title: () => `${post.value.title} | My Blog`,\n      description: post.value.excerpt,\n      ogTitle: post.value.title,\n      ogDescription: post.value.excerpt,\n      twitterCard: \"summary_large_image\",\n    })\n\n    return { post }\n  },\n})\n",[83,4237,4238,4243,4256,4267,4299,4303,4308,4317,4353,4373,4392,4411,4427,4434,4438,4448,4452],{"__ignoreMap":81},[86,4239,4240],{"class":88,"line":89},[86,4241,4242],{"class":92},"\u002F\u002F Nuxt 4 - Automatic SSR\n",[86,4244,4245,4247,4249,4252,4254],{"class":88,"line":96},[86,4246,845],{"class":152},[86,4248,848],{"class":152},[86,4250,4251],{"class":205}," defineNuxtComponent",[86,4253,243],{"class":156},[86,4255,180],{"class":163},[86,4257,4258,4260,4263,4265],{"class":88,"line":102},[86,4259,2630],{"class":185},[86,4261,4262],{"class":209}," setup",[86,4264,2560],{"class":163},[86,4266,865],{"class":163},[86,4268,4269,4271,4273,4275,4277,4280,4282,4284,4286,4288,4290,4292,4295,4297],{"class":88,"line":213},[86,4270,461],{"class":185},[86,4272,880],{"class":163},[86,4274,2571],{"class":209},[86,4276,643],{"class":163},[86,4278,4279],{"class":156}," post",[86,4281,2584],{"class":163},[86,4283,192],{"class":163},[86,4285,2722],{"class":152},[86,4287,2589],{"class":205},[86,4289,243],{"class":209},[86,4291,259],{"class":163},[86,4293,4294],{"class":255},"\u002Fapi\u002Fblog\u002Fpost",[86,4296,259],{"class":163},[86,4298,266],{"class":209},[86,4300,4301],{"class":88,"line":237},[86,4302,439],{"emptyLinePlaceholder":438},[86,4304,4305],{"class":88,"line":269},[86,4306,4307],{"class":92},"    \u002F\u002F SEO metadata\n",[86,4309,4310,4313,4315],{"class":88,"line":275},[86,4311,4312],{"class":205},"    useSeoMeta",[86,4314,243],{"class":209},[86,4316,180],{"class":163},[86,4318,4319,4322,4324,4326,4328,4331,4334,4336,4338,4340,4343,4345,4348,4351],{"class":88,"line":499},[86,4320,4321],{"class":205},"      title",[86,4323,643],{"class":163},[86,4325,2262],{"class":163},[86,4327,3816],{"class":185},[86,4329,4330],{"class":163}," `${",[86,4332,4333],{"class":156},"post",[86,4335,137],{"class":163},[86,4337,3127],{"class":156},[86,4339,137],{"class":163},[86,4341,4342],{"class":156},"title",[86,4344,990],{"class":163},[86,4346,4347],{"class":255}," | My Blog",[86,4349,4350],{"class":163},"`",[86,4352,947],{"class":163},[86,4354,4355,4358,4360,4362,4364,4366,4368,4371],{"class":88,"line":523},[86,4356,4357],{"class":209},"      description",[86,4359,643],{"class":163},[86,4361,4279],{"class":156},[86,4363,137],{"class":163},[86,4365,3127],{"class":156},[86,4367,137],{"class":163},[86,4369,4370],{"class":156},"excerpt",[86,4372,947],{"class":163},[86,4374,4375,4378,4380,4382,4384,4386,4388,4390],{"class":88,"line":529},[86,4376,4377],{"class":209},"      ogTitle",[86,4379,643],{"class":163},[86,4381,4279],{"class":156},[86,4383,137],{"class":163},[86,4385,3127],{"class":156},[86,4387,137],{"class":163},[86,4389,4342],{"class":156},[86,4391,947],{"class":163},[86,4393,4394,4397,4399,4401,4403,4405,4407,4409],{"class":88,"line":534},[86,4395,4396],{"class":209},"      ogDescription",[86,4398,643],{"class":163},[86,4400,4279],{"class":156},[86,4402,137],{"class":163},[86,4404,3127],{"class":156},[86,4406,137],{"class":163},[86,4408,4370],{"class":156},[86,4410,947],{"class":163},[86,4412,4413,4416,4418,4420,4423,4425],{"class":88,"line":1420},[86,4414,4415],{"class":209},"      twitterCard",[86,4417,643],{"class":163},[86,4419,252],{"class":163},[86,4421,4422],{"class":255},"summary_large_image",[86,4424,259],{"class":163},[86,4426,947],{"class":163},[86,4428,4429,4432],{"class":88,"line":1426},[86,4430,4431],{"class":163},"    }",[86,4433,266],{"class":209},[86,4435,4436],{"class":88,"line":1432},[86,4437,439],{"emptyLinePlaceholder":438},[86,4439,4440,4442,4444,4446],{"class":88,"line":1438},[86,4441,2841],{"class":152},[86,4443,880],{"class":163},[86,4445,4279],{"class":156},[86,4447,2872],{"class":163},[86,4449,4450],{"class":88,"line":1444},[86,4451,985],{"class":163},[86,4453,4454,4456],{"class":88,"line":1449},[86,4455,990],{"class":163},[86,4457,266],{"class":156},[294,4459,4461],{"id":4460},"_2-structured-data-with-schemaorg","2. Structured Data with Schema.org",[76,4463,4465],{"className":831,"code":4464,"language":833,"meta":81,"style":81},"\u002F\u002F app\u002Fpages\u002Fblog\u002F[slug].vue\n\u003Cscript setup lang=\"ts\">\nconst route = useRoute()\nconst { data: post } = await useFetch(`\u002Fapi\u002Fblog\u002F${route.params.slug}`)\n\n\u002F\u002F JSON-LD Schema\nuseSchemaOrg([\n  {\n    '@type': 'BlogPosting',\n    headline: post.value.title,\n    description: post.value.excerpt,\n    image: post.value.image,\n    datePublished: post.value.publishedAt,\n    dateModified: post.value.updatedAt,\n    author: {\n      '@type': 'Person',\n      name: post.value.author.name,\n    },\n  },\n])\n\u003C\u002Fscript>\n",[83,4466,4467,4472,4490,4504,4552,4556,4561,4569,4574,4595,4614,4633,4653,4673,4693,4702,4722,4747,4751,4755,4760],{"__ignoreMap":81},[86,4468,4469],{"class":88,"line":89},[86,4470,4471],{"class":92},"\u002F\u002F app\u002Fpages\u002Fblog\u002F[slug].vue\n",[86,4473,4474,4476,4479,4481,4483,4485,4487],{"class":88,"line":96},[86,4475,374],{"class":163},[86,4477,4478],{"class":156},"script setup lang",[86,4480,1602],{"class":163},[86,4482,259],{"class":163},[86,4484,80],{"class":255},[86,4486,259],{"class":163},[86,4488,4489],{"class":163},">\n",[86,4491,4492,4494,4497,4499,4502],{"class":88,"line":102},[86,4493,221],{"class":185},[86,4495,4496],{"class":156}," route ",[86,4498,1602],{"class":163},[86,4500,4501],{"class":205}," useRoute",[86,4503,210],{"class":156},[86,4505,4506,4508,4510,4512,4514,4517,4519,4521,4523,4525,4527,4529,4532,4535,4537,4539,4542,4544,4547,4550],{"class":88,"line":213},[86,4507,221],{"class":185},[86,4509,880],{"class":163},[86,4511,2571],{"class":209},[86,4513,643],{"class":163},[86,4515,4516],{"class":156}," post ",[86,4518,990],{"class":163},[86,4520,192],{"class":163},[86,4522,2722],{"class":152},[86,4524,2589],{"class":205},[86,4526,243],{"class":156},[86,4528,4350],{"class":163},[86,4530,4531],{"class":255},"\u002Fapi\u002Fblog\u002F",[86,4533,4534],{"class":163},"${",[86,4536,1777],{"class":156},[86,4538,137],{"class":163},[86,4540,4541],{"class":156},"params",[86,4543,137],{"class":163},[86,4545,4546],{"class":156},"slug",[86,4548,4549],{"class":163},"}`",[86,4551,266],{"class":156},[86,4553,4554],{"class":88,"line":237},[86,4555,439],{"emptyLinePlaceholder":438},[86,4557,4558],{"class":88,"line":269},[86,4559,4560],{"class":92},"\u002F\u002F JSON-LD Schema\n",[86,4562,4563,4566],{"class":88,"line":275},[86,4564,4565],{"class":205},"useSchemaOrg",[86,4567,4568],{"class":156},"([\n",[86,4570,4571],{"class":88,"line":499},[86,4572,4573],{"class":163},"  {\n",[86,4575,4576,4579,4582,4584,4586,4588,4591,4593],{"class":88,"line":523},[86,4577,4578],{"class":163},"    '",[86,4580,4581],{"class":209},"@type",[86,4583,1782],{"class":163},[86,4585,643],{"class":163},[86,4587,1847],{"class":163},[86,4589,4590],{"class":255},"BlogPosting",[86,4592,1782],{"class":163},[86,4594,947],{"class":163},[86,4596,4597,4600,4602,4604,4606,4608,4610,4612],{"class":88,"line":529},[86,4598,4599],{"class":209},"    headline",[86,4601,643],{"class":163},[86,4603,4279],{"class":156},[86,4605,137],{"class":163},[86,4607,3127],{"class":156},[86,4609,137],{"class":163},[86,4611,4342],{"class":156},[86,4613,947],{"class":163},[86,4615,4616,4619,4621,4623,4625,4627,4629,4631],{"class":88,"line":534},[86,4617,4618],{"class":209},"    description",[86,4620,643],{"class":163},[86,4622,4279],{"class":156},[86,4624,137],{"class":163},[86,4626,3127],{"class":156},[86,4628,137],{"class":163},[86,4630,4370],{"class":156},[86,4632,947],{"class":163},[86,4634,4635,4638,4640,4642,4644,4646,4648,4651],{"class":88,"line":1420},[86,4636,4637],{"class":209},"    image",[86,4639,643],{"class":163},[86,4641,4279],{"class":156},[86,4643,137],{"class":163},[86,4645,3127],{"class":156},[86,4647,137],{"class":163},[86,4649,4650],{"class":156},"image",[86,4652,947],{"class":163},[86,4654,4655,4658,4660,4662,4664,4666,4668,4671],{"class":88,"line":1426},[86,4656,4657],{"class":209},"    datePublished",[86,4659,643],{"class":163},[86,4661,4279],{"class":156},[86,4663,137],{"class":163},[86,4665,3127],{"class":156},[86,4667,137],{"class":163},[86,4669,4670],{"class":156},"publishedAt",[86,4672,947],{"class":163},[86,4674,4675,4678,4680,4682,4684,4686,4688,4691],{"class":88,"line":1432},[86,4676,4677],{"class":209},"    dateModified",[86,4679,643],{"class":163},[86,4681,4279],{"class":156},[86,4683,137],{"class":163},[86,4685,3127],{"class":156},[86,4687,137],{"class":163},[86,4689,4690],{"class":156},"updatedAt",[86,4692,947],{"class":163},[86,4694,4695,4698,4700],{"class":88,"line":1438},[86,4696,4697],{"class":209},"    author",[86,4699,643],{"class":163},[86,4701,865],{"class":163},[86,4703,4704,4707,4709,4711,4713,4715,4718,4720],{"class":88,"line":1444},[86,4705,4706],{"class":163},"      '",[86,4708,4581],{"class":209},[86,4710,1782],{"class":163},[86,4712,643],{"class":163},[86,4714,1847],{"class":163},[86,4716,4717],{"class":255},"Person",[86,4719,1782],{"class":163},[86,4721,947],{"class":163},[86,4723,4724,4727,4729,4731,4733,4735,4737,4740,4742,4745],{"class":88,"line":1449},[86,4725,4726],{"class":209},"      name",[86,4728,643],{"class":163},[86,4730,4279],{"class":156},[86,4732,137],{"class":163},[86,4734,3127],{"class":156},[86,4736,137],{"class":163},[86,4738,4739],{"class":156},"author",[86,4741,137],{"class":163},[86,4743,4744],{"class":156},"name",[86,4746,947],{"class":163},[86,4748,4749],{"class":88,"line":1455},[86,4750,980],{"class":163},[86,4752,4753],{"class":88,"line":1461},[86,4754,985],{"class":163},[86,4756,4757],{"class":88,"line":1467},[86,4758,4759],{"class":156},"])\n",[86,4761,4762,4765,4768],{"class":88,"line":1473},[86,4763,4764],{"class":163},"\u003C\u002F",[86,4766,4767],{"class":156},"script",[86,4769,4489],{"class":163},[294,4771,4773],{"id":4772},"_3-dynamic-sitemap-generation","3. Dynamic Sitemap Generation",[76,4775,4777],{"className":831,"code":4776,"language":833,"meta":81,"style":81},"\u002F\u002F app\u002Fpages\u002Fsitemap.xml.ts\nexport default defineEventHandler(async () => {\n  const posts = await queryCollection(\"blog\").all()\n\n  const sitemap = `\n    \u003Curlset xmlns=\"http:\u002F\u002Fwww.sitemaps.org\u002Fschemas\u002Fsitemap\u002F0.9\">\n      ${posts\n        .map(\n          (post) => `\n        \u003Curl>\n          \u003Cloc>https:\u002F\u002Fexample.com\u002Fblog\u002F${post.slug}\u003C\u002Floc>\n          \u003Clastmod>${post.updatedAt}\u003C\u002Flastmod>\n          \u003Cchangefreq>monthly\u003C\u002Fchangefreq>\n        \u003C\u002Furl>\n      `,\n        )\n        .join(\"\")}\n    \u003C\u002Furlset>\n  `\n\n  return sitemap\n})\n",[83,4778,4779,4784,4804,4836,4840,4852,4857,4865,4875,4888,4893,4911,4929,4934,4939,4946,4951,4967,4972,4977,4981,4988],{"__ignoreMap":81},[86,4780,4781],{"class":88,"line":89},[86,4782,4783],{"class":92},"\u002F\u002F app\u002Fpages\u002Fsitemap.xml.ts\n",[86,4785,4786,4788,4790,4793,4795,4798,4800,4802],{"class":88,"line":96},[86,4787,845],{"class":152},[86,4789,848],{"class":152},[86,4791,4792],{"class":205}," defineEventHandler",[86,4794,243],{"class":156},[86,4796,4797],{"class":185},"async",[86,4799,2262],{"class":163},[86,4801,3816],{"class":185},[86,4803,865],{"class":163},[86,4805,4806,4808,4811,4813,4815,4818,4820,4822,4825,4827,4829,4831,4834],{"class":88,"line":102},[86,4807,186],{"class":185},[86,4809,4810],{"class":156}," posts",[86,4812,192],{"class":163},[86,4814,2722],{"class":152},[86,4816,4817],{"class":205}," queryCollection",[86,4819,243],{"class":209},[86,4821,259],{"class":163},[86,4823,4824],{"class":255},"blog",[86,4826,259],{"class":163},[86,4828,1678],{"class":209},[86,4830,137],{"class":163},[86,4832,4833],{"class":205},"all",[86,4835,210],{"class":209},[86,4837,4838],{"class":88,"line":213},[86,4839,439],{"emptyLinePlaceholder":438},[86,4841,4842,4844,4847,4849],{"class":88,"line":237},[86,4843,186],{"class":185},[86,4845,4846],{"class":156}," sitemap",[86,4848,192],{"class":163},[86,4850,4851],{"class":163}," `\n",[86,4853,4854],{"class":88,"line":269},[86,4855,4856],{"class":255},"    \u003Curlset xmlns=\"http:\u002F\u002Fwww.sitemaps.org\u002Fschemas\u002Fsitemap\u002F0.9\">\n",[86,4858,4859,4862],{"class":88,"line":275},[86,4860,4861],{"class":163},"      ${",[86,4863,4864],{"class":156},"posts\n",[86,4866,4867,4870,4873],{"class":88,"line":499},[86,4868,4869],{"class":163},"        .",[86,4871,4872],{"class":205},"map",[86,4874,1957],{"class":156},[86,4876,4877,4880,4882,4884,4886],{"class":88,"line":523},[86,4878,4879],{"class":163},"          (",[86,4881,4333],{"class":2640},[86,4883,1678],{"class":163},[86,4885,3816],{"class":185},[86,4887,4851],{"class":163},[86,4889,4890],{"class":88,"line":529},[86,4891,4892],{"class":255},"        \u003Curl>\n",[86,4894,4895,4898,4900,4902,4904,4906,4908],{"class":88,"line":534},[86,4896,4897],{"class":255},"          \u003Cloc>https:\u002F\u002Fexample.com\u002Fblog\u002F",[86,4899,4534],{"class":163},[86,4901,4333],{"class":156},[86,4903,137],{"class":163},[86,4905,4546],{"class":156},[86,4907,990],{"class":163},[86,4909,4910],{"class":255},"\u003C\u002Floc>\n",[86,4912,4913,4916,4918,4920,4922,4924,4926],{"class":88,"line":1420},[86,4914,4915],{"class":255},"          \u003Clastmod>",[86,4917,4534],{"class":163},[86,4919,4333],{"class":156},[86,4921,137],{"class":163},[86,4923,4690],{"class":156},[86,4925,990],{"class":163},[86,4927,4928],{"class":255},"\u003C\u002Flastmod>\n",[86,4930,4931],{"class":88,"line":1426},[86,4932,4933],{"class":255},"          \u003Cchangefreq>monthly\u003C\u002Fchangefreq>\n",[86,4935,4936],{"class":88,"line":1432},[86,4937,4938],{"class":255},"        \u003C\u002Furl>\n",[86,4940,4941,4944],{"class":88,"line":1438},[86,4942,4943],{"class":163},"      `",[86,4945,947],{"class":163},[86,4947,4948],{"class":88,"line":1444},[86,4949,4950],{"class":156},"        )\n",[86,4952,4953,4955,4958,4960,4963,4965],{"class":88,"line":1449},[86,4954,4869],{"class":163},[86,4956,4957],{"class":205},"join",[86,4959,243],{"class":156},[86,4961,4962],{"class":163},"\"\"",[86,4964,1678],{"class":156},[86,4966,278],{"class":163},[86,4968,4969],{"class":88,"line":1455},[86,4970,4971],{"class":255},"    \u003C\u002Furlset>\n",[86,4973,4974],{"class":88,"line":1461},[86,4975,4976],{"class":163},"  `\n",[86,4978,4979],{"class":88,"line":1467},[86,4980,439],{"emptyLinePlaceholder":438},[86,4982,4983,4985],{"class":88,"line":1473},[86,4984,2857],{"class":152},[86,4986,4987],{"class":156}," sitemap\n",[86,4989,4990,4992],{"class":88,"line":1478},[86,4991,990],{"class":163},[86,4993,266],{"class":156},[68,4995,4997],{"id":4996},"core-web-vitals-optimization","Core Web Vitals Optimization",[294,4999,5001],{"id":5000},"_1-largest-contentful-paint-lcp","1. Largest Contentful Paint (LCP)",[72,5003,5004,5007],{},[134,5005,5006],{},"Target",": \u003C 2.5 seconds",[76,5009,5013],{"className":5010,"code":5011,"language":5012,"meta":81,"style":81},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C!-- Optimize images -->\n\u003Ctemplate>\n  \u003CNuxtImg\n    src=\"\u002Fhero-image.jpg\"\n    alt=\"Hero\"\n    width=\"1200\"\n    height=\"630\"\n    format=\"webp\"\n    quality=\"80\"\n    preload\n    priority\n  \u002F>\n\u003C\u002Ftemplate>\n","vue",[83,5014,5015,5020,5029,5037,5051,5065,5079,5093,5107,5121,5126,5131,5136],{"__ignoreMap":81},[86,5016,5017],{"class":88,"line":89},[86,5018,5019],{"class":92},"\u003C!-- Optimize images -->\n",[86,5021,5022,5024,5027],{"class":88,"line":96},[86,5023,374],{"class":163},[86,5025,5026],{"class":209},"template",[86,5028,4489],{"class":163},[86,5030,5031,5034],{"class":88,"line":102},[86,5032,5033],{"class":163},"  \u003C",[86,5035,5036],{"class":209},"NuxtImg\n",[86,5038,5039,5042,5044,5046,5049],{"class":88,"line":213},[86,5040,5041],{"class":185},"    src",[86,5043,1602],{"class":163},[86,5045,259],{"class":163},[86,5047,5048],{"class":255},"\u002Fhero-image.jpg",[86,5050,3153],{"class":163},[86,5052,5053,5056,5058,5060,5063],{"class":88,"line":237},[86,5054,5055],{"class":185},"    alt",[86,5057,1602],{"class":163},[86,5059,259],{"class":163},[86,5061,5062],{"class":255},"Hero",[86,5064,3153],{"class":163},[86,5066,5067,5070,5072,5074,5077],{"class":88,"line":269},[86,5068,5069],{"class":185},"    width",[86,5071,1602],{"class":163},[86,5073,259],{"class":163},[86,5075,5076],{"class":255},"1200",[86,5078,3153],{"class":163},[86,5080,5081,5084,5086,5088,5091],{"class":88,"line":275},[86,5082,5083],{"class":185},"    height",[86,5085,1602],{"class":163},[86,5087,259],{"class":163},[86,5089,5090],{"class":255},"630",[86,5092,3153],{"class":163},[86,5094,5095,5098,5100,5102,5105],{"class":88,"line":499},[86,5096,5097],{"class":185},"    format",[86,5099,1602],{"class":163},[86,5101,259],{"class":163},[86,5103,5104],{"class":255},"webp",[86,5106,3153],{"class":163},[86,5108,5109,5112,5114,5116,5119],{"class":88,"line":523},[86,5110,5111],{"class":185},"    quality",[86,5113,1602],{"class":163},[86,5115,259],{"class":163},[86,5117,5118],{"class":255},"80",[86,5120,3153],{"class":163},[86,5122,5123],{"class":88,"line":529},[86,5124,5125],{"class":185},"    preload\n",[86,5127,5128],{"class":88,"line":534},[86,5129,5130],{"class":185},"    priority\n",[86,5132,5133],{"class":88,"line":1420},[86,5134,5135],{"class":163},"  \u002F>\n",[86,5137,5138,5140,5142],{"class":88,"line":1426},[86,5139,4764],{"class":163},[86,5141,5026],{"class":209},[86,5143,4489],{"class":163},[294,5145,5147],{"id":5146},"_2-first-input-delay-fid","2. First Input Delay (FID)",[72,5149,5150,5152],{},[134,5151,5006],{},": \u003C 100 milliseconds",[76,5154,5156],{"className":831,"code":5155,"language":833,"meta":81,"style":81},"\u002F\u002F Minimize JavaScript\n\u002F\u002F Use web workers for heavy computation\n\u002F\u002F Implement code splitting\n",[83,5157,5158,5163,5168],{"__ignoreMap":81},[86,5159,5160],{"class":88,"line":89},[86,5161,5162],{"class":92},"\u002F\u002F Minimize JavaScript\n",[86,5164,5165],{"class":88,"line":96},[86,5166,5167],{"class":92},"\u002F\u002F Use web workers for heavy computation\n",[86,5169,5170],{"class":88,"line":102},[86,5171,5172],{"class":92},"\u002F\u002F Implement code splitting\n",[294,5174,5176],{"id":5175},"_3-cumulative-layout-shift-cls","3. Cumulative Layout Shift (CLS)",[72,5178,5179,5181],{},[134,5180,5006],{},": \u003C 0.1",[76,5183,5185],{"className":5010,"code":5184,"language":5012,"meta":81,"style":81},"\u003C!-- Reserve space for images -->\n\u003Ctemplate>\n  \u003Cdiv class=\"aspect-w-16 aspect-h-9\">\n    \u003Cimg src=\"image.jpg\" alt=\"Description\" \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[83,5186,5187,5192,5200,5221,5256,5265],{"__ignoreMap":81},[86,5188,5189],{"class":88,"line":89},[86,5190,5191],{"class":92},"\u003C!-- Reserve space for images -->\n",[86,5193,5194,5196,5198],{"class":88,"line":96},[86,5195,374],{"class":163},[86,5197,5026],{"class":209},[86,5199,4489],{"class":163},[86,5201,5202,5204,5207,5210,5212,5214,5217,5219],{"class":88,"line":102},[86,5203,5033],{"class":163},[86,5205,5206],{"class":209},"div",[86,5208,5209],{"class":185}," class",[86,5211,1602],{"class":163},[86,5213,259],{"class":163},[86,5215,5216],{"class":255},"aspect-w-16 aspect-h-9",[86,5218,259],{"class":163},[86,5220,4489],{"class":163},[86,5222,5223,5226,5229,5232,5234,5236,5239,5241,5244,5246,5248,5251,5253],{"class":88,"line":213},[86,5224,5225],{"class":163},"    \u003C",[86,5227,5228],{"class":209},"img",[86,5230,5231],{"class":185}," src",[86,5233,1602],{"class":163},[86,5235,259],{"class":163},[86,5237,5238],{"class":255},"image.jpg",[86,5240,259],{"class":163},[86,5242,5243],{"class":185}," alt",[86,5245,1602],{"class":163},[86,5247,259],{"class":163},[86,5249,5250],{"class":255},"Description",[86,5252,259],{"class":163},[86,5254,5255],{"class":163}," \u002F>\n",[86,5257,5258,5261,5263],{"class":88,"line":237},[86,5259,5260],{"class":163},"  \u003C\u002F",[86,5262,5206],{"class":209},[86,5264,4489],{"class":163},[86,5266,5267,5269,5271],{"class":88,"line":269},[86,5268,4764],{"class":163},[86,5270,5026],{"class":209},[86,5272,4489],{"class":163},[68,5274,5276],{"id":5275},"ai-content-optimization","AI Content Optimization",[294,5278,5280],{"id":5279},"_1-semantic-keyword-research","1. Semantic Keyword Research",[76,5282,5284],{"className":831,"code":5283,"language":833,"meta":81,"style":81},"\u002F\u002F Use AI for keyword clustering\nconst keywords = await aiClusterKeywords([\n  \"web development\",\n  \"frontend frameworks\",\n  \"JavaScript tutorials\",\n])\n\n\u002F\u002F Returns related terms and search intent\n",[83,5285,5286,5291,5307,5319,5330,5341,5345,5349],{"__ignoreMap":81},[86,5287,5288],{"class":88,"line":89},[86,5289,5290],{"class":92},"\u002F\u002F Use AI for keyword clustering\n",[86,5292,5293,5295,5298,5300,5302,5305],{"class":88,"line":96},[86,5294,221],{"class":185},[86,5296,5297],{"class":156}," keywords ",[86,5299,1602],{"class":163},[86,5301,2722],{"class":152},[86,5303,5304],{"class":205}," aiClusterKeywords",[86,5306,4568],{"class":156},[86,5308,5309,5312,5315,5317],{"class":88,"line":102},[86,5310,5311],{"class":163},"  \"",[86,5313,5314],{"class":255},"web development",[86,5316,259],{"class":163},[86,5318,947],{"class":163},[86,5320,5321,5323,5326,5328],{"class":88,"line":213},[86,5322,5311],{"class":163},[86,5324,5325],{"class":255},"frontend frameworks",[86,5327,259],{"class":163},[86,5329,947],{"class":163},[86,5331,5332,5334,5337,5339],{"class":88,"line":237},[86,5333,5311],{"class":163},[86,5335,5336],{"class":255},"JavaScript tutorials",[86,5338,259],{"class":163},[86,5340,947],{"class":163},[86,5342,5343],{"class":88,"line":269},[86,5344,4759],{"class":156},[86,5346,5347],{"class":88,"line":275},[86,5348,439],{"emptyLinePlaceholder":438},[86,5350,5351],{"class":88,"line":499},[86,5352,5353],{"class":92},"\u002F\u002F Returns related terms and search intent\n",[294,5355,5357],{"id":5356},"_2-content-structure","2. Content Structure",[76,5359,5363],{"className":5360,"code":5361,"language":5362,"meta":81,"style":81},"language-markdown shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# H1: Main Topic (include primary keyword)\n\n## H2: Key Subtopics\n\n- Cover related concepts\n- Answer common questions\n- Include semantic keywords\n\n### H3: Detailed Points\n\n- Provide examples\n- Add code snippets\n- Include data and statistics\n","markdown",[83,5364,5365,5370,5374,5379,5383,5388,5393,5398,5402,5407,5411,5416,5421],{"__ignoreMap":81},[86,5366,5367],{"class":88,"line":89},[86,5368,5369],{},"# H1: Main Topic (include primary keyword)\n",[86,5371,5372],{"class":88,"line":96},[86,5373,439],{"emptyLinePlaceholder":438},[86,5375,5376],{"class":88,"line":102},[86,5377,5378],{},"## H2: Key Subtopics\n",[86,5380,5381],{"class":88,"line":213},[86,5382,439],{"emptyLinePlaceholder":438},[86,5384,5385],{"class":88,"line":237},[86,5386,5387],{},"- Cover related concepts\n",[86,5389,5390],{"class":88,"line":269},[86,5391,5392],{},"- Answer common questions\n",[86,5394,5395],{"class":88,"line":275},[86,5396,5397],{},"- Include semantic keywords\n",[86,5399,5400],{"class":88,"line":499},[86,5401,439],{"emptyLinePlaceholder":438},[86,5403,5404],{"class":88,"line":523},[86,5405,5406],{},"### H3: Detailed Points\n",[86,5408,5409],{"class":88,"line":529},[86,5410,439],{"emptyLinePlaceholder":438},[86,5412,5413],{"class":88,"line":534},[86,5414,5415],{},"- Provide examples\n",[86,5417,5418],{"class":88,"line":1420},[86,5419,5420],{},"- Add code snippets\n",[86,5422,5423],{"class":88,"line":1426},[86,5424,5425],{},"- Include data and statistics\n",[294,5427,5429],{"id":5428},"_3-ai-generated-meta-descriptions","3. AI-Generated Meta Descriptions",[76,5431,5433],{"className":831,"code":5432,"language":833,"meta":81,"style":81},"import { generateMetaDescription } from \"@\u002Flib\u002Fai-seo\"\n\nconst metaDescription = await generateMetaDescription({\n  title: \"Complete Guide to Web Development\",\n  content: articleContent,\n  keywords: [\"web development\", \"frontend\", \"backend\"],\n  maxLength: 160,\n})\n",[83,5434,5435,5456,5460,5477,5493,5505,5544,5556],{"__ignoreMap":81},[86,5436,5437,5439,5441,5444,5446,5449,5451,5454],{"class":88,"line":89},[86,5438,160],{"class":152},[86,5440,880],{"class":163},[86,5442,5443],{"class":156}," generateMetaDescription",[86,5445,2584],{"class":163},[86,5447,5448],{"class":152}," from",[86,5450,252],{"class":163},[86,5452,5453],{"class":255},"@\u002Flib\u002Fai-seo",[86,5455,3153],{"class":163},[86,5457,5458],{"class":88,"line":96},[86,5459,439],{"emptyLinePlaceholder":438},[86,5461,5462,5464,5467,5469,5471,5473,5475],{"class":88,"line":102},[86,5463,221],{"class":185},[86,5465,5466],{"class":156}," metaDescription ",[86,5468,1602],{"class":163},[86,5470,2722],{"class":152},[86,5472,5443],{"class":205},[86,5474,243],{"class":156},[86,5476,180],{"class":163},[86,5478,5479,5482,5484,5486,5489,5491],{"class":88,"line":213},[86,5480,5481],{"class":209},"  title",[86,5483,643],{"class":163},[86,5485,252],{"class":163},[86,5487,5488],{"class":255},"Complete Guide to Web Development",[86,5490,259],{"class":163},[86,5492,947],{"class":163},[86,5494,5495,5498,5500,5503],{"class":88,"line":237},[86,5496,5497],{"class":209},"  content",[86,5499,643],{"class":163},[86,5501,5502],{"class":156}," articleContent",[86,5504,947],{"class":163},[86,5506,5507,5510,5512,5515,5517,5519,5521,5523,5525,5528,5530,5532,5534,5537,5539,5542],{"class":88,"line":269},[86,5508,5509],{"class":209},"  keywords",[86,5511,643],{"class":163},[86,5513,5514],{"class":156}," [",[86,5516,259],{"class":163},[86,5518,5314],{"class":255},[86,5520,259],{"class":163},[86,5522,249],{"class":163},[86,5524,252],{"class":163},[86,5526,5527],{"class":255},"frontend",[86,5529,259],{"class":163},[86,5531,249],{"class":163},[86,5533,252],{"class":163},[86,5535,5536],{"class":255},"backend",[86,5538,259],{"class":163},[86,5540,5541],{"class":156},"]",[86,5543,947],{"class":163},[86,5545,5546,5549,5551,5554],{"class":88,"line":275},[86,5547,5548],{"class":209},"  maxLength",[86,5550,643],{"class":163},[86,5552,5553],{"class":888}," 160",[86,5555,947],{"class":163},[86,5557,5558,5560],{"class":88,"line":499},[86,5559,990],{"class":163},[86,5561,266],{"class":156},[68,5563,5565],{"id":5564},"advanced-seo-techniques","Advanced SEO Techniques",[294,5567,5569],{"id":5568},"_1-edge-caching-for-seo","1. Edge Caching for SEO",[76,5571,5573],{"className":831,"code":5572,"language":833,"meta":81,"style":81},"\u002F\u002F nuxt.config.ts\nexport default defineNuxtConfig({\n  routeRules: {\n    \"\u002Fblog\u002F**\": {\n      isr: 3600, \u002F\u002F Revalidate every hour\n      cache: {\n        maxAge: 3600,\n        staleWhileRevalidate: 7200,\n      },\n    },\n  },\n})\n",[83,5574,5575,5580,5592,5600,5612,5627,5636,5647,5659,5664,5668,5672],{"__ignoreMap":81},[86,5576,5577],{"class":88,"line":89},[86,5578,5579],{"class":92},"\u002F\u002F nuxt.config.ts\n",[86,5581,5582,5584,5586,5588,5590],{"class":88,"line":96},[86,5583,845],{"class":152},[86,5585,848],{"class":152},[86,5587,851],{"class":205},[86,5589,243],{"class":156},[86,5591,180],{"class":163},[86,5593,5594,5596,5598],{"class":88,"line":102},[86,5595,860],{"class":209},[86,5597,643],{"class":163},[86,5599,865],{"class":163},[86,5601,5602,5604,5606,5608,5610],{"class":88,"line":213},[86,5603,870],{"class":163},[86,5605,873],{"class":209},[86,5607,259],{"class":163},[86,5609,643],{"class":163},[86,5611,865],{"class":163},[86,5613,5614,5617,5619,5622,5624],{"class":88,"line":237},[86,5615,5616],{"class":209},"      isr",[86,5618,643],{"class":163},[86,5620,5621],{"class":888}," 3600",[86,5623,249],{"class":163},[86,5625,5626],{"class":92}," \u002F\u002F Revalidate every hour\n",[86,5628,5629,5632,5634],{"class":88,"line":269},[86,5630,5631],{"class":209},"      cache",[86,5633,643],{"class":163},[86,5635,865],{"class":163},[86,5637,5638,5641,5643,5645],{"class":88,"line":275},[86,5639,5640],{"class":209},"        maxAge",[86,5642,643],{"class":163},[86,5644,5621],{"class":888},[86,5646,947],{"class":163},[86,5648,5649,5652,5654,5657],{"class":88,"line":499},[86,5650,5651],{"class":209},"        staleWhileRevalidate",[86,5653,643],{"class":163},[86,5655,5656],{"class":888}," 7200",[86,5658,947],{"class":163},[86,5660,5661],{"class":88,"line":523},[86,5662,5663],{"class":163},"      },\n",[86,5665,5666],{"class":88,"line":529},[86,5667,980],{"class":163},[86,5669,5670],{"class":88,"line":534},[86,5671,985],{"class":163},[86,5673,5674,5676],{"class":88,"line":1420},[86,5675,990],{"class":163},[86,5677,266],{"class":156},[294,5679,5681],{"id":5680},"_2-internationalization-i18n","2. Internationalization (i18n)",[76,5683,5685],{"className":5010,"code":5684,"language":5012,"meta":81,"style":81},"\u003C!-- Multi-language SEO -->\n\u003Cscript setup>\nuseSeoMeta({\n  title: \"My Blog\",\n  htmlAttrs: {\n    lang: \"en\",\n  },\n  link: [\n    { rel: \"alternate\", hreflang: \"es\", href: \"\u002Fes\u002Fblog\" },\n    { rel: \"alternate\", hreflang: \"fr\", href: \"\u002Ffr\u002Fblog\" },\n  ],\n})\n\u003C\u002Fscript>\n",[83,5686,5687,5692,5702,5711,5726,5735,5751,5755,5765,5812,5854,5861,5867],{"__ignoreMap":81},[86,5688,5689],{"class":88,"line":89},[86,5690,5691],{"class":92},"\u003C!-- Multi-language SEO -->\n",[86,5693,5694,5696,5698,5700],{"class":88,"line":96},[86,5695,374],{"class":163},[86,5697,4767],{"class":209},[86,5699,4262],{"class":185},[86,5701,4489],{"class":163},[86,5703,5704,5707,5709],{"class":88,"line":102},[86,5705,5706],{"class":205},"useSeoMeta",[86,5708,243],{"class":156},[86,5710,180],{"class":163},[86,5712,5713,5715,5717,5719,5722,5724],{"class":88,"line":213},[86,5714,5481],{"class":209},[86,5716,643],{"class":163},[86,5718,252],{"class":163},[86,5720,5721],{"class":255},"My Blog",[86,5723,259],{"class":163},[86,5725,947],{"class":163},[86,5727,5728,5731,5733],{"class":88,"line":237},[86,5729,5730],{"class":209},"  htmlAttrs",[86,5732,643],{"class":163},[86,5734,865],{"class":163},[86,5736,5737,5740,5742,5744,5747,5749],{"class":88,"line":269},[86,5738,5739],{"class":209},"    lang",[86,5741,643],{"class":163},[86,5743,252],{"class":163},[86,5745,5746],{"class":255},"en",[86,5748,259],{"class":163},[86,5750,947],{"class":163},[86,5752,5753],{"class":88,"line":275},[86,5754,985],{"class":163},[86,5756,5757,5760,5762],{"class":88,"line":499},[86,5758,5759],{"class":209},"  link",[86,5761,643],{"class":163},[86,5763,5764],{"class":156}," [\n",[86,5766,5767,5770,5773,5775,5777,5780,5782,5784,5787,5789,5791,5794,5796,5798,5801,5803,5805,5808,5810],{"class":88,"line":523},[86,5768,5769],{"class":163},"    {",[86,5771,5772],{"class":209}," rel",[86,5774,643],{"class":163},[86,5776,252],{"class":163},[86,5778,5779],{"class":255},"alternate",[86,5781,259],{"class":163},[86,5783,249],{"class":163},[86,5785,5786],{"class":209}," hreflang",[86,5788,643],{"class":163},[86,5790,252],{"class":163},[86,5792,5793],{"class":255},"es",[86,5795,259],{"class":163},[86,5797,249],{"class":163},[86,5799,5800],{"class":209}," href",[86,5802,643],{"class":163},[86,5804,252],{"class":163},[86,5806,5807],{"class":255},"\u002Fes\u002Fblog",[86,5809,259],{"class":163},[86,5811,975],{"class":163},[86,5813,5814,5816,5818,5820,5822,5824,5826,5828,5830,5832,5834,5837,5839,5841,5843,5845,5847,5850,5852],{"class":88,"line":529},[86,5815,5769],{"class":163},[86,5817,5772],{"class":209},[86,5819,643],{"class":163},[86,5821,252],{"class":163},[86,5823,5779],{"class":255},[86,5825,259],{"class":163},[86,5827,249],{"class":163},[86,5829,5786],{"class":209},[86,5831,643],{"class":163},[86,5833,252],{"class":163},[86,5835,5836],{"class":255},"fr",[86,5838,259],{"class":163},[86,5840,249],{"class":163},[86,5842,5800],{"class":209},[86,5844,643],{"class":163},[86,5846,252],{"class":163},[86,5848,5849],{"class":255},"\u002Ffr\u002Fblog",[86,5851,259],{"class":163},[86,5853,975],{"class":163},[86,5855,5856,5859],{"class":88,"line":534},[86,5857,5858],{"class":156},"  ]",[86,5860,947],{"class":163},[86,5862,5863,5865],{"class":88,"line":1420},[86,5864,990],{"class":163},[86,5866,266],{"class":156},[86,5868,5869,5871,5873],{"class":88,"line":1426},[86,5870,4764],{"class":163},[86,5872,4767],{"class":209},[86,5874,4489],{"class":163},[294,5876,5878],{"id":5877},"_3-breadcrumb-navigation","3. Breadcrumb Navigation",[76,5880,5882],{"className":5010,"code":5881,"language":5012,"meta":81,"style":81},"\u003Cscript setup>\nuseSchemaOrg([\n  {\n    \"@type\": \"BreadcrumbList\",\n    itemListElement: [\n      {\n        \"@type\": \"ListItem\",\n        position: 1,\n        name: \"Home\",\n        item: \"https:\u002F\u002Fexample.com\u002F\",\n      },\n      {\n        \"@type\": \"ListItem\",\n        position: 2,\n        name: \"Blog\",\n        item: \"https:\u002F\u002Fexample.com\u002Fblog\",\n      },\n    ],\n  },\n])\n\u003C\u002Fscript>\n",[83,5883,5884,5894,5900,5904,5923,5932,5937,5957,5969,5985,6001,6005,6009,6027,6038,6053,6068,6072,6079,6083,6087],{"__ignoreMap":81},[86,5885,5886,5888,5890,5892],{"class":88,"line":89},[86,5887,374],{"class":163},[86,5889,4767],{"class":209},[86,5891,4262],{"class":185},[86,5893,4489],{"class":163},[86,5895,5896,5898],{"class":88,"line":96},[86,5897,4565],{"class":205},[86,5899,4568],{"class":156},[86,5901,5902],{"class":88,"line":102},[86,5903,4573],{"class":163},[86,5905,5906,5908,5910,5912,5914,5916,5919,5921],{"class":88,"line":213},[86,5907,870],{"class":163},[86,5909,4581],{"class":209},[86,5911,259],{"class":163},[86,5913,643],{"class":163},[86,5915,252],{"class":163},[86,5917,5918],{"class":255},"BreadcrumbList",[86,5920,259],{"class":163},[86,5922,947],{"class":163},[86,5924,5925,5928,5930],{"class":88,"line":237},[86,5926,5927],{"class":209},"    itemListElement",[86,5929,643],{"class":163},[86,5931,5764],{"class":156},[86,5933,5934],{"class":88,"line":269},[86,5935,5936],{"class":163},"      {\n",[86,5938,5939,5942,5944,5946,5948,5950,5953,5955],{"class":88,"line":275},[86,5940,5941],{"class":163},"        \"",[86,5943,4581],{"class":209},[86,5945,259],{"class":163},[86,5947,643],{"class":163},[86,5949,252],{"class":163},[86,5951,5952],{"class":255},"ListItem",[86,5954,259],{"class":163},[86,5956,947],{"class":163},[86,5958,5959,5962,5964,5967],{"class":88,"line":499},[86,5960,5961],{"class":209},"        position",[86,5963,643],{"class":163},[86,5965,5966],{"class":888}," 1",[86,5968,947],{"class":163},[86,5970,5971,5974,5976,5978,5981,5983],{"class":88,"line":523},[86,5972,5973],{"class":209},"        name",[86,5975,643],{"class":163},[86,5977,252],{"class":163},[86,5979,5980],{"class":255},"Home",[86,5982,259],{"class":163},[86,5984,947],{"class":163},[86,5986,5987,5990,5992,5994,5997,5999],{"class":88,"line":529},[86,5988,5989],{"class":209},"        item",[86,5991,643],{"class":163},[86,5993,252],{"class":163},[86,5995,5996],{"class":255},"https:\u002F\u002Fexample.com\u002F",[86,5998,259],{"class":163},[86,6000,947],{"class":163},[86,6002,6003],{"class":88,"line":534},[86,6004,5663],{"class":163},[86,6006,6007],{"class":88,"line":1420},[86,6008,5936],{"class":163},[86,6010,6011,6013,6015,6017,6019,6021,6023,6025],{"class":88,"line":1426},[86,6012,5941],{"class":163},[86,6014,4581],{"class":209},[86,6016,259],{"class":163},[86,6018,643],{"class":163},[86,6020,252],{"class":163},[86,6022,5952],{"class":255},[86,6024,259],{"class":163},[86,6026,947],{"class":163},[86,6028,6029,6031,6033,6036],{"class":88,"line":1432},[86,6030,5961],{"class":209},[86,6032,643],{"class":163},[86,6034,6035],{"class":888}," 2",[86,6037,947],{"class":163},[86,6039,6040,6042,6044,6046,6049,6051],{"class":88,"line":1438},[86,6041,5973],{"class":209},[86,6043,643],{"class":163},[86,6045,252],{"class":163},[86,6047,6048],{"class":255},"Blog",[86,6050,259],{"class":163},[86,6052,947],{"class":163},[86,6054,6055,6057,6059,6061,6064,6066],{"class":88,"line":1444},[86,6056,5989],{"class":209},[86,6058,643],{"class":163},[86,6060,252],{"class":163},[86,6062,6063],{"class":255},"https:\u002F\u002Fexample.com\u002Fblog",[86,6065,259],{"class":163},[86,6067,947],{"class":163},[86,6069,6070],{"class":88,"line":1449},[86,6071,5663],{"class":163},[86,6073,6074,6077],{"class":88,"line":1455},[86,6075,6076],{"class":156},"    ]",[86,6078,947],{"class":163},[86,6080,6081],{"class":88,"line":1461},[86,6082,985],{"class":163},[86,6084,6085],{"class":88,"line":1467},[86,6086,4759],{"class":156},[86,6088,6089,6091,6093],{"class":88,"line":1473},[86,6090,4764],{"class":163},[86,6092,4767],{"class":209},[86,6094,4489],{"class":163},[68,6096,6098],{"id":6097},"mobile-first-seo","Mobile-First SEO",[294,6100,6102],{"id":6101},"_1-responsive-design","1. Responsive Design",[76,6104,6108],{"className":6105,"code":6106,"language":6107,"meta":81,"style":81},"language-css shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u002F* Mobile-first approach *\u002F\n.container {\n  @apply px-4 sm:px-6 lg:px-8;\n}\n\n.text {\n  @apply text-base sm:text-lg lg:text-xl;\n}\n","css",[83,6109,6110,6115,6124,6136,6140,6144,6153,6165],{"__ignoreMap":81},[86,6111,6112],{"class":88,"line":89},[86,6113,6114],{"class":92},"\u002F* Mobile-first approach *\u002F\n",[86,6116,6117,6119,6122],{"class":88,"line":96},[86,6118,137],{"class":163},[86,6120,6121],{"class":370},"container",[86,6123,865],{"class":163},[86,6125,6126,6129,6131,6134],{"class":88,"line":102},[86,6127,6128],{"class":156},"  @apply px-4 sm",[86,6130,643],{"class":163},[86,6132,6133],{"class":156},"px-6 lg:px-8",[86,6135,1614],{"class":163},[86,6137,6138],{"class":88,"line":213},[86,6139,278],{"class":163},[86,6141,6142],{"class":88,"line":237},[86,6143,439],{"emptyLinePlaceholder":438},[86,6145,6146,6148,6151],{"class":88,"line":269},[86,6147,137],{"class":163},[86,6149,6150],{"class":370},"text",[86,6152,865],{"class":163},[86,6154,6155,6158,6160,6163],{"class":88,"line":275},[86,6156,6157],{"class":156},"  @apply text-base sm",[86,6159,643],{"class":163},[86,6161,6162],{"class":156},"text-lg lg:text-xl",[86,6164,1614],{"class":163},[86,6166,6167],{"class":88,"line":499},[86,6168,278],{"class":163},[294,6170,6172],{"id":6171},"_2-touch-targets","2. Touch Targets",[76,6174,6176],{"className":5010,"code":6175,"language":5012,"meta":81,"style":81},"\u003Ctemplate>\n  \u003C!-- Minimum 44x44px touch targets -->\n  \u003Cbutton class=\"min-h-[44px] min-w-[44px] p-4\">Click Me\u003C\u002Fbutton>\n\u003C\u002Ftemplate>\n",[83,6177,6178,6186,6191,6220],{"__ignoreMap":81},[86,6179,6180,6182,6184],{"class":88,"line":89},[86,6181,374],{"class":163},[86,6183,5026],{"class":209},[86,6185,4489],{"class":163},[86,6187,6188],{"class":88,"line":96},[86,6189,6190],{"class":92},"  \u003C!-- Minimum 44x44px touch targets -->\n",[86,6192,6193,6195,6198,6200,6202,6204,6207,6209,6211,6214,6216,6218],{"class":88,"line":102},[86,6194,5033],{"class":163},[86,6196,6197],{"class":209},"button",[86,6199,5209],{"class":185},[86,6201,1602],{"class":163},[86,6203,259],{"class":163},[86,6205,6206],{"class":255},"min-h-[44px] min-w-[44px] p-4",[86,6208,259],{"class":163},[86,6210,385],{"class":163},[86,6212,6213],{"class":156},"Click Me",[86,6215,4764],{"class":163},[86,6217,6197],{"class":209},[86,6219,4489],{"class":163},[86,6221,6222,6224,6226],{"class":88,"line":213},[86,6223,4764],{"class":163},[86,6225,5026],{"class":209},[86,6227,4489],{"class":163},[294,6229,6231],{"id":6230},"_3-mobile-performance","3. Mobile Performance",[76,6233,6235],{"className":831,"code":6234,"language":833,"meta":81,"style":81},"\u002F\u002F Lazy load non-critical resources\nconst loadOnInteraction = () => {\n  return import(\".\u002Fheavy-component.vue\")\n}\n",[83,6236,6237,6242,6257,6275],{"__ignoreMap":81},[86,6238,6239],{"class":88,"line":89},[86,6240,6241],{"class":92},"\u002F\u002F Lazy load non-critical resources\n",[86,6243,6244,6246,6249,6251,6253,6255],{"class":88,"line":96},[86,6245,221],{"class":185},[86,6247,6248],{"class":156}," loadOnInteraction ",[86,6250,1602],{"class":163},[86,6252,2262],{"class":163},[86,6254,3816],{"class":185},[86,6256,865],{"class":163},[86,6258,6259,6261,6264,6266,6268,6271,6273],{"class":88,"line":102},[86,6260,2857],{"class":152},[86,6262,6263],{"class":163}," import",[86,6265,243],{"class":209},[86,6267,259],{"class":163},[86,6269,6270],{"class":255},".\u002Fheavy-component.vue",[86,6272,259],{"class":163},[86,6274,266],{"class":209},[86,6276,6277],{"class":88,"line":213},[86,6278,278],{"class":163},[68,6280,6282],{"id":6281},"monitoring-and-analytics","Monitoring and Analytics",[294,6284,6286],{"id":6285},"_1-google-search-console-integration","1. Google Search Console Integration",[76,6288,6290],{"className":831,"code":6289,"language":833,"meta":81,"style":81},"\u002F\u002F Verify site ownership\nuseHead({\n  meta: [\n    { name: \"google-site-verification\", content: \"your-verification-code\" },\n  ],\n})\n",[83,6291,6292,6297,6306,6315,6347,6353],{"__ignoreMap":81},[86,6293,6294],{"class":88,"line":89},[86,6295,6296],{"class":92},"\u002F\u002F Verify site ownership\n",[86,6298,6299,6302,6304],{"class":88,"line":96},[86,6300,6301],{"class":205},"useHead",[86,6303,243],{"class":156},[86,6305,180],{"class":163},[86,6307,6308,6311,6313],{"class":88,"line":102},[86,6309,6310],{"class":209},"  meta",[86,6312,643],{"class":163},[86,6314,5764],{"class":156},[86,6316,6317,6319,6322,6324,6326,6329,6331,6333,6336,6338,6340,6343,6345],{"class":88,"line":213},[86,6318,5769],{"class":163},[86,6320,6321],{"class":209}," name",[86,6323,643],{"class":163},[86,6325,252],{"class":163},[86,6327,6328],{"class":255},"google-site-verification",[86,6330,259],{"class":163},[86,6332,249],{"class":163},[86,6334,6335],{"class":209}," content",[86,6337,643],{"class":163},[86,6339,252],{"class":163},[86,6341,6342],{"class":255},"your-verification-code",[86,6344,259],{"class":163},[86,6346,975],{"class":163},[86,6348,6349,6351],{"class":88,"line":237},[86,6350,5858],{"class":156},[86,6352,947],{"class":163},[86,6354,6355,6357],{"class":88,"line":269},[86,6356,990],{"class":163},[86,6358,266],{"class":156},[294,6360,6362],{"id":6361},"_2-performance-monitoring","2. Performance Monitoring",[76,6364,6366],{"className":831,"code":6365,"language":833,"meta":81,"style":81},"\u002F\u002F app\u002Fplugins\u002Fweb-vitals.ts\nimport { onCLS, onFID, onLCP } from \"web-vitals\"\n\nexport default defineNuxtPlugin(() => {\n  onCLS(console.log)\n  onFID(console.log)\n  onLCP(console.log)\n})\n",[83,6367,6368,6373,6403,6407,6424,6441,6456,6471],{"__ignoreMap":81},[86,6369,6370],{"class":88,"line":89},[86,6371,6372],{"class":92},"\u002F\u002F app\u002Fplugins\u002Fweb-vitals.ts\n",[86,6374,6375,6377,6379,6382,6384,6387,6389,6392,6394,6396,6398,6401],{"class":88,"line":96},[86,6376,160],{"class":152},[86,6378,880],{"class":163},[86,6380,6381],{"class":156}," onCLS",[86,6383,249],{"class":163},[86,6385,6386],{"class":156}," onFID",[86,6388,249],{"class":163},[86,6390,6391],{"class":156}," onLCP",[86,6393,2584],{"class":163},[86,6395,5448],{"class":152},[86,6397,252],{"class":163},[86,6399,6400],{"class":255},"web-vitals",[86,6402,3153],{"class":163},[86,6404,6405],{"class":88,"line":102},[86,6406,439],{"emptyLinePlaceholder":438},[86,6408,6409,6411,6413,6416,6418,6420,6422],{"class":88,"line":213},[86,6410,845],{"class":152},[86,6412,848],{"class":152},[86,6414,6415],{"class":205}," defineNuxtPlugin",[86,6417,243],{"class":156},[86,6419,2560],{"class":163},[86,6421,3816],{"class":185},[86,6423,865],{"class":163},[86,6425,6426,6429,6431,6434,6436,6439],{"class":88,"line":237},[86,6427,6428],{"class":205},"  onCLS",[86,6430,243],{"class":209},[86,6432,6433],{"class":156},"console",[86,6435,137],{"class":163},[86,6437,6438],{"class":156},"log",[86,6440,266],{"class":209},[86,6442,6443,6446,6448,6450,6452,6454],{"class":88,"line":269},[86,6444,6445],{"class":205},"  onFID",[86,6447,243],{"class":209},[86,6449,6433],{"class":156},[86,6451,137],{"class":163},[86,6453,6438],{"class":156},[86,6455,266],{"class":209},[86,6457,6458,6461,6463,6465,6467,6469],{"class":88,"line":275},[86,6459,6460],{"class":205},"  onLCP",[86,6462,243],{"class":209},[86,6464,6433],{"class":156},[86,6466,137],{"class":163},[86,6468,6438],{"class":156},[86,6470,266],{"class":209},[86,6472,6473,6475],{"class":88,"line":499},[86,6474,990],{"class":163},[86,6476,266],{"class":156},[294,6478,6480],{"id":6479},"_3-seo-testing-tools","3. SEO Testing Tools",[76,6482,6486],{"className":6483,"code":6484,"language":6485,"meta":81,"style":81},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Lighthouse CI\nnpm install -g @lhci\u002Fcli\nlhci autorun\n\n# Check Core Web Vitals\nnpx lighthouse https:\u002F\u002Fexample.com --view\n","bash",[83,6487,6488,6493,6507,6515,6519,6524],{"__ignoreMap":81},[86,6489,6490],{"class":88,"line":89},[86,6491,6492],{"class":92},"# Lighthouse CI\n",[86,6494,6495,6498,6501,6504],{"class":88,"line":96},[86,6496,6497],{"class":370},"npm",[86,6499,6500],{"class":255}," install",[86,6502,6503],{"class":255}," -g",[86,6505,6506],{"class":255}," @lhci\u002Fcli\n",[86,6508,6509,6512],{"class":88,"line":102},[86,6510,6511],{"class":370},"lhci",[86,6513,6514],{"class":255}," autorun\n",[86,6516,6517],{"class":88,"line":213},[86,6518,439],{"emptyLinePlaceholder":438},[86,6520,6521],{"class":88,"line":237},[86,6522,6523],{"class":92},"# Check Core Web Vitals\n",[86,6525,6526,6529,6532,6535],{"class":88,"line":269},[86,6527,6528],{"class":370},"npx",[86,6530,6531],{"class":255}," lighthouse",[86,6533,6534],{"class":255}," https:\u002F\u002Fexample.com",[86,6536,6537],{"class":255}," --view\n",[68,6539,6541],{"id":6540},"common-seo-mistakes-to-avoid","Common SEO Mistakes to Avoid",[294,6543,6545],{"id":6544},"_1-ignoring-mobile-performance","1. Ignoring Mobile Performance",[76,6547,6549],{"className":5010,"code":6548,"language":5012,"meta":81,"style":81},"\u003C!-- ❌ Bad: Large unoptimized images -->\n\u003Cimg src=\"huge-image.jpg\" \u002F>\n\n\u003C!-- ✅ Good: Optimized and responsive -->\n\u003CNuxtImg src=\"image.jpg\" sizes=\"xs:100vw sm:800px\" format=\"webp\" \u002F>\n",[83,6550,6551,6556,6575,6579,6584],{"__ignoreMap":81},[86,6552,6553],{"class":88,"line":89},[86,6554,6555],{"class":92},"\u003C!-- ❌ Bad: Large unoptimized images -->\n",[86,6557,6558,6560,6562,6564,6566,6568,6571,6573],{"class":88,"line":96},[86,6559,374],{"class":163},[86,6561,5228],{"class":209},[86,6563,5231],{"class":185},[86,6565,1602],{"class":163},[86,6567,259],{"class":163},[86,6569,6570],{"class":255},"huge-image.jpg",[86,6572,259],{"class":163},[86,6574,5255],{"class":163},[86,6576,6577],{"class":88,"line":102},[86,6578,439],{"emptyLinePlaceholder":438},[86,6580,6581],{"class":88,"line":213},[86,6582,6583],{"class":92},"\u003C!-- ✅ Good: Optimized and responsive -->\n",[86,6585,6586,6588,6591,6593,6595,6597,6599,6601,6604,6606,6608,6611,6613,6616,6618,6620,6622,6624],{"class":88,"line":237},[86,6587,374],{"class":163},[86,6589,6590],{"class":209},"NuxtImg",[86,6592,5231],{"class":185},[86,6594,1602],{"class":163},[86,6596,259],{"class":163},[86,6598,5238],{"class":255},[86,6600,259],{"class":163},[86,6602,6603],{"class":185}," sizes",[86,6605,1602],{"class":163},[86,6607,259],{"class":163},[86,6609,6610],{"class":255},"xs:100vw sm:800px",[86,6612,259],{"class":163},[86,6614,6615],{"class":185}," format",[86,6617,1602],{"class":163},[86,6619,259],{"class":163},[86,6621,5104],{"class":255},[86,6623,259],{"class":163},[86,6625,5255],{"class":163},[294,6627,6629],{"id":6628},"_2-missing-structured-data","2. Missing Structured Data",[76,6631,6633],{"className":5010,"code":6632,"language":5012,"meta":81,"style":81},"\u003C!-- ❌ Bad: No schema markup -->\n\u003Carticle>\n  \u003Ch1>Blog Post Title\u003C\u002Fh1>\n\u003C\u002Farticle>\n\n\u003C!-- ✅ Good: With schema markup -->\n\u003Cscript setup>\nuseSchemaOrg([\n  {\n    \"@type\": \"BlogPosting\",\n    headline: \"Blog Post Title\",\n  },\n])\n\u003C\u002Fscript>\n",[83,6634,6635,6640,6649,6654,6662,6666,6671,6681,6687,6691,6709,6724,6728,6732],{"__ignoreMap":81},[86,6636,6637],{"class":88,"line":89},[86,6638,6639],{"class":92},"\u003C!-- ❌ Bad: No schema markup -->\n",[86,6641,6642,6644,6647],{"class":88,"line":96},[86,6643,374],{"class":163},[86,6645,6646],{"class":209},"article",[86,6648,4489],{"class":163},[86,6650,6651],{"class":88,"line":102},[86,6652,6653],{"class":156},"  \u003Ch1>Blog Post Title\u003C\u002Fh1>\n",[86,6655,6656,6658,6660],{"class":88,"line":213},[86,6657,4764],{"class":163},[86,6659,6646],{"class":209},[86,6661,4489],{"class":163},[86,6663,6664],{"class":88,"line":237},[86,6665,439],{"emptyLinePlaceholder":438},[86,6667,6668],{"class":88,"line":269},[86,6669,6670],{"class":92},"\u003C!-- ✅ Good: With schema markup -->\n",[86,6672,6673,6675,6677,6679],{"class":88,"line":275},[86,6674,374],{"class":163},[86,6676,4767],{"class":209},[86,6678,4262],{"class":185},[86,6680,4489],{"class":163},[86,6682,6683,6685],{"class":88,"line":499},[86,6684,4565],{"class":205},[86,6686,4568],{"class":156},[86,6688,6689],{"class":88,"line":523},[86,6690,4573],{"class":163},[86,6692,6693,6695,6697,6699,6701,6703,6705,6707],{"class":88,"line":529},[86,6694,870],{"class":163},[86,6696,4581],{"class":209},[86,6698,259],{"class":163},[86,6700,643],{"class":163},[86,6702,252],{"class":163},[86,6704,4590],{"class":255},[86,6706,259],{"class":163},[86,6708,947],{"class":163},[86,6710,6711,6713,6715,6717,6720,6722],{"class":88,"line":534},[86,6712,4599],{"class":209},[86,6714,643],{"class":163},[86,6716,252],{"class":163},[86,6718,6719],{"class":255},"Blog Post Title",[86,6721,259],{"class":163},[86,6723,947],{"class":163},[86,6725,6726],{"class":88,"line":1420},[86,6727,985],{"class":163},[86,6729,6730],{"class":88,"line":1426},[86,6731,4759],{"class":156},[86,6733,6734,6736,6738],{"class":88,"line":1432},[86,6735,4764],{"class":163},[86,6737,4767],{"class":209},[86,6739,4489],{"class":163},[294,6741,6743],{"id":6742},"_3-poor-url-structure","3. Poor URL Structure",[76,6745,6747],{"className":831,"code":6746,"language":833,"meta":81,"style":81},"\u002F\u002F ❌ Bad: Unclear URLs\n\"\u002Fp?id=123&cat=blog\"\n\n\u002F\u002F ✅ Good: Descriptive URLs\n\"\u002Fblog\u002Fseo-guide-2026\"\n",[83,6748,6749,6754,6763,6767,6772],{"__ignoreMap":81},[86,6750,6751],{"class":88,"line":89},[86,6752,6753],{"class":92},"\u002F\u002F ❌ Bad: Unclear URLs\n",[86,6755,6756,6758,6761],{"class":88,"line":96},[86,6757,259],{"class":163},[86,6759,6760],{"class":255},"\u002Fp?id=123&cat=blog",[86,6762,3153],{"class":163},[86,6764,6765],{"class":88,"line":102},[86,6766,439],{"emptyLinePlaceholder":438},[86,6768,6769],{"class":88,"line":213},[86,6770,6771],{"class":92},"\u002F\u002F ✅ Good: Descriptive URLs\n",[86,6773,6774,6776,6779],{"class":88,"line":237},[86,6775,259],{"class":163},[86,6777,6778],{"class":255},"\u002Fblog\u002Fseo-guide-2026",[86,6780,3153],{"class":163},[68,6782,6784],{"id":6783},"ai-seo-tools-for-2026","AI SEO Tools for 2026",[294,6786,6788],{"id":6787},"_1-content-optimization","1. Content Optimization",[630,6790,6791,6797,6803],{},[572,6792,6793,6796],{},[134,6794,6795],{},"Surfer SEO",": AI-powered content optimization",[572,6798,6799,6802],{},[134,6800,6801],{},"Clearscope",": Content grading and suggestions",[572,6804,6805,6808],{},[134,6806,6807],{},"MarketMuse",": Content planning and optimization",[294,6810,6812],{"id":6811},"_2-technical-seo","2. Technical SEO",[630,6814,6815,6821,6827],{},[572,6816,6817,6820],{},[134,6818,6819],{},"Screaming Frog",": Site crawling and analysis",[572,6822,6823,6826],{},[134,6824,6825],{},"Ahrefs",": Backlink analysis and keywords",[572,6828,6829,6832],{},[134,6830,6831],{},"SE Ranking",": All-in-one SEO platform",[294,6834,6836],{"id":6835},"_3-performance","3. Performance",[630,6838,6839,6845,6851],{},[572,6840,6841,6844],{},[134,6842,6843],{},"PageSpeed Insights",": Core Web Vitals testing",[572,6846,6847,6850],{},[134,6848,6849],{},"WebPageTest",": Advanced performance testing",[572,6852,6853,6856],{},[134,6854,6855],{},"Lighthouse",": Automated auditing",[68,6858,6860],{"id":6859},"future-of-seo","Future of SEO",[294,6862,6864],{"id":6863},"trends-to-watch","Trends to Watch",[569,6866,6867,6873,6879,6885,6891],{},[572,6868,6869,6872],{},[134,6870,6871],{},"Voice Search Optimization",": 50% of searches will be voice-based",[572,6874,6875,6878],{},[134,6876,6877],{},"Visual Search",": AI-powered image recognition",[572,6880,6881,6884],{},[134,6882,6883],{},"Video SEO",": Video content in search results",[572,6886,6887,6890],{},[134,6888,6889],{},"E-A-T",": Expertise, Authoritativeness, Trustworthiness",[572,6892,6893,6896],{},[134,6894,6895],{},"Zero-Click Searches",": Featured snippets and AI answers",[68,6898,1204],{"id":1203},[72,6900,6901],{},"AI-powered SEO in 2026 requires a combination of technical excellence, quality content, and strategic optimization. By focusing on Core Web Vitals, structured data, and user experience, you can improve your search visibility and drive organic traffic.",[72,6903,6904],{},"Start with the fundamentals: fast loading times, mobile optimization, and semantic HTML. Then layer on advanced techniques like schema markup and AI content optimization. Monitor your results and iterate based on data.",[710,6906],{},[72,6908,6909,6912],{},[134,6910,6911],{},"Ready to optimize?"," Run a Lighthouse audit on your site and address the top 3 issues. Then implement structured data for your most important pages.",[718,6914,6915],{},"html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"title":81,"searchDepth":96,"depth":96,"links":6917},[6918,6919,6923,6928,6933,6938,6943,6948,6953,6958,6963,6966],{"id":4154,"depth":96,"text":4149},{"id":4160,"depth":96,"text":4161,"children":6920},[6921,6922],{"id":4164,"depth":102,"text":4165},{"id":4197,"depth":102,"text":4198},{"id":4227,"depth":96,"text":4228,"children":6924},[6925,6926,6927],{"id":4231,"depth":102,"text":4232},{"id":4460,"depth":102,"text":4461},{"id":4772,"depth":102,"text":4773},{"id":4996,"depth":96,"text":4997,"children":6929},[6930,6931,6932],{"id":5000,"depth":102,"text":5001},{"id":5146,"depth":102,"text":5147},{"id":5175,"depth":102,"text":5176},{"id":5275,"depth":96,"text":5276,"children":6934},[6935,6936,6937],{"id":5279,"depth":102,"text":5280},{"id":5356,"depth":102,"text":5357},{"id":5428,"depth":102,"text":5429},{"id":5564,"depth":96,"text":5565,"children":6939},[6940,6941,6942],{"id":5568,"depth":102,"text":5569},{"id":5680,"depth":102,"text":5681},{"id":5877,"depth":102,"text":5878},{"id":6097,"depth":96,"text":6098,"children":6944},[6945,6946,6947],{"id":6101,"depth":102,"text":6102},{"id":6171,"depth":102,"text":6172},{"id":6230,"depth":102,"text":6231},{"id":6281,"depth":96,"text":6282,"children":6949},[6950,6951,6952],{"id":6285,"depth":102,"text":6286},{"id":6361,"depth":102,"text":6362},{"id":6479,"depth":102,"text":6480},{"id":6540,"depth":96,"text":6541,"children":6954},[6955,6956,6957],{"id":6544,"depth":102,"text":6545},{"id":6628,"depth":102,"text":6629},{"id":6742,"depth":102,"text":6743},{"id":6783,"depth":96,"text":6784,"children":6959},[6960,6961,6962],{"id":6787,"depth":102,"text":6788},{"id":6811,"depth":102,"text":6812},{"id":6835,"depth":102,"text":6836},{"id":6859,"depth":96,"text":6860,"children":6964},[6965],{"id":6863,"depth":102,"text":6864},{"id":1203,"depth":96,"text":1204},"2026-02-19","Master AI-powered SEO techniques for 2026 including schema markup, Core Web Vitals optimization, and AI search visibility strategies.",{"readingTime":6970},"12 min read","\u002Fblog\u002F30-ai-seo-developer-guide-2026",{"title":4149,"description":6968},"SEO Mastery","Modern SEO techniques for developers",{"src":6976,"mime":742,"alt":6977,"width":744,"height":745},"\u002Fimg\u002Fblog\u002F30-ai-seo-developer-guide-2026\u002Fbanner.svg","AI SEO 2026 Guide - Search optimization with AI brain and graph charts on gradient","blog\u002F30-ai-seo-developer-guide-2026",[6980,6981,753,748,6982],"SEO","AI","Search Optimization","t_7wJUaG-7Ed5VZjwdeAIlwjtxNxeWDKqFC28LrWaVo",1789238288245]