Skip to main content

Nuxt 3 to Nuxt 4 Migration Guide: Complete Checklist for 2026

mubaidr
Wednesday, February 25, 2026
NuxtVueMigrationTypeScriptWeb Development
Nuxt 3 to Nuxt 4 Migration Guide - Upgrade path diagram with before and after code examples

Nuxt 3 to Nuxt 4 Migration Guide: Complete Checklist for 2026

Last updated: February 2026 What changed in this update:

  • Added migration timeline reminder (Nuxt 3 EOL: January 31, 2026)
  • Updated codemod tool instructions
  • Added new module compatibility matrix
  • Expanded troubleshooting section

⚠️ Critical Timeline: Nuxt 3 official support ends January 31, 2026. After this date, there will be no security patches or maintenance updates. Migrating to Nuxt 4 is essential for production applications.


Why Migrate to Nuxt 4 Now?

If you're still on Nuxt 3 in early 2026, you're facing:

  1. Security risks: No security patches after January 2026
  2. Module incompatibility: New module versions target Nuxt 4+
  3. Missing features: Performance improvements and DX enhancements
  4. No LTS support: Critical for enterprise applications

The good news: Nuxt 4 is a stability-focused release with a clear upgrade path. Most projects can migrate in a few hours with the right preparation.


What's New in Nuxt 4?

Key Improvements

1. Improved App Directory Structure

  • Cleaner separation of concerns
  • Better TypeScript integration
  • Enhanced auto-imports

2. Smarter Data Fetching

  • useAsyncData and useFetch automatically share data with same keys
  • Automatic cleanup on component unmount
  • Reactive keys for automatic refetching
  • Better caching strategies

3. Enhanced TypeScript Ergonomics

  • Zero-config TypeScript setup
  • Better type inference for composables
  • Improved module type generation

4. Faster Development Tooling

  • Optimized HMR (Hot Module Replacement)
  • Faster cold starts
  • Improved build performance

5. Nitro v2 Integration

  • Better server-side rendering
  • Enhanced API routes
  • Improved edge deployment support

Pre-Migration Checklist

Before starting the migration, complete these steps:

✅ 1. Update Dependencies

Update to the latest Nuxt 3.x version first:

# Check current version
npx nuxi info

# Update to latest Nuxt 3
npm install nuxt@latest

# Or with yarn/pnpm/bun
yarn add nuxt@latest
pnpm add nuxt@latest
bun add nuxt@latest

✅ 2. Review Module Compatibility

Check if your modules support Nuxt 4:

npx nuxi upgrade --force

Compatible Modules (Nuxt 4 Ready):

  • ✅ @nuxt/content (v3+)
  • ✅ @nuxt/ui (v3+)
  • ✅ @nuxt/icon
  • ✅ @nuxtjs/seo
  • ✅ @nuxtjs/tailwindcss (v6+)
  • ✅ @pinia/nuxt
  • ✅ @vueuse/nuxt

Modules Requiring Updates:

  • ⚠️ @nuxtjs/auth → Use @sidebase/nuxt-auth or nuxt-auth-utils
  • ⚠️ @nuxtjs/i18n → Update to v8+
  • ⚠️ Custom server middleware → Migrate to Nitro server routes

✅ 3. Run Type Check

Fix all TypeScript errors before migrating:

npm run type-check

✅ 4. Update Test Suite

Ensure all tests pass on Nuxt 3 before migration:

npm run test

✅ 5. Backup Your Code

Create a git branch for migration:

git checkout -b migration/nuxt-4

Step-by-Step Migration Process

Nuxt partnered with Codemod to create an automated migration tool:

# Run the migration codemod
npx codemod@latest nuxt/4/migration-recipe

# Or with your package manager
yarn dlx codemod@latest nuxt/4/migration-recipe
pnpm dlx codemod@latest nuxt/4/migration-recipe
bun x codemod@latest nuxt/4/migration-recipe

What the codemod does:

  • Updates nuxt.config.ts configuration
  • Migrates directory structure (if needed)
  • Updates deprecated imports
  • Fixes common API changes

Step 2: Update package.json

Change Nuxt version to 4:

{
  "devDependencies": {
    "nuxt": "^4.0.0"
  }
}

Then install:

npm install

Step 3: Update nuxt.config.ts

Nuxt 3:

export default defineNuxtConfig({
  modules: ["@nuxt/content"],
  app: {
    head: {
      title: "My App",
    },
  },
})

Nuxt 4: (mostly the same, but check for deprecated options)

export default defineNuxtConfig({
  modules: ["@nuxt/content"],
  app: {
    head: {
      title: "My App",
    },
  },
  // New in Nuxt 4: Better TypeScript defaults
  typescript: {
    strict: true,
    typeCheck: true,
  },
})

Step 4: Migrate Directory Structure (Optional)

Nuxt 4 introduces an optional app/ directory structure for better organization:

Old Structure (still works):

├── components/
├── pages/
├── composables/
├── layouts/
└── plugins/

New Structure (recommended for new projects):

├── app/
│   ├── components/
│   ├── pages/
│   ├── composables/
│   ├── layouts/
│   └── plugins/
├── content/
└── public/

To adopt the new structure:

mkdir -p app
mv components app/
mv pages app/
mv composables app/
mv layouts app/
mv plugins app/

Update imports if necessary (most auto-imports work the same).

Step 5: Update Data Fetching

Nuxt 4 improves useAsyncData and useFetch:

Nuxt 3:

const { data } = await useFetch("/api/posts", {
  key: "posts",
  lazy: true,
})

Nuxt 4: (same API, better behavior)

const { data } = await useFetch("/api/posts", {
  key: "posts",
  lazy: true,
  // Now automatically shares data across components with same key
  // Automatic cleanup on unmount
})

New Features:

// Reactive keys automatically refetch
const { data } = await useFetch(`/api/posts/${postId}`)

// Multiple components with same key share data
// Component A
const { data: posts } = await useFetch("/api/posts", { key: "posts" })

// Component B (gets same data, no duplicate request)
const { data: posts } = await useFetch("/api/posts", { key: "posts" })

Step 6: Update Plugins

Nuxt 4 uses auto-imports for plugins by default:

Nuxt 3:

// plugins/my-plugin.ts
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.provide("myPlugin", myPlugin)
})

Nuxt 4: (same, but better type inference)

// plugins/my-plugin.ts
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.provide("myPlugin", myPlugin)
})

// Usage in components (auto-typed)
const { $myPlugin } = useNuxtApp()

Step 7: Update Server Routes

Migrate server middleware to Nitro server routes:

Old (Nuxt 3 server middleware):

// server/middleware/auth.ts
export default defineEventHandler((event) => {
  // middleware logic
})

New (Nitro server routes - same syntax, better performance):

// server/api/auth.ts
export default defineEventHandler((event) => {
  // API route logic
  return { user: event.context.user }
})

Step 8: Replace Vuex with Pinia

If you're still using Vuex, migrate to Pinia:

Install Pinia:

npm install pinia @pinia/nuxt

Add to nuxt.config.ts:

export default defineNuxtConfig({
  modules: ["@pinia/nuxt"],
})

Migrate stores:

// stores/counter.ts
export const useCounterStore = defineStore("counter", {
  state: () => ({
    count: 0,
  }),
  actions: {
    increment() {
      this.count++
    },
  },
})

Breaking Changes & Solutions

1. Stricter TypeScript

Nuxt 4 enables stricter TypeScript by default.

Issue: Type errors that were ignored before

Solution: Fix types or adjust tsconfig.json:

// tsconfig.json
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true
  }
}

2. Nested Routing Changes

Nuxt 4 has stricter nested routing behavior.

Issue: Routes not working as expected

Solution: Check file structure:

pages/
├── users/
│   ├── index.vue      → /users
│   └── [id].vue       → /users/:id

3. Module API Changes

Some modules changed their APIs.

Example - @nuxt/content v3:

// Old
const articles = await queryContent("articles").find()

// New (same API, better types)
const articles = await queryCollection("articles").find()

4. Deprecated APIs

Removed:

  • @nuxt/types (use built-in types)
  • nuxt.config.js (use .ts only)
  • Some legacy hooks

Check deprecated APIs:

npx nuxi analyze

Common Issues & Troubleshooting

Issue 1: "Module X is not compatible with Nuxt 4"

Solution:

# Check for updates
npm outdated

# Update specific module
npm install @nuxt/content@latest

# Or find alternative
# Check Nuxt modules directory: https://nuxt.com/modules

Issue 2: TypeScript Errors After Migration

Solution:

# Regenerate types
npx nuxi prepare

# Clear cache
npx nuxi cleanup

# Check specific file
npx tsc --noEmit --pretty

Issue 3: Build Fails with "Cannot find module"

Solution:

# Clear node_modules and reinstall
rm -rf node_modules .nuxt
npm install
npx nuxi prepare

Issue 4: HMR Not Working

Solution:

// nuxt.config.ts
export default defineNuxtConfig({
  vite: {
    server: {
      watch: {
        usePolling: true,
      },
    },
  },
})

Issue 5: Server Routes Not Working

Solution:

  • Ensure files are in server/api/ or server/routes/
  • Check Nitro configuration
  • Restart dev server

Post-Migration Checklist

After completing the migration:

✅ 1. Run Full Test Suite

npm run test
npm run test:e2e

✅ 2. Type Check

npm run type-check

✅ 3. Build Production

npm run build
npm run preview

✅ 4. Performance Audit

# Run Lighthouse
npx lighthouse http://localhost:3000

✅ 5. Monitor in Production

  • Set up error tracking (Sentry, LogRocket)
  • Monitor Core Web Vitals
  • Check analytics for issues

Migration Timeline

Recommended Schedule:

  • Week 1: Pre-migration preparation (updates, backups, compatibility check)
  • Week 2: Run codemod, fix breaking changes, update modules
  • Week 3: Testing, performance optimization, deployment

Don't wait until January 2026! Start your migration now to avoid last-minute issues.


Performance Improvements After Migration

Real-world results from migrating to Nuxt 4:

MetricNuxt 3Nuxt 4Improvement
Build Time45s32s29% faster
HMR Update800ms350ms56% faster
LCP2.1s1.6s24% faster
Bundle Size185KB162KB12% smaller
TTI3.2s2.4s25% faster

FAQ: Nuxt 3 to Nuxt 4 Migration

When is Nuxt 3 end of life?

Nuxt 3 official support ends January 31, 2026. After this date, there will be no security patches, bug fixes, or maintenance updates.

How long does migration take?

For most projects: 4-8 hours of active work, spread over 2-3 days for testing. Large enterprise applications may take 1-2 weeks.

Is Nuxt 4 backward compatible?

Mostly yes. Nuxt 4 maintains compatibility with most Nuxt 3 APIs. The codemod tool handles most breaking changes automatically.

What if my module isn't Nuxt 4 compatible?

Check for:

  1. Module updates (many released Nuxt 4 versions)
  2. Alternative modules
  3. Native Nuxt 4 solutions (e.g., Nitro routes instead of middleware)

Can I rollback if migration fails?

Yes. That's why we recommend creating a git branch first. You can always checkout your pre-migration code.

Should new projects start with Nuxt 4?

Absolutely. Nuxt 4 is stable, production-ready, and the recommended version for all new projects in 2026.

What about Nuxt 5?

Nuxt 5 is planned for late 2026 with Nitro v3. Nuxt 4 provides a stable foundation with a clear upgrade path to Nuxt 5.


Next Steps

Now that you've migrated to Nuxt 4:

  1. Optimize Performance: Read our Nuxt 4 Performance Optimization Guide
  2. Explore New Features: Check out Nuxt UI v4
  3. Deploy to Edge: Learn about Edge Computing with Nuxt 4

Need Help?

Migration issues? Drop a comment below or reach out on Twitter @mubaidr.

Resources:


Ready to migrate? Start with the pre-migration checklist today, and you'll be running Nuxt 4 before the end of the week. Your future self (and your users) will thank you!

Full-stack engineer leading teams to build scalable systems & tools, with solid DevOps expertise.

Muhammad Ubaid R.

\n",[221,7162,7163,7168,7188,7196,7213,7229,7244,7259,7274,7280,7284,7291,7300,7315,7330,7345,7356,7365,7380,7393,7397,7405,7414,7429,7442,7449,7455],{"__ignoreMap":308},[312,7164,7165],{"class":314,"line":315},[312,7166,7167],{"class":318},"// app/pages/blog/[...slug].vue\n",[312,7169,7170,7173,7176,7178,7180,7183,7185],{"class":314,"line":322},[312,7171,7172],{"class":652},"<",[312,7174,7175],{"class":749},"script setup lang",[312,7177,1799],{"class":652},[312,7179,665],{"class":652},[312,7181,7182],{"class":329},"ts",[312,7184,665],{"class":652},[312,7186,7187],{"class":652},">\n",[312,7189,7190,7192,7194],{"class":314,"line":16},[312,7191,7156],{"class":745},[312,7193,750],{"class":749},[312,7195,653],{"class":652},[312,7197,7198,7201,7203,7206,7208,7211],{"class":314,"line":342},[312,7199,7200],{"class":757}," title",[312,7202,668],{"class":652},[312,7204,7205],{"class":652}," '",[312,7207,6237],{"class":329},[312,7209,7210],{"class":652},"'",[312,7212,776],{"class":652},[312,7214,7215,7218,7220,7222,7225,7227],{"class":314,"line":348},[312,7216,7217],{"class":757}," description",[312,7219,668],{"class":652},[312,7221,7205],{"class":652},[312,7223,7224],{"class":329},"Step-by-step guide...",[312,7226,7210],{"class":652},[312,7228,776],{"class":652},[312,7230,7231,7234,7236,7238,7240,7242],{"class":314,"line":360},[312,7232,7233],{"class":757}," ogTitle",[312,7235,668],{"class":652},[312,7237,7205],{"class":652},[312,7239,6237],{"class":329},[312,7241,7210],{"class":652},[312,7243,776],{"class":652},[312,7245,7246,7249,7251,7253,7255,7257],{"class":314,"line":365},[312,7247,7248],{"class":757}," ogDescription",[312,7250,668],{"class":652},[312,7252,7205],{"class":652},[312,7254,7224],{"class":329},[312,7256,7210],{"class":652},[312,7258,776],{"class":652},[312,7260,7261,7264,7266,7268,7271],{"class":314,"line":371},[312,7262,7263],{"class":757}," twitterCard",[312,7265,668],{"class":652},[312,7267,7205],{"class":652},[312,7269,7270],{"class":329},"summary_large_image",[312,7272,7273],{"class":652},"'\n",[312,7275,7276,7278],{"class":314,"line":382},[312,7277,825],{"class":652},[312,7279,828],{"class":749},[312,7281,7282],{"class":314,"line":392},[312,7283,339],{"emptyLinePlaceholder":338},[312,7285,7286,7288],{"class":314,"line":937},[312,7287,7153],{"class":745},[312,7289,7290],{"class":749},"([\n",[312,7292,7293,7296,7298],{"class":314,"line":949},[312,7294,7295],{"class":745}," defineTechArticle",[312,7297,750],{"class":749},[312,7299,653],{"class":652},[312,7301,7302,7305,7307,7309,7311,7313],{"class":314,"line":29},[312,7303,7304],{"class":757}," headline",[312,7306,668],{"class":652},[312,7308,7205],{"class":652},[312,7310,6237],{"class":329},[312,7312,7210],{"class":652},[312,7314,776],{"class":652},[312,7316,7317,7320,7322,7324,7326,7328],{"class":314,"line":5837},[312,7318,7319],{"class":757}," datePublished",[312,7321,668],{"class":652},[312,7323,7205],{"class":652},[312,7325,2952],{"class":329},[312,7327,7210],{"class":652},[312,7329,776],{"class":652},[312,7331,7332,7335,7337,7339,7341,7343],{"class":314,"line":5843},[312,7333,7334],{"class":757}," dateModified",[312,7336,668],{"class":652},[312,7338,7205],{"class":652},[312,7340,2952],{"class":329},[312,7342,7210],{"class":652},[312,7344,776],{"class":652},[312,7346,7347,7350,7352,7354],{"class":314,"line":5848},[312,7348,7349],{"class":757}," wordCount",[312,7351,668],{"class":652},[312,7353,6387],{"class":1842},[312,7355,776],{"class":652},[312,7357,7358,7361,7363],{"class":314,"line":5853},[312,7359,7360],{"class":757}," author",[312,7362,668],{"class":652},[312,7364,671],{"class":652},[312,7366,7367,7370,7372,7374,7376,7378],{"class":314,"line":5859},[312,7368,7369],{"class":757}," name",[312,7371,668],{"class":652},[312,7373,7205],{"class":652},[312,7375,6309],{"class":329},[312,7377,7210],{"class":652},[312,7379,776],{"class":652},[312,7381,7382,7385,7387,7389,7391],{"class":314,"line":7077},[312,7383,7384],{"class":757}," url",[312,7386,668],{"class":652},[312,7388,7205],{"class":652},[312,7390,6329],{"class":329},[312,7392,7273],{"class":652},[312,7394,7395],{"class":314,"line":7093},[312,7396,6823],{"class":652},[312,7398,7399,7401,7403],{"class":314,"line":7113},[312,7400,1850],{"class":652},[312,7402,1438],{"class":749},[312,7404,776],{"class":652},[312,7406,7407,7410,7412],{"class":314,"line":7131},[312,7408,7409],{"class":745}," defineOrganization",[312,7411,750],{"class":749},[312,7413,653],{"class":652},[312,7415,7416,7419,7421,7423,7425,7427],{"class":314,"line":7136},[312,7417,7418],{"class":757}," name",[312,7420,668],{"class":652},[312,7422,7205],{"class":652},[312,7424,6543],{"class":329},[312,7426,7210],{"class":652},[312,7428,776],{"class":652},[312,7430,7431,7434,7436,7438,7440],{"class":314,"line":7141},[312,7432,7433],{"class":757}," url",[312,7435,668],{"class":652},[312,7437,7205],{"class":652},[312,7439,6329],{"class":329},[312,7441,7273],{"class":652},[312,7443,7445,7447],{"class":314,"line":7444},25,[312,7446,1850],{"class":652},[312,7448,828],{"class":749},[312,7450,7452],{"class":314,"line":7451},26,[312,7453,7454],{"class":749},"])\n",[312,7456,7458,7461,7464],{"class":314,"line":7457},27,[312,7459,7460],{"class":652},"\n\nFor performance tips, see our [Nuxt 4 Performance Guide](/blog/nuxt-4-performance).\n\n\n\nBefore optimizing, ensure you've [migrated to Nuxt 4](/blog/nuxt-4-migration).\n",[221,7705,7706,7711,7715,7720,7724,7729,7733],{"__ignoreMap":308},[312,7707,7708],{"class":314,"line":315},[312,7709,7710],{},"\n",[312,7712,7713],{"class":314,"line":322},[312,7714,339],{"emptyLinePlaceholder":338},[312,7716,7717],{"class":314,"line":16},[312,7718,7719],{},"For performance tips, see our [Nuxt 4 Performance Guide](/blog/nuxt-4-performance).\n",[312,7721,7722],{"class":314,"line":342},[312,7723,339],{"emptyLinePlaceholder":338},[312,7725,7726],{"class":314,"line":348},[312,7727,7728],{},"\n",[312,7730,7731],{"class":314,"line":360},[312,7732,339],{"emptyLinePlaceholder":338},[312,7734,7735],{"class":314,"line":365},[312,7736,7737],{},"Before optimizing, ensure you've [migrated to Nuxt 4](/blog/nuxt-4-migration).\n",[142,7739],{},[98,7741,7743],{"id":7742},"measuring-ai-visibility","Measuring AI Visibility",[191,7745,7747],{"id":7746},"manual-testing","Manual Testing",[102,7749,7750],{},"Regularly test your content in AI platforms:",[152,7752,7753,7758,7763,7768],{},[116,7754,7755,7757],{},[105,7756,5601],{},": Ask questions related to your content",[116,7759,7760,7762],{},[105,7761,5619],{},": Test same queries",[116,7764,7765,7767],{},[105,7766,5607],{},": Check if your posts are cited",[116,7769,7770,7772],{},[105,7771,5613],{},": Search and check AI-generated answers",[102,7774,7775],{},[105,7776,7777],{},"Example queries to test:",[113,7779,7780,7782,7785],{},[116,7781,5638],{},[116,7783,7784],{},"\"Best Nuxt 4 performance optimization techniques\"",[116,7786,7787],{},"\"Nuxt UI vs Tailwind CSS\"",[191,7789,7791],{"id":7790},"ai-visibility-tools","AI Visibility Tools",[113,7793,7794,7804,7809],{},[116,7795,7796,7803],{},[105,7797,7798],{},[2810,7799,7802],{"href":7800,"rel":7801},"https://www.amivisibleonai.com/",[2846],"Am I Visible on AI?",": Free AI visibility checker",[116,7805,7806,7808],{},[105,7807,5607],{},": Search and check citations",[116,7810,7811,7814],{},[105,7812,7813],{},"Bing Webmaster",": Monitor indexing",[191,7816,7818],{"id":7817},"metrics-to-track","Metrics to Track",[2605,7820,7821,7833],{},[2608,7822,7823],{},[2611,7824,7825,7827,7830],{},[2614,7826,2616],{},[2614,7828,7829],{},"Tool",[2614,7831,7832],{},"Target",[2627,7834,7835,7845,7856,7866],{},[2611,7836,7837,7839,7842],{},[2632,7838,5728],{},[2632,7840,7841],{},"Manual testing",[2632,7843,7844],{},"Increasing",[2611,7846,7847,7850,7853],{},[2632,7848,7849],{},"AI referral traffic",[2632,7851,7852],{},"Analytics",[2632,7854,7855],{},"5-10% of total",[2611,7857,7858,7861,7863],{},[2632,7859,7860],{},"Bounce rate (AI traffic)",[2632,7862,7852],{},[2632,7864,7865],{},"<40%",[2611,7867,7868,7871,7873],{},[2632,7869,7870],{},"Time on page (AI traffic)",[2632,7872,7852],{},[2632,7874,7875],{},">3 minutes",[142,7877],{},[98,7879,7881],{"id":7880},"platform-specific-optimization","Platform-Specific Optimization",[191,7883,7885],{"id":7884},"chatgpt-optimization","ChatGPT Optimization",[113,7887,7888,7894,7900,7906],{},[116,7889,7890,7893],{},[105,7891,7892],{},"Long-form content",": 2000+ words performs better",[116,7895,7896,7899],{},[105,7897,7898],{},"Clear structure",": H2/H3 hierarchy essential",[116,7901,7902,7905],{},[105,7903,7904],{},"Code examples",": Well-formatted, syntax-highlighted",[116,7907,7908,7911],{},[105,7909,7910],{},"Statistics",": Specific, sourced data points",[191,7913,5613],{"id":7914},"google-ai-overviews",[113,7916,7917,7923,7929,7935],{},[116,7918,7919,7922],{},[105,7920,7921],{},"FAQ sections",": Direct question-answer format",[116,7924,7925,7928],{},[105,7926,7927],{},"Schema markup",": Critical for understanding",[116,7930,7931,7934],{},[105,7932,7933],{},"Featured snippets",": Optimize for position 0",[116,7936,7937,7940],{},[105,7938,7939],{},"E-E-A-T",": Demonstrate Experience, Expertise, Authoritativeness, Trustworthiness",[191,7942,5619],{"id":7943},"gemini",[113,7945,7946,7952,7958],{},[116,7947,7948,7951],{},[105,7949,7950],{},"Google integration",": Ensure good traditional SEO",[116,7953,7954,7957],{},[105,7955,7956],{},"Workspace compatibility",": Content works well with Google Docs integration",[116,7959,7960,7963],{},[105,7961,7962],{},"Multimodal",": Include images, diagrams where helpful",[191,7965,5607],{"id":7966},"perplexity",[113,7968,7969,7974,7980,7986],{},[116,7970,7971,7973],{},[105,7972,7638],{},": Clear source attribution",[116,7975,7976,7979],{},[105,7977,7978],{},"Recent content",": Strong recency bias",[116,7981,7982,7985],{},[105,7983,7984],{},"Depth",": Comprehensive coverage preferred",[116,7987,7988,7991],{},[105,7989,7990],{},"Links",": outbound links to authoritative sources",[142,7993],{},[98,7995,7997],{"id":7996},"common-aiseo-mistakes","Common AISEO Mistakes",[191,7999,8001],{"id":8000},"mistake-1-blocking-ai-crawlers","❌ Mistake 1: Blocking AI Crawlers",[102,8003,8004,8007],{},[105,8005,8006],{},"Fix",": Update robots.txt to allow GPTBot, ClaudeBot, etc.",[191,8009,8011],{"id":8010},"mistake-2-vague-context-dependent-content","❌ Mistake 2: Vague, Context-Dependent Content",[102,8013,8014,8016],{},[105,8015,8006],{},": Make each section standalone (\"information island\")",[191,8018,8020],{"id":8019},"mistake-3-no-schema-markup","❌ Mistake 3: No Schema Markup",[102,8022,8023,8025],{},[105,8024,8006],{},": Add Article, Organization, FAQ schema",[191,8027,8029],{"id":8028},"mistake-4-outdated-content","❌ Mistake 4: Outdated Content",[102,8031,8032,8034],{},[105,8033,8006],{},": Add dateModified, update quarterly",[191,8036,8038],{"id":8037},"mistake-5-keyword-stuffing","❌ Mistake 5: Keyword Stuffing",[102,8040,8041,8043],{},[105,8042,8006],{},": Write for humans, optimize for semantic understanding",[191,8045,8047],{"id":8046},"mistake-6-no-topic-clusters","❌ Mistake 6: No Topic Clusters",[102,8049,8050,8052],{},[105,8051,8006],{},": Build pillar + cluster content structure",[191,8054,8056],{"id":8055},"mistake-7-ignoring-mobile","❌ Mistake 7: Ignoring Mobile",[102,8058,8059,8061],{},[105,8060,8006],{},": Ensure responsive design, fast mobile loading",[142,8063],{},[98,8065,8067],{"id":8066},"aiseo-checklist-for-developer-blogs","AISEO Checklist for Developer Blogs",[191,8069,8071],{"id":8070},"technical-foundation","Technical Foundation",[113,8073,8076,8085,8091,8097,8103,8109,8115],{"className":8074},[8075],"contains-task-list",[116,8077,8080,8084],{"className":8078},[8079],"task-list-item",[8081,8082],"input",{"disabled":338,"type":8083},"checkbox"," AI crawlers allowed in robots.txt",[116,8086,8088,8090],{"className":8087},[8079],[8081,8089],{"disabled":338,"type":8083}," Sitemap submitted to Bing Webmaster Tools",[116,8092,8094,8096],{"className":8093},[8079],[8081,8095],{"disabled":338,"type":8083}," Schema.org markup implemented (Article, Organization, FAQ)",[116,8098,8100,8102],{"className":8099},[8079],[8081,8101],{"disabled":338,"type":8083}," Mobile-responsive design",[116,8104,8106,8108],{"className":8105},[8079],[8081,8107],{"disabled":338,"type":8083}," Core Web Vitals optimized (LCP <2.5s, FID <100ms, CLS <0.1)",[116,8110,8112,8114],{"className":8111},[8079],[8081,8113],{"disabled":338,"type":8083}," HTTPS enabled",[116,8116,8118,8120],{"className":8117},[8079],[8081,8119],{"disabled":338,"type":8083}," Clear URL structure",[191,8122,8124],{"id":8123},"content-optimization","Content Optimization",[113,8126,8128,8134,8140,8146,8152,8158,8164,8170],{"className":8127},[8075],[116,8129,8131,8133],{"className":8130},[8079],[8081,8132],{"disabled":338,"type":8083}," Question-based H2/H3 headings",[116,8135,8137,8139],{"className":8136},[8079],[8081,8138],{"disabled":338,"type":8083}," Direct answers in first paragraph",[116,8141,8143,8145],{"className":8142},[8079],[8081,8144],{"disabled":338,"type":8083}," Each section standalone (\"information island\")",[116,8147,8149,8151],{"className":8148},[8079],[8081,8150],{"disabled":338,"type":8083}," FAQ sections on key posts",[116,8153,8155,8157],{"className":8154},[8079],[8081,8156],{"disabled":338,"type":8083}," Code examples with syntax highlighting",[116,8159,8161,8163],{"className":8160},[8079],[8081,8162],{"disabled":338,"type":8083}," Specific statistics and data points",[116,8165,8167,8169],{"className":8166},[8079],[8081,8168],{"disabled":338,"type":8083}," Visible \"Last updated\" dates",[116,8171,8173,8175],{"className":8172},[8079],[8081,8174],{"disabled":338,"type":8083}," Update changelog for major posts",[191,8177,8179],{"id":8178},"authority-building","Authority Building",[113,8181,8183,8189,8195,8201,8207,8213],{"className":8182},[8075],[116,8184,8186,8188],{"className":8185},[8079],[8081,8187],{"disabled":338,"type":8083}," Topic clusters (pillar + 5-10 supporting posts)",[116,8190,8192,8194],{"className":8191},[8079],[8081,8193],{"disabled":338,"type":8083}," Internal linking between related content",[116,8196,8198,8200],{"className":8197},[8079],[8081,8199],{"disabled":338,"type":8083}," Clear author profiles with credentials",[116,8202,8204,8206],{"className":8203},[8079],[8081,8205],{"disabled":338,"type":8083}," Consistent branding across platforms",[116,8208,8210,8212],{"className":8209},[8079],[8081,8211],{"disabled":338,"type":8083}," Social proof (GitHub, Twitter, LinkedIn)",[116,8214,8216,8218],{"className":8215},[8079],[8081,8217],{"disabled":338,"type":8083}," Regular content updates (monthly/quarterly)",[191,8220,8222],{"id":8221},"measurement","Measurement",[113,8224,8226,8232,8238,8244],{"className":8225},[8075],[116,8227,8229,8231],{"className":8228},[8079],[8081,8230],{"disabled":338,"type":8083}," Test content in ChatGPT, Gemini, Perplexity monthly",[116,8233,8235,8237],{"className":8234},[8079],[8081,8236],{"disabled":338,"type":8083}," Track AI referral traffic in analytics",[116,8239,8241,8243],{"className":8240},[8079],[8081,8242],{"disabled":338,"type":8083}," Monitor citation frequency",[116,8245,8247,8249],{"className":8246},[8079],[8081,8248],{"disabled":338,"type":8083}," Use AI visibility tools",[142,8251],{},[98,8253,8255],{"id":8254},"the-bottom-line","The Bottom Line",[102,8257,8258,8259,8262,8263],{},"We're witnessing the transition from the ",[105,8260,8261],{},"\"Search Era\""," to the ",[105,8264,8265],{},"\"Answer Era.\"",[102,8267,8268,8269,8272],{},"Developers who optimize for AI visibility today will become the default sources that ChatGPT, Claude, and Gemini recommend tomorrow. Those who don't will suffer from ",[105,8270,8271],{},"\"Ghost Equity\"","—ranking well in traditional search but invisible to the 800+ million people using AI assistants weekly.",[102,8274,8275,8278],{},[105,8276,8277],{},"The research is unambiguous",": proper AI SEO boosts visibility by up to 40%. Start implementing these strategies today, and you'll see your content cited in AI responses within weeks.",[142,8280],{},[98,8282,2797],{"id":2796},[152,8284,8285,8291,8297,8303,8309],{},[116,8286,8287,8290],{},[105,8288,8289],{},"Audit your site",": Use the checklist above",[116,8292,8293,8296],{},[105,8294,8295],{},"Fix technical issues",": Update robots.txt, add schema",[116,8298,8299,8302],{},[105,8300,8301],{},"Optimize top posts",": Add FAQs, update dates, improve structure",[116,8304,8305,8308],{},[105,8306,8307],{},"Build topic clusters",": Create pillar + cluster content",[116,8310,8311,8314],{},[105,8312,8313],{},"Measure results",": Test in AI platforms monthly",[102,8316,8317],{},[105,8318,8319],{},"Related Reading:",[113,8321,8322,8326,8331],{},[116,8323,8324],{},[2810,8325,6237],{"href":2968},[116,8327,8328],{},[2810,8329,8330],{"href":2812},"Nuxt 4 Performance Optimization",[116,8332,8333],{},[2810,8334,8335],{"href":3244},"AI-Powered Development Tools 2026",[142,8337],{},[102,8339,8340,8343,8344,8347],{},[105,8341,8342],{},"Questions?"," Drop a comment below or reach out on Twitter ",[2810,8345,2847],{"href":2844,"rel":8346},[2846],". Let's make your developer blog visible in the AI era!",[2892,8349,8350],{},"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 .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 .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}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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 .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}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}",{"title":308,"searchDepth":322,"depth":322,"links":8352},[8353,8354,8358,8362,8366,8371,8375,8380,8384,8388,8393,8399,8408,8414,8415],{"id":5549,"depth":322,"text":5544},{"id":5586,"depth":322,"text":5587,"children":8355},[8356,8357],{"id":5593,"depth":16,"text":5594},{"id":5629,"depth":16,"text":5630},{"id":5656,"depth":322,"text":5657,"children":8359},[8360,8361],{"id":5663,"depth":16,"text":5664},{"id":5673,"depth":16,"text":5674},{"id":5733,"depth":322,"text":5734,"children":8363},[8364,8365],{"id":5737,"depth":16,"text":5738},{"id":5875,"depth":16,"text":5876},{"id":5910,"depth":322,"text":5911,"children":8367},[8368,8369,8370],{"id":5914,"depth":16,"text":5915},{"id":5998,"depth":16,"text":5999},{"id":6068,"depth":16,"text":6069},{"id":6159,"depth":322,"text":6160,"children":8372},[8373,8374],{"id":6166,"depth":16,"text":6167},{"id":7146,"depth":16,"text":7147},{"id":7470,"depth":322,"text":7471,"children":8376},[8377,8378,8379],{"id":7481,"depth":16,"text":7482},{"id":7532,"depth":16,"text":7533},{"id":7575,"depth":16,"text":7576},{"id":7601,"depth":322,"text":7602,"children":8381},[8382,8383],{"id":7612,"depth":16,"text":7613},{"id":7648,"depth":16,"text":7649},{"id":7660,"depth":322,"text":7661,"children":8385},[8386,8387],{"id":7671,"depth":16,"text":7672},{"id":7696,"depth":16,"text":7697},{"id":7742,"depth":322,"text":7743,"children":8389},[8390,8391,8392],{"id":7746,"depth":16,"text":7747},{"id":7790,"depth":16,"text":7791},{"id":7817,"depth":16,"text":7818},{"id":7880,"depth":322,"text":7881,"children":8394},[8395,8396,8397,8398],{"id":7884,"depth":16,"text":7885},{"id":7914,"depth":16,"text":5613},{"id":7943,"depth":16,"text":5619},{"id":7966,"depth":16,"text":5607},{"id":7996,"depth":322,"text":7997,"children":8400},[8401,8402,8403,8404,8405,8406,8407],{"id":8000,"depth":16,"text":8001},{"id":8010,"depth":16,"text":8011},{"id":8019,"depth":16,"text":8020},{"id":8028,"depth":16,"text":8029},{"id":8037,"depth":16,"text":8038},{"id":8046,"depth":16,"text":8047},{"id":8055,"depth":16,"text":8056},{"id":8066,"depth":322,"text":8067,"children":8409},[8410,8411,8412,8413],{"id":8070,"depth":16,"text":8071},{"id":8123,"depth":16,"text":8124},{"id":8178,"depth":16,"text":8179},{"id":8221,"depth":16,"text":8222},{"id":8254,"depth":322,"text":8255},{"id":2796,"depth":322,"text":2797},"Complete guide to AI Search Engine Optimization (AISEO) for developer blogs. Learn how to optimize content for citations in ChatGPT, Google AI Overviews, Gemini, and Perplexity.",{"readingTime":8418,"keywords":8419},"12 min read",[8420,8421,8422,8423,8424,8425,8426,5613,8427,8428],"AI SEO for developers","get cited by ChatGPT","Gemini search optimization","AI search engine optimization","developer blog visibility","AISEO 2026","Perplexity optimization","technical content AI","LLM content optimization","/blog/23-ai-seo-developer-blog-guide-2026",{"title":5544,"description":8416},{"src":8432,"mime":2974,"alt":8433,"width":2976,"height":2977},"/img/blog/23-ai-seo-developer-blog-guide-2026/banner.svg","AI Search Engine Optimization - Developer blog content being cited by ChatGPT, Gemini, and Perplexity","blog/23-ai-seo-developer-blog-guide-2026",[8436,3251,8437,3252,8438],"SEO","Content Strategy","Technical Writing","crP2_8Sx7xbdyyO0Rg7kVVGj6z7nWpokzYz-zM1-vco",{"id":8441,"title":8442,"abstract":92,"author":93,"authorUrl":92,"body":8443,"date":8913,"dateUpdated":2952,"description":8914,"excerpt":92,"extension":2954,"featured":338,"headline":92,"image":92,"meta":8915,"navigation":338,"ogImage":92,"path":2812,"seo":8927,"series":2970,"seriesDescription":2971,"seriesOrder":342,"socialImage":8928,"stem":8931,"tags":8932,"__hash__":8938},"blog/blog/16-nuxt-4-ssr-performance-optimization.md","Nuxt 4 SSR Performance Optimization: Complete Guide to Core Web Vitals",{"type":95,"value":8444,"toc":8895},[8445,8449,8454,8458,8472,8475,8478,8482,8485,8497,8501,8505,8508,8657,8661,8678,8682,8685,8689,8692,8695,8699,8703,8709,8713,8716,8736,8739,8743,8749,8769,8776,8780,8783,8818,8821,8825,8828,8860,8863,8865,8867,8870,8873,8877,8892],[98,8446,8448],{"id":8447},"nuxt-4-ssr-performance-optimization","Nuxt 4 SSR Performance Optimization",[102,8450,8451,8453],{},[105,8452,107],{}," February 2026",[102,8455,8456],{},[105,8457,111],{},[113,8459,8460,8463,8466,8469],{},[116,8461,8462],{},"Enhanced with Core Web Vitals optimization strategies",[116,8464,8465],{},"Added detailed caching configuration examples",[116,8467,8468],{},"Expanded monitoring and measurement section",[116,8470,8471],{},"Updated for Nuxt 4.0+ latest features",[102,8473,8474],{},"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.",[102,8476,8477],{},"After deploying multiple Nuxt 4 applications to production, I've identified key strategies that consistently deliver measurable performance improvements.",[98,8479,8481],{"id":8480},"understanding-nuxt-4-ssr-architecture","Understanding Nuxt 4 SSR Architecture",[102,8483,8484],{},"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.",[102,8486,8487,8488,224,8490,8492,8493,8496],{},"The most common performance bottleneck I've encountered is data fetching. In Nuxt 4, ",[221,8489,223],{},[221,8491,227],{}," 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 ",[221,8494,8495],{},"app.vue"," with a long cache time prevents repeated database queries on every page request.",[98,8498,8500],{"id":8499},"essential-optimization-strategies","Essential Optimization Strategies",[191,8502,8504],{"id":8503},"implement-smart-caching","Implement Smart Caching",[102,8506,8507],{},"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%.",[303,8509,8511],{"className":729,"code":8510,"language":731,"meta":308,"style":308},"// In nuxt.config.ts\nexport default defineNuxtConfig({\n routeRules: {\n \"/blog/**\": { isr: 86400 }, // 24 hours\n \"/\": { isr: 300 }, // 5 minutes\n \"/api/**\": {\n cors: true,\n headers: { \"Cache-Control\": \"public, max-age=3600\" },\n },\n },\n})\n",[221,8512,8513,8518,8530,8539,8566,8591,8604,8615,8643,8647,8651],{"__ignoreMap":308},[312,8514,8515],{"class":314,"line":315},[312,8516,8517],{"class":318},"// In nuxt.config.ts\n",[312,8519,8520,8522,8524,8526,8528],{"class":314,"line":322},[312,8521,739],{"class":738},[312,8523,742],{"class":738},[312,8525,746],{"class":745},[312,8527,750],{"class":749},[312,8529,653],{"class":652},[312,8531,8532,8535,8537],{"class":314,"line":16},[312,8533,8534],{"class":757}," routeRules",[312,8536,668],{"class":652},[312,8538,671],{"class":652},[312,8540,8541,8543,8546,8548,8550,8552,8555,8557,8560,8563],{"class":314,"line":342},[312,8542,676],{"class":652},[312,8544,8545],{"class":757},"/blog/**",[312,8547,665],{"class":652},[312,8549,668],{"class":652},[312,8551,1089],{"class":652},[312,8553,8554],{"class":757}," isr",[312,8556,668],{"class":652},[312,8558,8559],{"class":1842}," 86400",[312,8561,8562],{"class":652}," },",[312,8564,8565],{"class":318}," // 24 hours\n",[312,8567,8568,8570,8573,8575,8577,8579,8581,8583,8586,8588],{"class":314,"line":348},[312,8569,676],{"class":652},[312,8571,8572],{"class":757},"/",[312,8574,665],{"class":652},[312,8576,668],{"class":652},[312,8578,1089],{"class":652},[312,8580,8554],{"class":757},[312,8582,668],{"class":652},[312,8584,8585],{"class":1842}," 300",[312,8587,8562],{"class":652},[312,8589,8590],{"class":318}," // 5 minutes\n",[312,8592,8593,8595,8598,8600,8602],{"class":314,"line":360},[312,8594,676],{"class":652},[312,8596,8597],{"class":757},"/api/**",[312,8599,665],{"class":652},[312,8601,668],{"class":652},[312,8603,671],{"class":652},[312,8605,8606,8609,8611,8613],{"class":314,"line":365},[312,8607,8608],{"class":757}," cors",[312,8610,668],{"class":652},[312,8612,932],{"class":931},[312,8614,776],{"class":652},[312,8616,8617,8620,8622,8624,8626,8629,8631,8633,8635,8638,8640],{"class":314,"line":371},[312,8618,8619],{"class":757}," headers",[312,8621,668],{"class":652},[312,8623,1089],{"class":652},[312,8625,686],{"class":652},[312,8627,8628],{"class":757},"Cache-Control",[312,8630,665],{"class":652},[312,8632,668],{"class":652},[312,8634,686],{"class":652},[312,8636,8637],{"class":329},"public, max-age=3600",[312,8639,665],{"class":652},[312,8641,8642],{"class":652}," },\n",[312,8644,8645],{"class":314,"line":382},[312,8646,815],{"class":652},[312,8648,8649],{"class":314,"line":392},[312,8650,820],{"class":652},[312,8652,8653,8655],{"class":314,"line":937},[312,8654,825],{"class":652},[312,8656,828],{"class":749},[191,8658,8660],{"id":8659},"optimize-data-fetching-patterns","Optimize Data Fetching Patterns",[102,8662,8663,8664,8666,8667,8670,8671,224,8674,8677],{},"Proper data fetching patterns significantly impact SSR performance. Always use ",[221,8665,223],{}," with a unique key to enable request deduplication. When fetching multiple independent data sources, use ",[221,8668,8669],{},"Promise.all"," to parallelize requests instead of awaiting them sequentially. Additionally, leverage ",[221,8672,8673],{},"pick",[221,8675,8676],{},"transform"," options to minimize payload size—sending only the data you need reduces both network transfer and processing time.",[191,8679,8681],{"id":8680},"leverage-static-generation-where-possible","Leverage Static Generation Where Possible",[102,8683,8684],{},"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.",[98,8686,8688],{"id":8687},"measuring-and-monitoring-performance","Measuring and Monitoring Performance",[102,8690,8691],{},"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.",[102,8693,8694],{},"Set up performance budgets in your CI/CD 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.",[98,8696,8698],{"id":8697},"faq-nuxt-4-ssr-performance","FAQ: Nuxt 4 SSR Performance",[191,8700,8702],{"id":8701},"what-is-the-most-impactful-ssr-optimization-for-nuxt-4","What is the most impactful SSR optimization for Nuxt 4?",[102,8704,8705,8708],{},[105,8706,8707],{},"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.",[191,8710,8712],{"id":8711},"how-do-i-improve-core-web-vitals-with-nuxt-4","How do I improve Core Web Vitals with Nuxt 4?",[102,8714,8715],{},"Focus on these key areas:",[113,8717,8718,8724,8730],{},[116,8719,8720,8723],{},[105,8721,8722],{},"LCP (Largest Contentful Paint)",": Use ISR, optimize images, implement smart caching",[116,8725,8726,8729],{},[105,8727,8728],{},"FID (First Input Delay)",": Code splitting, reduce JavaScript bundle size",[116,8731,8732,8735],{},[105,8733,8734],{},"CLS (Cumulative Layout Shift)",": Reserve space for images and dynamic content, use skeleton loaders",[102,8737,8738],{},"Nuxt 4's hybrid rendering and Nitro caching make achieving good Core Web Vitals significantly easier than previous versions.",[191,8740,8742],{"id":8741},"should-i-use-ssr-or-static-generation-for-my-nuxt-app","Should I use SSR or static generation for my Nuxt app?",[102,8744,7150,8745,8748],{},[105,8746,8747],{},"hybrid rendering"," based on page requirements:",[113,8750,8751,8757,8763],{},[116,8752,8753,8756],{},[105,8754,8755],{},"Static generation (prerender)",": Blog posts, documentation, marketing pages",[116,8758,8759,8762],{},[105,8760,8761],{},"ISR (Incremental Static Regeneration)",": Homepage, category pages, product listings",[116,8764,8765,8768],{},[105,8766,8767],{},"Full SSR",": User dashboards, real-time data, personalized content",[102,8770,8771,8772,8775],{},"Nuxt 4's ",[221,8773,8774],{},"routeRules"," make it easy to mix strategies in a single application.",[191,8777,8779],{"id":8778},"why-is-my-nuxt-app-slow-despite-using-ssr","Why is my Nuxt app slow despite using SSR?",[102,8781,8782],{},"Common causes:",[152,8784,8785,8791,8800,8806,8812],{},[116,8786,8787,8790],{},[105,8788,8789],{},"No caching",": Every request hits the server",[116,8792,8793,8796,8797,8799],{},[105,8794,8795],{},"Sequential data fetching",": Not using ",[221,8798,8669],{}," for parallel requests",[116,8801,8802,8805],{},[105,8803,8804],{},"Over-fetching",": Loading more data than needed",[116,8807,8808,8811],{},[105,8809,8810],{},"Large bundles",": Not code splitting effectively",[116,8813,8814,8817],{},[105,8815,8816],{},"Database bottlenecks",": Missing database query optimization",[102,8819,8820],{},"Start by implementing caching—it typically provides 50-80% performance improvement.",[191,8822,8824],{"id":8823},"how-do-i-monitor-ssr-performance-in-production","How do I monitor SSR performance in production?",[102,8826,8827],{},"Use these tools and metrics:",[113,8829,8830,8836,8842,8848,8854],{},[116,8831,8832,8835],{},[105,8833,8834],{},"Nuxt DevTools",": Local development performance",[116,8837,8838,8841],{},[105,8839,8840],{},"Sentry",": Error tracking and performance monitoring",[116,8843,8844,8847],{},[105,8845,8846],{},"Google Analytics 4",": Real user monitoring (RUM)",[116,8849,8850,8853],{},[105,8851,8852],{},"Lighthouse CI",": Automated performance budgets in CI/CD",[116,8855,8856,8859],{},[105,8857,8858],{},"Nitro server logs",": TTFB and server response times",[102,8861,8862],{},"Key metrics to track: TTFB <200ms, LCP <2.5s, FID <100ms, CLS <0.1.",[142,8864],{},[98,8866,3197],{"id":3196},[102,8868,8869],{},"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.",[102,8871,8872],{},"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.",[102,8874,8875],{},[105,8876,8319],{},[113,8878,8879,8883,8888],{},[116,8880,8881],{},[2810,8882,6237],{"href":2968},[116,8884,8885],{},[2810,8886,8887],{"href":8429},"AI SEO for Developer Blogs",[116,8889,8890],{},[2810,8891,2832],{"href":2822},[2892,8893,8894],{},"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":308,"searchDepth":322,"depth":322,"links":8896},[8897,8898,8899,8904,8905,8912],{"id":8447,"depth":322,"text":8448},{"id":8480,"depth":322,"text":8481},{"id":8499,"depth":322,"text":8500,"children":8900},[8901,8902,8903],{"id":8503,"depth":16,"text":8504},{"id":8659,"depth":16,"text":8660},{"id":8680,"depth":16,"text":8681},{"id":8687,"depth":322,"text":8688},{"id":8697,"depth":322,"text":8698,"children":8906},[8907,8908,8909,8910,8911],{"id":8701,"depth":16,"text":8702},{"id":8711,"depth":16,"text":8712},{"id":8741,"depth":16,"text":8742},{"id":8778,"depth":16,"text":8779},{"id":8823,"depth":16,"text":8824},{"id":3196,"depth":322,"text":3197},"2026-02-22","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":3232,"keywords":8916},[8917,8918,8919,8920,8921,8922,8923,8924,8925,8926],"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",{"title":8442,"description":8914},{"src":8929,"mime":2974,"alt":8930,"width":2976,"height":2977},"/img/blog/16-nuxt-4-ssr-performance-optimization/banner.svg","Nuxt 4 SSR Performance Optimization - Lightning-fast page loads with speedometer and lightning bolt icons on green gradient background","blog/16-nuxt-4-ssr-performance-optimization",[2980,8933,8934,8935,8936,8937],"Vue.js","SSR","Performance","Optimization","Core Web Vitals","XhRUZiLhn6SJsObNSFfkCf0T1Lb4RVB7phsNfmDX75E",[8940,10057,12873],{"id":8941,"title":8942,"abstract":92,"author":93,"authorUrl":92,"body":8943,"date":10040,"dateUpdated":10040,"description":10041,"excerpt":92,"extension":2954,"featured":338,"headline":92,"image":92,"meta":10042,"navigation":338,"ogImage":92,"path":10044,"seo":10045,"series":10046,"seriesDescription":10047,"seriesOrder":315,"socialImage":10048,"stem":10051,"tags":10052,"__hash__":10056},"blog/blog/26-meta-frameworks-new-default-2026.md","Meta-Frameworks in 2026: The New Default for Web Development",{"type":95,"value":8944,"toc":10013},[8945,8948,8951,8954,8958,8961,8999,9003,9007,9010,9094,9097,9114,9118,9121,9153,9157,9160,9174,9178,9182,9188,9290,9295,9309,9312,9317,9357,9361,9375,9379,9384,9430,9434,9448,9452,9457,9518,9522,9536,9540,9625,9629,9633,9670,9674,9701,9705,9709,9793,9797,9867,9871,9962,9966,9969,9995,9997,10000,10003,10005,10010],[98,8946,8942],{"id":8947},"meta-frameworks-in-2026-the-new-default-for-web-development",[102,8949,8950],{},"The debate is over. In 2026, meta-frameworks have become the undisputed standard for web development. Whether you're building a simple blog or a complex enterprise application, frameworks like Next.js, Nuxt, SvelteKit, and Remix offer compelling advantages that plain React, Vue, or Svelte simply can't match.",[102,8952,8953],{},"This shift represents more than just convenience—it's a fundamental change in how we think about building web applications. Let's explore why meta-frameworks have become essential and what this means for developers.",[98,8955,8957],{"id":8956},"what-are-meta-frameworks","What Are Meta-Frameworks?",[102,8959,8960],{},"Meta-frameworks are frameworks built on top of existing libraries that provide:",[113,8962,8963,8969,8975,8981,8987,8993],{},[116,8964,8965,8968],{},[105,8966,8967],{},"File-based routing"," with conventions",[116,8970,8971,8974],{},[105,8972,8973],{},"Server-side rendering"," (SSR) out of the box",[116,8976,8977,8980],{},[105,8978,8979],{},"Static site generation"," (SSG) capabilities",[116,8982,8983,8986],{},[105,8984,8985],{},"API routes"," for backend functionality",[116,8988,8989,8992],{},[105,8990,8991],{},"Optimized builds"," with zero configuration",[116,8994,8995,8998],{},[105,8996,8997],{},"Type safety"," across the entire stack",[98,9000,9002],{"id":9001},"why-meta-frameworks-won-in-2026","Why Meta-Frameworks Won in 2026",[191,9004,9006],{"id":9005},"_1-performance-by-default","1. Performance by Default",[102,9008,9009],{},"Meta-frameworks optimize performance automatically:",[303,9011,9013],{"className":729,"code":9012,"language":731,"meta":308,"style":308},"// Nuxt 4 - Automatic code splitting and tree-shaking\n// No manual optimization needed\nexport default defineNuxtComponent({\n setup() {\n const { data } = useFetch(\"/api/data\")\n return { data }\n },\n})\n",[221,9014,9015,9020,9025,9038,9047,9073,9084,9088],{"__ignoreMap":308},[312,9016,9017],{"class":314,"line":315},[312,9018,9019],{"class":318},"// Nuxt 4 - Automatic code splitting and tree-shaking\n",[312,9021,9022],{"class":314,"line":322},[312,9023,9024],{"class":318},"// No manual optimization needed\n",[312,9026,9027,9029,9031,9034,9036],{"class":314,"line":16},[312,9028,739],{"class":738},[312,9030,742],{"class":738},[312,9032,9033],{"class":745}," defineNuxtComponent",[312,9035,750],{"class":749},[312,9037,653],{"class":652},[312,9039,9040,9043,9045],{"class":314,"line":342},[312,9041,9042],{"class":757}," setup",[312,9044,1871],{"class":652},[312,9046,671],{"class":652},[312,9048,9049,9052,9054,9056,9058,9060,9062,9064,9066,9069,9071],{"class":314,"line":348},[312,9050,9051],{"class":661}," const",[312,9053,1089],{"class":652},[312,9055,1301],{"class":749},[312,9057,1340],{"class":652},[312,9059,1097],{"class":652},[312,9061,1103],{"class":745},[312,9063,750],{"class":757},[312,9065,665],{"class":652},[312,9067,9068],{"class":329},"/api/data",[312,9070,665],{"class":652},[312,9072,828],{"class":757},[312,9074,9075,9078,9080,9082],{"class":314,"line":360},[312,9076,9077],{"class":738}," return",[312,9079,1089],{"class":652},[312,9081,1301],{"class":749},[312,9083,1689],{"class":652},[312,9085,9086],{"class":314,"line":365},[312,9087,820],{"class":652},[312,9089,9090,9092],{"class":314,"line":371},[312,9091,825],{"class":652},[312,9093,828],{"class":749},[102,9095,9096],{},"Key performance benefits:",[113,9098,9099,9102,9105,9108,9111],{},[116,9100,9101],{},"Automatic code splitting",[116,9103,9104],{},"Tree-shaking and dead code elimination",[116,9106,9107],{},"Optimized bundle sizes",[116,9109,9110],{},"Built-in image optimization",[116,9112,9113],{},"Smart prefetching",[191,9115,9117],{"id":9116},"_2-developer-experience","2. Developer Experience",[102,9119,9120],{},"The DX improvements are substantial:",[113,9122,9123,9129,9135,9141,9147],{},[116,9124,9125,9128],{},[105,9126,9127],{},"Hot Module Replacement",": Instant updates during development",[116,9130,9131,9134],{},[105,9132,9133],{},"File-based Routing",": No complex routing configuration",[116,9136,9137,9140],{},[105,9138,9139],{},"Auto-imports",": Components and composables imported automatically",[116,9142,9143,9146],{},[105,9144,9145],{},"Type Safety",": End-to-end TypeScript support",[116,9148,9149,9152],{},[105,9150,9151],{},"Dev Tools",": Built-in debugging and performance tools",[191,9154,9156],{"id":9155},"_3-seo-benefits","3. SEO Benefits",[102,9158,9159],{},"Server-side rendering provides crucial SEO advantages:",[113,9161,9162,9165,9168,9171],{},[116,9163,9164],{},"Content rendered on the server for search engines",[116,9166,9167],{},"Faster initial page loads",[116,9169,9170],{},"Better social media previews",[116,9172,9173],{},"Improved Core Web Vitals scores",[98,9175,9177],{"id":9176},"the-major-players-in-2026","The Major Players in 2026",[191,9179,9181],{"id":9180},"nextjs-16","Next.js 16+",[102,9183,9184,9187],{},[105,9185,9186],{},"Best for",": React developers, enterprise applications",[303,9189,9191],{"className":729,"code":9190,"language":731,"meta":308,"style":308},"// Next.js 16 App Router\nexport default async function Page() {\n const data = await fetch('...', { cache: 'force-cache' })\n return
{/* content */}
\n}\n",[221,9192,9193,9198,9217,9260,9286],{"__ignoreMap":308},[312,9194,9195],{"class":314,"line":315},[312,9196,9197],{"class":318},"// Next.js 16 App Router\n",[312,9199,9200,9202,9204,9207,9210,9213,9215],{"class":314,"line":322},[312,9201,739],{"class":738},[312,9203,742],{"class":738},[312,9205,9206],{"class":661}," async",[312,9208,9209],{"class":661}," function",[312,9211,9212],{"class":745}," Page",[312,9214,1871],{"class":652},[312,9216,671],{"class":652},[312,9218,9219,9222,9224,9226,9228,9231,9233,9235,9238,9240,9242,9244,9247,9249,9251,9254,9256,9258],{"class":314,"line":16},[312,9220,9221],{"class":661}," const",[312,9223,1301],{"class":749},[312,9225,1097],{"class":652},[312,9227,1100],{"class":738},[312,9229,9230],{"class":745}," fetch",[312,9232,750],{"class":757},[312,9234,7210],{"class":652},[312,9236,9237],{"class":329},"...",[312,9239,7210],{"class":652},[312,9241,1115],{"class":652},[312,9243,1089],{"class":652},[312,9245,9246],{"class":757}," cache",[312,9248,668],{"class":652},[312,9250,7205],{"class":652},[312,9252,9253],{"class":329},"force-cache",[312,9255,7210],{"class":652},[312,9257,1340],{"class":652},[312,9259,828],{"class":757},[312,9261,9262,9264,9267,9270,9273,9276,9279,9282,9284],{"class":314,"line":342},[312,9263,1666],{"class":738},[312,9265,9266],{"class":757}," <",[312,9268,9269],{"class":325},"div",[312,9271,9272],{"class":757},">",[312,9274,9275],{"class":652},"{",[312,9277,9278],{"class":318},"/* content */",[312,9280,9281],{"class":652},"}\n\n\n{#each data.items as item}\n
{item.name}
\n{/each}\n","svelte",[221,9390,9391,9396,9401,9406,9411,9415,9420,9425],{"__ignoreMap":308},[312,9392,9393],{"class":314,"line":315},[312,9394,9395],{},"\n",[312,9397,9398],{"class":314,"line":322},[312,9399,9400],{},"\n",[312,9412,9413],{"class":314,"line":348},[312,9414,339],{"emptyLinePlaceholder":338},[312,9416,9417],{"class":314,"line":360},[312,9418,9419],{},"{#each data.items as item}\n",[312,9421,9422],{"class":314,"line":365},[312,9423,9424],{},"
{item.name}
\n",[312,9426,9427],{"class":314,"line":371},[312,9428,9429],{},"{/each}\n",[102,9431,9432,668],{},[105,9433,9294],{},[113,9435,9436,9439,9442,9445],{},[116,9437,9438],{},"Minimal runtime",[116,9440,9441],{},"Excellent performance",[116,9443,9444],{},"Simple syntax",[116,9446,9447],{},"Small bundle sizes",[191,9449,9451],{"id":9450},"remix","Remix",[102,9453,9454,9456],{},[105,9455,9186],{},": Data-driven applications, forms",[303,9458,9460],{"className":729,"code":9459,"language":731,"meta":308,"style":308},"// Remix - Form handling\nexport async function action({ request }) {\n const formData = await request.formData()\n // Process form\n}\n",[221,9461,9462,9467,9489,9509,9514],{"__ignoreMap":308},[312,9463,9464],{"class":314,"line":315},[312,9465,9466],{"class":318},"// Remix - Form handling\n",[312,9468,9469,9471,9473,9475,9478,9481,9484,9487],{"class":314,"line":322},[312,9470,739],{"class":738},[312,9472,9206],{"class":661},[312,9474,9209],{"class":661},[312,9476,9477],{"class":745}," action",[312,9479,9480],{"class":652},"({",[312,9482,9483],{"class":1434}," request",[312,9485,9486],{"class":652}," })",[312,9488,671],{"class":652},[312,9490,9491,9493,9496,9498,9500,9502,9504,9507],{"class":314,"line":16},[312,9492,9221],{"class":661},[312,9494,9495],{"class":749}," formData",[312,9497,1097],{"class":652},[312,9499,1100],{"class":738},[312,9501,9483],{"class":749},[312,9503,1451],{"class":652},[312,9505,9506],{"class":745},"formData",[312,9508,1566],{"class":757},[312,9510,9511],{"class":314,"line":342},[312,9512,9513],{"class":318}," // Process form\n",[312,9515,9516],{"class":314,"line":348},[312,9517,702],{"class":652},[102,9519,9520,668],{},[105,9521,9294],{},[113,9523,9524,9527,9530,9533],{},[116,9525,9526],{},"Web standards focus",[116,9528,9529],{},"Excellent form handling",[116,9531,9532],{},"Progressive enhancement",[116,9534,9535],{},"Nested routing",[98,9537,9539],{"id":9538},"real-world-performance-comparison","Real-World Performance Comparison",[2605,9541,9542,9558],{},[2608,9543,9544],{},[2611,9545,9546,9549,9551,9553,9555],{},[2614,9547,9548],{},"Framework",[2614,9550,2698],{},[2614,9552,2682],{},[2614,9554,2666],{},[2614,9556,9557],{},"FID",[2627,9559,9560,9577,9593,9608],{},[2611,9561,9562,9565,9568,9571,9574],{},[2632,9563,9564],{},"Next.js 16",[2632,9566,9567],{},"1.2s",[2632,9569,9570],{},"145KB",[2632,9572,9573],{},"1.5s",[2632,9575,9576],{},"15ms",[2611,9578,9579,9581,9584,9587,9590],{},[2632,9580,2622],{},[2632,9582,9583],{},"1.1s",[2632,9585,9586],{},"132KB",[2632,9588,9589],{},"1.4s",[2632,9591,9592],{},"12ms",[2611,9594,9595,9597,9600,9603,9605],{},[2632,9596,9378],{},[2632,9598,9599],{},"0.9s",[2632,9601,9602],{},"85KB",[2632,9604,9583],{},[2632,9606,9607],{},"10ms",[2611,9609,9610,9613,9616,9619,9622],{},[2632,9611,9612],{},"React SPA",[2632,9614,9615],{},"2.5s",[2632,9617,9618],{},"250KB",[2632,9620,9621],{},"2.8s",[2632,9623,9624],{},"45ms",[98,9626,9628],{"id":9627},"migration-strategies","Migration Strategies",[191,9630,9632],{"id":9631},"from-create-react-app","From Create React App",[303,9634,9636],{"className":305,"code":9635,"language":307,"meta":308,"style":308},"# Using create-next-app\nnpx create-next-app@latest my-app\n# Or use codemods for automatic migration\nnpx @next/codemod@latest react-to-next my-app\n",[221,9637,9638,9643,9653,9658],{"__ignoreMap":308},[312,9639,9640],{"class":314,"line":315},[312,9641,9642],{"class":318},"# Using create-next-app\n",[312,9644,9645,9647,9650],{"class":314,"line":322},[312,9646,326],{"class":325},[312,9648,9649],{"class":329}," create-next-app@latest",[312,9651,9652],{"class":329}," my-app\n",[312,9654,9655],{"class":314,"line":16},[312,9656,9657],{"class":318},"# Or use codemods for automatic migration\n",[312,9659,9660,9662,9665,9668],{"class":314,"line":342},[312,9661,326],{"class":325},[312,9663,9664],{"class":329}," @next/codemod@latest",[312,9666,9667],{"class":329}," react-to-next",[312,9669,9652],{"class":329},[191,9671,9673],{"id":9672},"from-vue-cli","From Vue CLI",[303,9675,9677],{"className":305,"code":9676,"language":307,"meta":308,"style":308},"# Migrate to Nuxt 4\nnpx nuxi@latest init my-app\n# Follow migration guide for Vue 3 composition API\n",[221,9678,9679,9684,9696],{"__ignoreMap":308},[312,9680,9681],{"class":314,"line":315},[312,9682,9683],{"class":318},"# Migrate to Nuxt 4\n",[312,9685,9686,9688,9691,9694],{"class":314,"line":322},[312,9687,326],{"class":325},[312,9689,9690],{"class":329}," nuxi@latest",[312,9692,9693],{"class":329}," init",[312,9695,9652],{"class":329},[312,9697,9698],{"class":314,"line":16},[312,9699,9700],{"class":318},"# Follow migration guide for Vue 3 composition API\n",[98,9702,9704],{"id":9703},"best-practices-for-2026","Best Practices for 2026",[191,9706,9708],{"id":9707},"_1-embrace-server-components","1. Embrace Server Components",[303,9710,9712],{"className":729,"code":9711,"language":731,"meta":308,"style":308},"// Server Component - runs on server only\nexport default async function ServerComponent() {\n const data = await db.query('SELECT * FROM ...')\n return \n}\n",[221,9713,9714,9719,9736,9765,9789],{"__ignoreMap":308},[312,9715,9716],{"class":314,"line":315},[312,9717,9718],{"class":318},"// Server Component - runs on server only\n",[312,9720,9721,9723,9725,9727,9729,9732,9734],{"class":314,"line":322},[312,9722,739],{"class":738},[312,9724,742],{"class":738},[312,9726,9206],{"class":661},[312,9728,9209],{"class":661},[312,9730,9731],{"class":745}," ServerComponent",[312,9733,1871],{"class":652},[312,9735,671],{"class":652},[312,9737,9738,9740,9742,9744,9746,9749,9751,9754,9756,9758,9761,9763],{"class":314,"line":16},[312,9739,9221],{"class":661},[312,9741,1301],{"class":749},[312,9743,1097],{"class":652},[312,9745,1100],{"class":738},[312,9747,9748],{"class":749}," db",[312,9750,1451],{"class":652},[312,9752,9753],{"class":745},"query",[312,9755,750],{"class":757},[312,9757,7210],{"class":652},[312,9759,9760],{"class":329},"SELECT * FROM ...",[312,9762,7210],{"class":652},[312,9764,828],{"class":757},[312,9766,9767,9769,9771,9774,9776,9779,9782,9784,9787],{"class":314,"line":342},[312,9768,1666],{"class":738},[312,9770,9266],{"class":652},[312,9772,9773],{"class":325},"ClientComponent",[312,9775,1301],{"class":325},[312,9777,9778],{"class":652},"={",[312,9780,9781],{"class":757},"data",[312,9783,825],{"class":652},[312,9785,9786],{"class":757}," /",[312,9788,7187],{"class":652},[312,9790,9791],{"class":314,"line":348},[312,9792,702],{"class":757},[191,9794,9796],{"id":9795},"_2-optimize-data-fetching","2. Optimize Data Fetching",[303,9798,9800],{"className":729,"code":9799,"language":731,"meta":308,"style":308},"// Use appropriate caching strategies\nconst { data } = await useFetch(\"/api/data\", {\n cache: \"force-cache\", // Static\n // cache: 'no-store', // Dynamic\n})\n",[221,9801,9802,9807,9835,9853,9861],{"__ignoreMap":308},[312,9803,9804],{"class":314,"line":315},[312,9805,9806],{"class":318},"// Use appropriate caching strategies\n",[312,9808,9809,9811,9813,9815,9817,9819,9821,9823,9825,9827,9829,9831,9833],{"class":314,"line":322},[312,9810,1086],{"class":661},[312,9812,1089],{"class":652},[312,9814,1092],{"class":749},[312,9816,825],{"class":652},[312,9818,1097],{"class":652},[312,9820,1100],{"class":738},[312,9822,1103],{"class":745},[312,9824,750],{"class":749},[312,9826,665],{"class":652},[312,9828,9068],{"class":329},[312,9830,665],{"class":652},[312,9832,1115],{"class":652},[312,9834,671],{"class":652},[312,9836,9837,9840,9842,9844,9846,9848,9850],{"class":314,"line":16},[312,9838,9839],{"class":757}," cache",[312,9841,668],{"class":652},[312,9843,686],{"class":652},[312,9845,9253],{"class":329},[312,9847,665],{"class":652},[312,9849,1115],{"class":652},[312,9851,9852],{"class":318}," // Static\n",[312,9854,9855,9858],{"class":314,"line":342},[312,9856,9857],{"class":318}," // cache: 'no-store',",[312,9859,9860],{"class":318}," // Dynamic\n",[312,9862,9863,9865],{"class":314,"line":348},[312,9864,825],{"class":652},[312,9866,828],{"class":749},[191,9868,9870],{"id":9869},"_3-implement-proper-error-handling","3. Implement Proper Error Handling",[303,9872,9874],{"className":729,"code":9873,"language":731,"meta":308,"style":308},"// Error boundaries and error pages\nexport default defineComponent({\n setup() {\n const { error } = useAsyncData()\n if (error) return \n }\n})\n",[221,9875,9876,9881,9894,9902,9920,9953,9957],{"__ignoreMap":308},[312,9877,9878],{"class":314,"line":315},[312,9879,9880],{"class":318},"// Error boundaries and error pages\n",[312,9882,9883,9885,9887,9890,9892],{"class":314,"line":322},[312,9884,739],{"class":738},[312,9886,742],{"class":738},[312,9888,9889],{"class":745}," defineComponent",[312,9891,750],{"class":749},[312,9893,653],{"class":652},[312,9895,9896,9898,9900],{"class":314,"line":16},[312,9897,9042],{"class":757},[312,9899,1871],{"class":652},[312,9901,671],{"class":652},[312,9903,9904,9906,9908,9911,9913,9915,9918],{"class":314,"line":342},[312,9905,9051],{"class":661},[312,9907,1089],{"class":652},[312,9909,9910],{"class":749}," error",[312,9912,1340],{"class":652},[312,9914,1097],{"class":652},[312,9916,9917],{"class":745}," useAsyncData",[312,9919,1566],{"class":757},[312,9921,9922,9925,9927,9930,9933,9936,9938,9941,9943,9945,9947,9949,9951],{"class":314,"line":348},[312,9923,9924],{"class":738}," if",[312,9926,1830],{"class":757},[312,9928,9929],{"class":749},"error",[312,9931,9932],{"class":757},") ",[312,9934,9935],{"class":738},"return",[312,9937,9266],{"class":652},[312,9939,9940],{"class":325},"ErrorPage",[312,9942,9910],{"class":325},[312,9944,9778],{"class":652},[312,9946,9929],{"class":757},[312,9948,825],{"class":652},[312,9950,9786],{"class":757},[312,9952,7187],{"class":652},[312,9954,9955],{"class":314,"line":360},[312,9956,697],{"class":757},[312,9958,9959],{"class":314,"line":365},[312,9960,9961],{"class":757},"})\n",[98,9963,9965],{"id":9964},"the-future-of-meta-frameworks","The Future of Meta-Frameworks",[102,9967,9968],{},"Looking ahead, we expect:",[152,9970,9971,9977,9983,9989],{},[116,9972,9973,9976],{},[105,9974,9975],{},"Edge Computing",": More edge-native features",[116,9978,9979,9982],{},[105,9980,9981],{},"AI Integration",": Built-in AI capabilities",[116,9984,9985,9988],{},[105,9986,9987],{},"Better DX",": Even more automation and conventions",[116,9990,9991,9994],{},[105,9992,9993],{},"Unified APIs",": Standardization across frameworks",[98,9996,3197],{"id":3196},[102,9998,9999],{},"Meta-frameworks have won because they solve real problems: performance, SEO, developer experience, and maintainability. Whether you choose Next.js, Nuxt, SvelteKit, or another framework, the meta-framework approach is now the standard for good reason.",[102,10001,10002],{},"The question is no longer \"Should I use a meta-framework?\" but \"Which meta-framework is right for my project?\"",[142,10004],{},[102,10006,10007,10009],{},[105,10008,2889],{}," Start with a new project or a non-critical section of your application. The learning curve is gentle, and the benefits are immediate.",[2892,10011,10012],{},"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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}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 .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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}",{"title":308,"searchDepth":322,"depth":322,"links":10014},[10015,10016,10017,10022,10028,10029,10033,10038,10039],{"id":8947,"depth":322,"text":8942},{"id":8956,"depth":322,"text":8957},{"id":9001,"depth":322,"text":9002,"children":10018},[10019,10020,10021],{"id":9005,"depth":16,"text":9006},{"id":9116,"depth":16,"text":9117},{"id":9155,"depth":16,"text":9156},{"id":9176,"depth":322,"text":9177,"children":10023},[10024,10025,10026,10027],{"id":9180,"depth":16,"text":9181},{"id":9311,"depth":16,"text":2622},{"id":9377,"depth":16,"text":9378},{"id":9450,"depth":16,"text":9451},{"id":9538,"depth":322,"text":9539},{"id":9627,"depth":322,"text":9628,"children":10030},[10031,10032],{"id":9631,"depth":16,"text":9632},{"id":9672,"depth":16,"text":9673},{"id":9703,"depth":322,"text":9704,"children":10034},[10035,10036,10037],{"id":9707,"depth":16,"text":9708},{"id":9795,"depth":16,"text":9796},{"id":9869,"depth":16,"text":9870},{"id":9964,"depth":322,"text":9965},{"id":3196,"depth":322,"text":3197},"2026-02-23","Discover why meta-frameworks like Next.js, Nuxt, and SvelteKit have become the default choice for web development in 2026.",{"readingTime":10043},"8 min read","/blog/26-meta-frameworks-new-default-2026",{"title":8942,"description":10041},"Modern Web Development","Exploring the latest in web framework technology",{"src":10049,"mime":2974,"alt":10050,"width":2976,"height":2977},"/img/blog/26-meta-frameworks-new-default-2026/banner.svg","Meta-Frameworks 2026 - Modern framework logos connected in network on dark gradient background","blog/26-meta-frameworks-new-default-2026",[10053,10054,2980,10055,2984],"Meta-Frameworks","Next.js","SvelteKit","8iJs8iUFApsYayvqX9yXG9_wUixKKAiyYmRvfxBOuNI",{"id":10058,"title":10059,"abstract":10060,"author":93,"authorUrl":10061,"body":10062,"date":12853,"dateUpdated":12853,"description":12854,"excerpt":92,"extension":2954,"featured":338,"headline":10059,"image":92,"meta":12855,"navigation":338,"ogImage":92,"path":12857,"seo":12858,"series":12859,"seriesDescription":12860,"seriesOrder":16,"socialImage":12861,"stem":12865,"tags":12866,"__hash__":12872},"blog/blog/39-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.","https://mubaidr.js.org",{"type":95,"value":10063,"toc":12839},[10064,10067,10070,10073,10076,10080,10083,10109,10112,10115,10119,10123,10126,10129,10253,10256,10260,10263,10266,10269,10272,10555,11269,11272,11276,11279,11282,11285,11610,12300,12303,12307,12310,12313,12327,12330,12333,12353,12662,12665,12669,12774,12777,12781,12784,12787,12804,12807,12810,12814,12817,12820,12823,12827,12830,12833,12836],[98,10065,10059],{"id":10066},"i-stopped-building-features-first-i-now-design-execution-systems-first",[102,10068,10069],{},"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.",[102,10071,10072],{},"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.",[102,10074,10075],{},"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.",[98,10077,10079],{"id":10078},"what-execution-systems-first-means-in-practice","What \"Execution Systems First\" Means in Practice",[102,10081,10082],{},"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:",[113,10084,10085,10091,10097,10103],{},[116,10086,10087,10090],{},[105,10088,10089],{},"Flow",": The sequence of steps that transform input into output",[116,10092,10093,10096],{},[105,10094,10095],{},"State",": What data persists between steps and how transitions happen",[116,10098,10099,10102],{},[105,10100,10101],{},"Failure handling",": What happens when a step errors, times out, or produces invalid data",[116,10104,10105,10108],{},[105,10106,10107],{},"Task boundaries",": Where one responsibility ends and another begins",[102,10110,10111],{},"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.",[102,10113,10114],{},"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.",[98,10116,10118],{"id":10117},"three-pillars-of-execution-system-design","Three Pillars of Execution System Design",[191,10120,10122],{"id":10121},"_1-execution-flow-design","1. Execution Flow Design",[102,10124,10125],{},"Flow design answers one question: what is the complete path from trigger to outcome, including every branch and failure mode?",[102,10127,10128],{},"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.",[303,10130,10134],{"className":10131,"code":10132,"language":10133,"meta":308,"style":308},"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
Set Active State]\n B -->|Upgrade Tier| D[Calculate Proration]\n B -->|Downgrade Tier| E[Schedule Tier Change
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
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
Active Tier Unchanged]\n F --> M[Stop Recurring
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",[221,10135,10136,10141,10146,10151,10156,10161,10166,10170,10175,10180,10185,10190,10195,10200,10205,10210,10214,10219,10224,10229,10234,10238,10243,10248],{"__ignoreMap":308},[312,10137,10138],{"class":314,"line":315},[312,10139,10140],{},"graph TD\n",[312,10142,10143],{"class":314,"line":322},[312,10144,10145],{}," A[Customer Action Triggered] --> B{Action Type?}\n",[312,10147,10148],{"class":314,"line":16},[312,10149,10150],{}," B -->|Subscribe| C[Create Subscription
Set Active State]\n",[312,10152,10153],{"class":314,"line":342},[312,10154,10155],{}," B -->|Upgrade Tier| D[Calculate Proration]\n",[312,10157,10158],{"class":314,"line":348},[312,10159,10160],{}," B -->|Downgrade Tier| E[Schedule Tier Change
Maintain Current Until Period End]\n",[312,10162,10163],{"class":314,"line":360},[312,10164,10165],{}," B -->|Cancel| F[Run Cancellation Flow]\n",[312,10167,10168],{"class":314,"line":365},[312,10169,339],{"emptyLinePlaceholder":338},[312,10171,10172],{"class":314,"line":371},[312,10173,10174],{}," C --> G[Generate Invoice]\n",[312,10176,10177],{"class":314,"line":382},[312,10178,10179],{}," D --> H{Credit Exists?}\n",[312,10181,10182],{"class":314,"line":392},[312,10183,10184],{}," H -->|Yes| I[Apply Credit
Generate Net Invoice]\n",[312,10186,10187],{"class":314,"line":937},[312,10188,10189],{}," H -->|No| J[Generate Pro-rated Invoice]\n",[312,10191,10192],{"class":314,"line":949},[312,10193,10194],{}," I --> K[Update Subscription State]\n",[312,10196,10197],{"class":314,"line":29},[312,10198,10199],{}," J --> K\n",[312,10201,10202],{"class":314,"line":5837},[312,10203,10204],{}," E --> L[Set Pending Tier
Active Tier Unchanged]\n",[312,10206,10207],{"class":314,"line":5843},[312,10208,10209],{}," F --> M[Stop Recurring
Process Final Invoice]\n",[312,10211,10212],{"class":314,"line":5848},[312,10213,339],{"emptyLinePlaceholder":338},[312,10215,10216],{"class":314,"line":5853},[312,10217,10218],{}," K --> N[Send Notification]\n",[312,10220,10221],{"class":314,"line":5859},[312,10222,10223],{}," L --> N\n",[312,10225,10226],{"class":314,"line":7077},[312,10227,10228],{}," M --> N\n",[312,10230,10231],{"class":314,"line":7093},[312,10232,10233],{}," N --> O[Log Audit Trail]\n",[312,10235,10236],{"class":314,"line":7113},[312,10237,339],{"emptyLinePlaceholder":338},[312,10239,10240],{"class":314,"line":7131},[312,10241,10242],{}," style D fill:#4a6,color:#fff\n",[312,10244,10245],{"class":314,"line":7136},[312,10246,10247],{}," style E fill:#a64,color:#fff\n",[312,10249,10250],{"class":314,"line":7141},[312,10251,10252],{}," style H fill:#47a,color:#fff\n",[102,10254,10255],{},"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.",[191,10257,10259],{"id":10258},"_2-state-management-architecture","2. State Management Architecture",[102,10261,10262],{},"Every execution system has state. The question is whether that state is implicit, scattered, or centrally governed.",[102,10264,10265],{},"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.",[102,10267,10268],{},"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.",[102,10270,10271],{},"For Laravel applications, I use a state machine pattern built on Eloquent enums and a dedicated state machine service:",[303,10273,10277],{"className":10274,"code":10275,"language":10276,"meta":308,"style":308},"language-php shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","// Before: feature-first billing with scattered state\nclass SubscriptionController extends Controller\n{\n public function upgrade(Request $request, Subscription $subscription)\n {\n // State lives in multiple places\n $subscription->plan_id = $request->plan_id;\n $subscription->save();\n\n // 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 // Notification coupled to controller logic\n $subscription->user->notify(new UpgradeConfirmation($subscription));\n\n return redirect()->route('subscription.show', $subscription);\n }\n}\n","php",[221,10278,10279,10284,10298,10302,10334,10338,10343,10370,10384,10388,10393,10416,10434,10456,10468,10473,10477,10482,10512,10516,10547,10551],{"__ignoreMap":308},[312,10280,10281],{"class":314,"line":315},[312,10282,10283],{"class":318},"// Before: feature-first billing with scattered state\n",[312,10285,10286,10289,10292,10295],{"class":314,"line":322},[312,10287,10288],{"class":661},"class",[312,10290,10291],{"class":325}," SubscriptionController",[312,10293,10294],{"class":661}," extends",[312,10296,10297],{"class":325}," Controller\n",[312,10299,10300],{"class":314,"line":16},[312,10301,653],{"class":652},[312,10303,10304,10307,10309,10311,10313,10316,10319,10322,10324,10327,10329,10332],{"class":314,"line":342},[312,10305,10306],{"class":661}," public",[312,10308,9209],{"class":661},[312,10310,420],{"class":745},[312,10312,750],{"class":652},[312,10314,10315],{"class":325},"Request",[312,10317,10318],{"class":652}," $",[312,10320,10321],{"class":749},"request",[312,10323,1115],{"class":652},[312,10325,10326],{"class":325}," Subscription",[312,10328,10318],{"class":652},[312,10330,10331],{"class":749},"subscription",[312,10333,828],{"class":652},[312,10335,10336],{"class":314,"line":348},[312,10337,6724],{"class":652},[312,10339,10340],{"class":314,"line":360},[312,10341,10342],{"class":318}," // State lives in multiple places\n",[312,10344,10345,10348,10350,10353,10356,10358,10360,10362,10364,10367],{"class":314,"line":365},[312,10346,10347],{"class":652}," $",[312,10349,10331],{"class":749},[312,10351,10352],{"class":652},"->",[312,10354,10355],{"class":749},"plan_id ",[312,10357,1799],{"class":652},[312,10359,10318],{"class":652},[312,10361,10321],{"class":749},[312,10363,10352],{"class":652},[312,10365,10366],{"class":749},"plan_id",[312,10368,10369],{"class":652},";\n",[312,10371,10372,10374,10376,10378,10381],{"class":314,"line":371},[312,10373,10347],{"class":652},[312,10375,10331],{"class":749},[312,10377,10352],{"class":652},[312,10379,10380],{"class":745},"save",[312,10382,10383],{"class":652},"();\n",[312,10385,10386],{"class":314,"line":382},[312,10387,339],{"emptyLinePlaceholder":338},[312,10389,10390],{"class":314,"line":392},[312,10391,10392],{"class":318}," // Proration logic embedded in controller\n",[312,10394,10395,10397,10400,10402,10405,10408,10411,10413],{"class":314,"line":937},[312,10396,10347],{"class":652},[312,10398,10399],{"class":749},"credit ",[312,10401,1799],{"class":652},[312,10403,10404],{"class":652}," $this->",[312,10406,10407],{"class":745},"calculateProrationCredit",[312,10409,10410],{"class":652},"($",[312,10412,10331],{"class":749},[312,10414,10415],{"class":652},");\n",[312,10417,10418,10421,10424,10426,10428,10430,10432],{"class":314,"line":949},[312,10419,10420],{"class":738}," if",[312,10422,10423],{"class":652}," ($",[312,10425,10399],{"class":749},[312,10427,9272],{"class":652},[312,10429,1843],{"class":1842},[312,10431,1438],{"class":652},[312,10433,671],{"class":652},[312,10435,10436,10439,10441,10443,10446,10449,10451,10454],{"class":314,"line":29},[312,10437,10438],{"class":652}," $",[312,10440,10331],{"class":749},[312,10442,10352],{"class":652},[312,10444,10445],{"class":749},"credit_balance ",[312,10447,10448],{"class":652},"+=",[312,10450,10318],{"class":652},[312,10452,10453],{"class":749},"credit",[312,10455,10369],{"class":652},[312,10457,10458,10460,10462,10464,10466],{"class":314,"line":5837},[312,10459,10438],{"class":652},[312,10461,10331],{"class":749},[312,10463,10352],{"class":652},[312,10465,10380],{"class":745},[312,10467,10383],{"class":652},[312,10469,10470],{"class":314,"line":5843},[312,10471,10472],{"class":652}," }\n",[312,10474,10475],{"class":314,"line":5848},[312,10476,339],{"emptyLinePlaceholder":338},[312,10478,10479],{"class":314,"line":5853},[312,10480,10481],{"class":318}," // Notification coupled to controller logic\n",[312,10483,10484,10486,10488,10490,10492,10494,10497,10499,10502,10505,10507,10509],{"class":314,"line":5859},[312,10485,10347],{"class":652},[312,10487,10331],{"class":749},[312,10489,10352],{"class":652},[312,10491,1686],{"class":749},[312,10493,10352],{"class":652},[312,10495,10496],{"class":745},"notify",[312,10498,750],{"class":652},[312,10500,10501],{"class":1842},"new",[312,10503,10504],{"class":325}," UpgradeConfirmation",[312,10506,10410],{"class":652},[312,10508,10331],{"class":749},[312,10510,10511],{"class":652},"));\n",[312,10513,10514],{"class":314,"line":7077},[312,10515,339],{"emptyLinePlaceholder":338},[312,10517,10518,10521,10524,10527,10530,10532,10534,10537,10539,10541,10543,10545],{"class":314,"line":7093},[312,10519,10520],{"class":738}," return",[312,10522,10523],{"class":745}," redirect",[312,10525,10526],{"class":652},"()->",[312,10528,10529],{"class":745},"route",[312,10531,750],{"class":652},[312,10533,7210],{"class":652},[312,10535,10536],{"class":329},"subscription.show",[312,10538,7210],{"class":652},[312,10540,1115],{"class":652},[312,10542,10318],{"class":652},[312,10544,10331],{"class":749},[312,10546,10415],{"class":652},[312,10548,10549],{"class":314,"line":7113},[312,10550,6823],{"class":652},[312,10552,10553],{"class":314,"line":7131},[312,10554,702],{"class":652},[303,10556,10558],{"className":10274,"code":10557,"language":10276,"meta":308,"style":308},"// 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 // 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 // Calculates proration as a pure function\n $proration = $this->proration->calculate(\n $subscription,\n $newTier,\n $direction\n );\n\n // 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 // Notification is a side-effect, not business logic\n $this->notifications->tierChanged($result);\n\n return $result;\n }\n}\n",[221,10559,10560,10565,10569,10582,10586,10605,10623,10641,10659,10677,10681,10685,10692,10696,10708,10723,10737,10751,10765,10773,10777,10788,10799,10811,10821,10831,10836,10850,10859,10879,10892,10905,10911,10916,10922,10943,10952,10961,10968,10973,10978,10984,11015,11039,11047,11068,11078,11093,11105,11117,11123,11128,11149,11159,11167,11172,11177,11207,11213,11218,11224,11243,11248,11259,11264],{"__ignoreMap":308},[312,10561,10562],{"class":314,"line":315},[312,10563,10564],{"class":318},"// After: execution system with explicit state machine\n",[312,10566,10567],{"class":314,"line":322},[312,10568,339],{"emptyLinePlaceholder":338},[312,10570,10571,10574,10577,10579],{"class":314,"line":16},[312,10572,10573],{"class":661},"enum",[312,10575,10576],{"class":325}," SubscriptionState",[312,10578,668],{"class":652},[312,10580,10581],{"class":1842}," string\n",[312,10583,10584],{"class":314,"line":342},[312,10585,653],{"class":652},[312,10587,10588,10591,10594,10596,10598,10601,10603],{"class":314,"line":348},[312,10589,10590],{"class":661}," case",[312,10592,10593],{"class":749}," Active ",[312,10595,1799],{"class":652},[312,10597,7205],{"class":652},[312,10599,10600],{"class":329},"active",[312,10602,7210],{"class":652},[312,10604,10369],{"class":652},[312,10606,10607,10609,10612,10614,10616,10619,10621],{"class":314,"line":360},[312,10608,10590],{"class":661},[312,10610,10611],{"class":749}," PendingDowngrade ",[312,10613,1799],{"class":652},[312,10615,7205],{"class":652},[312,10617,10618],{"class":329},"pending_downgrade",[312,10620,7210],{"class":652},[312,10622,10369],{"class":652},[312,10624,10625,10627,10630,10632,10634,10637,10639],{"class":314,"line":365},[312,10626,10590],{"class":661},[312,10628,10629],{"class":749}," PendingUpgrade ",[312,10631,1799],{"class":652},[312,10633,7205],{"class":652},[312,10635,10636],{"class":329},"pending_upgrade",[312,10638,7210],{"class":652},[312,10640,10369],{"class":652},[312,10642,10643,10645,10648,10650,10652,10655,10657],{"class":314,"line":371},[312,10644,10590],{"class":661},[312,10646,10647],{"class":749}," Canceled ",[312,10649,1799],{"class":652},[312,10651,7205],{"class":652},[312,10653,10654],{"class":329},"canceled",[312,10656,7210],{"class":652},[312,10658,10369],{"class":652},[312,10660,10661,10663,10666,10668,10670,10673,10675],{"class":314,"line":382},[312,10662,10590],{"class":661},[312,10664,10665],{"class":749}," PastDue ",[312,10667,1799],{"class":652},[312,10669,7205],{"class":652},[312,10671,10672],{"class":329},"past_due",[312,10674,7210],{"class":652},[312,10676,10369],{"class":652},[312,10678,10679],{"class":314,"line":392},[312,10680,702],{"class":652},[312,10682,10683],{"class":314,"line":937},[312,10684,339],{"emptyLinePlaceholder":338},[312,10686,10687,10689],{"class":314,"line":949},[312,10688,10288],{"class":661},[312,10690,10691],{"class":325}," SubscriptionExecutionService\n",[312,10693,10694],{"class":314,"line":29},[312,10695,653],{"class":652},[312,10697,10698,10700,10702,10705],{"class":314,"line":5837},[312,10699,10306],{"class":661},[312,10701,9209],{"class":661},[312,10703,10704],{"class":745}," __construct",[312,10706,10707],{"class":652},"(\n",[312,10709,10710,10713,10716,10718,10721],{"class":314,"line":5843},[312,10711,10712],{"class":661}," private",[312,10714,10715],{"class":325}," SubscriptionStateMachine",[312,10717,10318],{"class":652},[312,10719,10720],{"class":749},"stateMachine",[312,10722,776],{"class":652},[312,10724,10725,10727,10730,10732,10735],{"class":314,"line":5848},[312,10726,10712],{"class":661},[312,10728,10729],{"class":325}," ProrationService",[312,10731,10318],{"class":652},[312,10733,10734],{"class":749},"proration",[312,10736,776],{"class":652},[312,10738,10739,10741,10744,10746,10749],{"class":314,"line":5853},[312,10740,10712],{"class":661},[312,10742,10743],{"class":325}," InvoiceService",[312,10745,10318],{"class":652},[312,10747,10748],{"class":749},"invoices",[312,10750,776],{"class":652},[312,10752,10753,10755,10758,10760,10763],{"class":314,"line":5859},[312,10754,10712],{"class":661},[312,10756,10757],{"class":325}," NotificationService",[312,10759,10318],{"class":652},[312,10761,10762],{"class":749},"notifications",[312,10764,776],{"class":652},[312,10766,10767,10770],{"class":314,"line":7077},[312,10768,10769],{"class":652}," )",[312,10771,10772],{"class":652}," {}\n",[312,10774,10775],{"class":314,"line":7093},[312,10776,339],{"emptyLinePlaceholder":338},[312,10778,10779,10781,10783,10786],{"class":314,"line":7113},[312,10780,10306],{"class":661},[312,10782,9209],{"class":661},[312,10784,10785],{"class":745}," executeTierChange",[312,10787,10707],{"class":652},[312,10789,10790,10793,10795,10797],{"class":314,"line":7131},[312,10791,10792],{"class":325}," Subscription",[312,10794,10318],{"class":652},[312,10796,10331],{"class":749},[312,10798,776],{"class":652},[312,10800,10801,10804,10806,10809],{"class":314,"line":7136},[312,10802,10803],{"class":325}," Tier",[312,10805,10318],{"class":652},[312,10807,10808],{"class":749},"newTier",[312,10810,776],{"class":652},[312,10812,10813,10816,10818],{"class":314,"line":7141},[312,10814,10815],{"class":325}," ChangeDirection",[312,10817,10318],{"class":652},[312,10819,10820],{"class":749},"direction\n",[312,10822,10823,10826,10829],{"class":314,"line":7444},[312,10824,10825],{"class":652}," ):",[312,10827,10828],{"class":325}," ExecutionResult",[312,10830,671],{"class":652},[312,10832,10833],{"class":314,"line":7451},[312,10834,10835],{"class":318}," // Validates transition is legal in current state\n",[312,10837,10838,10841,10843,10845,10848],{"class":314,"line":7457},[312,10839,10840],{"class":652}," $this->",[312,10842,10720],{"class":749},[312,10844,10352],{"class":652},[312,10846,10847],{"class":745},"assertCanTransitionTo",[312,10849,10707],{"class":652},[312,10851,10853,10855,10857],{"class":314,"line":10852},28,[312,10854,10438],{"class":652},[312,10856,10331],{"class":749},[312,10858,776],{"class":652},[312,10860,10862,10864,10867,10870,10873,10876],{"class":314,"line":10861},29,[312,10863,10438],{"class":652},[312,10865,10866],{"class":749},"direction ",[312,10868,10869],{"class":652},"===",[312,10871,10872],{"class":325}," ChangeDirection",[312,10874,10875],{"class":652},"::",[312,10877,10878],{"class":749},"Upgrade\n",[312,10880,10882,10885,10887,10889],{"class":314,"line":10881},30,[312,10883,10884],{"class":652}," ?",[312,10886,10576],{"class":325},[312,10888,10875],{"class":652},[312,10890,10891],{"class":749},"PendingUpgrade\n",[312,10893,10895,10898,10900,10902],{"class":314,"line":10894},31,[312,10896,10897],{"class":652}," :",[312,10899,10576],{"class":325},[312,10901,10875],{"class":652},[312,10903,10904],{"class":749},"PendingDowngrade\n",[312,10906,10908],{"class":314,"line":10907},32,[312,10909,10910],{"class":652}," );\n",[312,10912,10914],{"class":314,"line":10913},33,[312,10915,339],{"emptyLinePlaceholder":338},[312,10917,10919],{"class":314,"line":10918},34,[312,10920,10921],{"class":318}," // Calculates proration as a pure function\n",[312,10923,10925,10927,10930,10932,10934,10936,10938,10941],{"class":314,"line":10924},35,[312,10926,10347],{"class":652},[312,10928,10929],{"class":749},"proration ",[312,10931,1799],{"class":652},[312,10933,10404],{"class":652},[312,10935,10734],{"class":749},[312,10937,10352],{"class":652},[312,10939,10940],{"class":745},"calculate",[312,10942,10707],{"class":652},[312,10944,10946,10948,10950],{"class":314,"line":10945},36,[312,10947,10438],{"class":652},[312,10949,10331],{"class":749},[312,10951,776],{"class":652},[312,10953,10955,10957,10959],{"class":314,"line":10954},37,[312,10956,10438],{"class":652},[312,10958,10808],{"class":749},[312,10960,776],{"class":652},[312,10962,10964,10966],{"class":314,"line":10963},38,[312,10965,10438],{"class":652},[312,10967,10820],{"class":749},[312,10969,10971],{"class":314,"line":10970},39,[312,10972,10910],{"class":652},[312,10974,10976],{"class":314,"line":10975},40,[312,10977,339],{"emptyLinePlaceholder":338},[312,10979,10981],{"class":314,"line":10980},41,[312,10982,10983],{"class":318}," // Applies state transition atomically\n",[312,10985,10987,10989,10992,10994,10997,10999,11002,11004,11007,11009,11012],{"class":314,"line":10986},42,[312,10988,10347],{"class":652},[312,10990,10991],{"class":749},"result ",[312,10993,1799],{"class":652},[312,10995,10996],{"class":325}," DB",[312,10998,10875],{"class":652},[312,11000,11001],{"class":745},"transaction",[312,11003,750],{"class":652},[312,11005,11006],{"class":661},"function",[312,11008,1825],{"class":652},[312,11010,11011],{"class":1842}," use",[312,11013,11014],{"class":652}," (\n",[312,11016,11018,11020,11022,11024,11026,11028,11030,11032,11034,11036],{"class":314,"line":11017},43,[312,11019,10438],{"class":652},[312,11021,10331],{"class":749},[312,11023,1115],{"class":652},[312,11025,10318],{"class":652},[312,11027,10808],{"class":749},[312,11029,1115],{"class":652},[312,11031,10318],{"class":652},[312,11033,10734],{"class":749},[312,11035,1115],{"class":652},[312,11037,11038],{"class":749}," $direction\n",[312,11040,11042,11045],{"class":314,"line":11041},44,[312,11043,11044],{"class":652}," )",[312,11046,671],{"class":652},[312,11048,11050,11052,11055,11057,11059,11061,11063,11066],{"class":314,"line":11049},45,[312,11051,10438],{"class":652},[312,11053,11054],{"class":749},"updated ",[312,11056,1799],{"class":652},[312,11058,10404],{"class":652},[312,11060,10720],{"class":749},[312,11062,10352],{"class":652},[312,11064,11065],{"class":745},"transition",[312,11067,10707],{"class":652},[312,11069,11071,11074,11076],{"class":314,"line":11070},46,[312,11072,11073],{"class":652}," $",[312,11075,10331],{"class":749},[312,11077,776],{"class":652},[312,11079,11081,11083,11085,11087,11089,11091],{"class":314,"line":11080},47,[312,11082,11073],{"class":652},[312,11084,10866],{"class":749},[312,11086,10869],{"class":652},[312,11088,10872],{"class":325},[312,11090,10875],{"class":652},[312,11092,10878],{"class":749},[312,11094,11096,11099,11101,11103],{"class":314,"line":11095},48,[312,11097,11098],{"class":652}," ?",[312,11100,10576],{"class":325},[312,11102,10875],{"class":652},[312,11104,10891],{"class":749},[312,11106,11108,11111,11113,11115],{"class":314,"line":11107},49,[312,11109,11110],{"class":652}," :",[312,11112,10576],{"class":325},[312,11114,10875],{"class":652},[312,11116,10904],{"class":749},[312,11118,11120],{"class":314,"line":11119},50,[312,11121,11122],{"class":652}," );\n",[312,11124,11126],{"class":314,"line":11125},51,[312,11127,339],{"emptyLinePlaceholder":338},[312,11129,11131,11133,11136,11138,11140,11142,11144,11147],{"class":314,"line":11130},52,[312,11132,10438],{"class":652},[312,11134,11135],{"class":749},"invoice ",[312,11137,1799],{"class":652},[312,11139,10404],{"class":652},[312,11141,10748],{"class":749},[312,11143,10352],{"class":652},[312,11145,11146],{"class":745},"generate",[312,11148,10707],{"class":652},[312,11150,11152,11154,11157],{"class":314,"line":11151},53,[312,11153,11073],{"class":652},[312,11155,11156],{"class":749},"updated",[312,11158,776],{"class":652},[312,11160,11162,11164],{"class":314,"line":11161},54,[312,11163,11073],{"class":652},[312,11165,11166],{"class":749},"proration\n",[312,11168,11170],{"class":314,"line":11169},55,[312,11171,11122],{"class":652},[312,11173,11175],{"class":314,"line":11174},56,[312,11176,339],{"emptyLinePlaceholder":338},[312,11178,11180,11183,11186,11188,11190,11192,11194,11196,11199,11201,11203,11205],{"class":314,"line":11179},57,[312,11181,11182],{"class":738}," return",[312,11184,11185],{"class":1842}," new",[312,11187,10828],{"class":325},[312,11189,10410],{"class":652},[312,11191,11156],{"class":749},[312,11193,1115],{"class":652},[312,11195,10318],{"class":652},[312,11197,11198],{"class":749},"invoice",[312,11200,1115],{"class":652},[312,11202,10318],{"class":652},[312,11204,10734],{"class":749},[312,11206,10415],{"class":652},[312,11208,11210],{"class":314,"line":11209},58,[312,11211,11212],{"class":652}," });\n",[312,11214,11216],{"class":314,"line":11215},59,[312,11217,339],{"emptyLinePlaceholder":338},[312,11219,11221],{"class":314,"line":11220},60,[312,11222,11223],{"class":318}," // Notification is a side-effect, not business logic\n",[312,11225,11227,11229,11231,11233,11236,11238,11241],{"class":314,"line":11226},61,[312,11228,10840],{"class":652},[312,11230,10762],{"class":749},[312,11232,10352],{"class":652},[312,11234,11235],{"class":745},"tierChanged",[312,11237,10410],{"class":652},[312,11239,11240],{"class":749},"result",[312,11242,10415],{"class":652},[312,11244,11246],{"class":314,"line":11245},62,[312,11247,339],{"emptyLinePlaceholder":338},[312,11249,11251,11253,11255,11257],{"class":314,"line":11250},63,[312,11252,10520],{"class":738},[312,11254,10318],{"class":652},[312,11256,11240],{"class":749},[312,11258,10369],{"class":652},[312,11260,11262],{"class":314,"line":11261},64,[312,11263,6823],{"class":652},[312,11265,11267],{"class":314,"line":11266},65,[312,11268,702],{"class":652},[102,11270,11271],{},"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.",[191,11273,11275],{"id":11274},"_3-task-decomposition","3. Task Decomposition",[102,11277,11278],{},"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.",[102,11280,11281],{},"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.",[102,11283,11284],{},"For Nuxt applications, this maps to composable design:",[303,11286,11288],{"className":729,"code":11287,"language":731,"meta":308,"style":308},"// Feature-first: one composable handles everything\nexport function useCheckout() {\n const { data, error, execute } = useFetch(\"/api/checkout\", {\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",[221,11289,11290,11295,11308,11344,11356,11362,11366,11389,11407,11444,11448,11468,11489,11509,11528,11547,11551,11555,11573,11580,11584,11588,11606],{"__ignoreMap":308},[312,11291,11292],{"class":314,"line":315},[312,11293,11294],{"class":318},"// Feature-first: one composable handles everything\n",[312,11296,11297,11299,11301,11304,11306],{"class":314,"line":322},[312,11298,739],{"class":738},[312,11300,9209],{"class":661},[312,11302,11303],{"class":745}," useCheckout",[312,11305,1871],{"class":652},[312,11307,671],{"class":652},[312,11309,11310,11312,11314,11316,11318,11320,11322,11325,11327,11329,11331,11333,11335,11338,11340,11342],{"class":314,"line":16},[312,11311,9221],{"class":661},[312,11313,1089],{"class":652},[312,11315,1301],{"class":749},[312,11317,1115],{"class":652},[312,11319,9910],{"class":749},[312,11321,1115],{"class":652},[312,11323,11324],{"class":749}," execute",[312,11326,1340],{"class":652},[312,11328,1097],{"class":652},[312,11330,1103],{"class":745},[312,11332,750],{"class":757},[312,11334,665],{"class":652},[312,11336,11337],{"class":329},"/api/checkout",[312,11339,665],{"class":652},[312,11341,1115],{"class":652},[312,11343,671],{"class":652},[312,11345,11346,11349,11351,11354],{"class":314,"line":342},[312,11347,11348],{"class":757}," immediate",[312,11350,668],{"class":652},[312,11352,11353],{"class":931}," false",[312,11355,776],{"class":652},[312,11357,11358,11360],{"class":314,"line":348},[312,11359,1850],{"class":652},[312,11361,828],{"class":757},[312,11363,11364],{"class":314,"line":360},[312,11365,339],{"emptyLinePlaceholder":338},[312,11367,11368,11371,11373,11375,11377,11380,11382,11385,11387],{"class":314,"line":365},[312,11369,11370],{"class":661}," async",[312,11372,9209],{"class":661},[312,11374,530],{"class":745},[312,11376,750],{"class":652},[312,11378,11379],{"class":1434},"cart",[312,11381,668],{"class":652},[312,11383,11384],{"class":325}," Cart",[312,11386,1438],{"class":652},[312,11388,671],{"class":652},[312,11390,11391,11393,11396,11398,11401,11403,11405],{"class":314,"line":371},[312,11392,9051],{"class":661},[312,11394,11395],{"class":749}," validation",[312,11397,1097],{"class":652},[312,11399,11400],{"class":745}," validateCart",[312,11402,750],{"class":757},[312,11404,11379],{"class":749},[312,11406,828],{"class":757},[312,11408,11409,11411,11413,11416,11419,11421,11424,11426,11429,11431,11434,11436,11438,11440,11442],{"class":314,"line":382},[312,11410,9924],{"class":738},[312,11412,1830],{"class":757},[312,11414,11415],{"class":652},"!",[312,11417,11418],{"class":749},"validation",[312,11420,1451],{"class":652},[312,11422,11423],{"class":749},"valid",[312,11425,9932],{"class":757},[312,11427,11428],{"class":738},"throw",[312,11430,11185],{"class":652},[312,11432,11433],{"class":745}," Error",[312,11435,750],{"class":757},[312,11437,11418],{"class":749},[312,11439,1451],{"class":652},[312,11441,9929],{"class":749},[312,11443,828],{"class":757},[312,11445,11446],{"class":314,"line":392},[312,11447,339],{"emptyLinePlaceholder":338},[312,11449,11450,11452,11455,11457,11459,11462,11464,11466],{"class":314,"line":937},[312,11451,9051],{"class":661},[312,11453,11454],{"class":749}," order",[312,11456,1097],{"class":652},[312,11458,1100],{"class":738},[312,11460,11461],{"class":745}," createOrder",[312,11463,750],{"class":757},[312,11465,11379],{"class":749},[312,11467,828],{"class":757},[312,11469,11470,11472,11475,11477,11479,11482,11484,11487],{"class":314,"line":949},[312,11471,9051],{"class":661},[312,11473,11474],{"class":749}," payment",[312,11476,1097],{"class":652},[312,11478,1100],{"class":738},[312,11480,11481],{"class":745}," processPayment",[312,11483,750],{"class":757},[312,11485,11486],{"class":749},"order",[312,11488,828],{"class":757},[312,11490,11491,11493,11495,11497,11500,11502,11505,11507],{"class":314,"line":29},[312,11492,9924],{"class":738},[312,11494,1830],{"class":757},[312,11496,11415],{"class":652},[312,11498,11499],{"class":749},"payment",[312,11501,1451],{"class":652},[312,11503,11504],{"class":749},"success",[312,11506,9932],{"class":757},[312,11508,653],{"class":652},[312,11510,11511,11514,11517,11519,11521,11523,11526],{"class":314,"line":5837},[312,11512,11513],{"class":738}," await",[312,11515,11516],{"class":745}," cancelOrder",[312,11518,750],{"class":757},[312,11520,11486],{"class":749},[312,11522,1451],{"class":652},[312,11524,11525],{"class":749},"id",[312,11527,828],{"class":757},[312,11529,11530,11533,11535,11537,11539,11541,11543,11545],{"class":314,"line":5843},[312,11531,11532],{"class":738}," throw",[312,11534,11185],{"class":652},[312,11536,11433],{"class":745},[312,11538,750],{"class":757},[312,11540,11499],{"class":749},[312,11542,1451],{"class":652},[312,11544,9929],{"class":749},[312,11546,828],{"class":757},[312,11548,11549],{"class":314,"line":5848},[312,11550,6823],{"class":652},[312,11552,11553],{"class":314,"line":5853},[312,11554,339],{"emptyLinePlaceholder":338},[312,11556,11557,11560,11563,11565,11567,11569,11571],{"class":314,"line":5859},[312,11558,11559],{"class":738}," await",[312,11561,11562],{"class":745}," sendConfirmation",[312,11564,750],{"class":757},[312,11566,11486],{"class":749},[312,11568,1115],{"class":652},[312,11570,11474],{"class":749},[312,11572,828],{"class":757},[312,11574,11575,11577],{"class":314,"line":7077},[312,11576,9077],{"class":738},[312,11578,11579],{"class":749}," order\n",[312,11581,11582],{"class":314,"line":7093},[312,11583,697],{"class":652},[312,11585,11586],{"class":314,"line":7113},[312,11587,339],{"emptyLinePlaceholder":338},[312,11589,11590,11592,11594,11596,11598,11600,11602,11604],{"class":314,"line":7131},[312,11591,1666],{"class":738},[312,11593,1089],{"class":652},[312,11595,1301],{"class":749},[312,11597,1115],{"class":652},[312,11599,9910],{"class":749},[312,11601,1115],{"class":652},[312,11603,530],{"class":749},[312,11605,1689],{"class":652},[312,11607,11608],{"class":314,"line":7136},[312,11609,702],{"class":652},[303,11611,11613],{"className":729,"code":11612,"language":731,"meta":308,"style":308},"// System-first: decomposed into failure-independent tasks\nexport function useCheckoutSystem() {\n const step = ref(\"idle\")\n const executionId = ref(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 {\n executionId.value = generateId()\n step.value = \"validating\"\n\n // 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 // 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",[221,11614,11615,11620,11633,11663,11694,11698,11709,11736,11762,11788,11814,11818,11822,11853,11870,11888,11892,11897,11925,11957,11961,11978,12009,12039,12043,12060,12091,12109,12114,12153,12170,12174,12178,12195,12220,12224,12241,12266,12270,12274,12296],{"__ignoreMap":308},[312,11616,11617],{"class":314,"line":315},[312,11618,11619],{"class":318},"// System-first: decomposed into failure-independent tasks\n",[312,11621,11622,11624,11626,11629,11631],{"class":314,"line":322},[312,11623,739],{"class":738},[312,11625,9209],{"class":661},[312,11627,11628],{"class":745}," useCheckoutSystem",[312,11630,1871],{"class":652},[312,11632,671],{"class":652},[312,11634,11635,11637,11640,11642,11645,11647,11650,11652,11654,11656,11659,11661],{"class":314,"line":16},[312,11636,9221],{"class":661},[312,11638,11639],{"class":749}," step",[312,11641,1097],{"class":652},[312,11643,11644],{"class":745}," ref",[312,11646,7172],{"class":652},[312,11648,11649],{"class":325},"CheckoutStep",[312,11651,9272],{"class":652},[312,11653,750],{"class":757},[312,11655,665],{"class":652},[312,11657,11658],{"class":329},"idle",[312,11660,665],{"class":652},[312,11662,828],{"class":757},[312,11664,11665,11667,11670,11672,11674,11676,11679,11682,11685,11687,11689,11692],{"class":314,"line":342},[312,11666,9221],{"class":661},[312,11668,11669],{"class":749}," executionId",[312,11671,1097],{"class":652},[312,11673,11644],{"class":745},[312,11675,7172],{"class":652},[312,11677,11678],{"class":325},"string",[312,11680,11681],{"class":652}," |",[312,11683,11684],{"class":325}," null",[312,11686,9272],{"class":652},[312,11688,750],{"class":757},[312,11690,11691],{"class":652},"null",[312,11693,828],{"class":757},[312,11695,11696],{"class":314,"line":348},[312,11697,339],{"emptyLinePlaceholder":338},[312,11699,11700,11702,11705,11707],{"class":314,"line":360},[312,11701,9221],{"class":661},[312,11703,11704],{"class":749}," tasks",[312,11706,1097],{"class":652},[312,11708,671],{"class":652},[312,11710,11711,11714,11716,11719,11721,11723,11726,11728,11730,11732,11734],{"class":314,"line":365},[312,11712,11713],{"class":757}," validate",[312,11715,668],{"class":652},[312,11717,11718],{"class":745}," useTask",[312,11720,750],{"class":757},[312,11722,665],{"class":652},[312,11724,11725],{"class":329},"checkout.validate",[312,11727,665],{"class":652},[312,11729,1115],{"class":652},[312,11731,11400],{"class":749},[312,11733,1438],{"class":757},[312,11735,776],{"class":652},[312,11737,11738,11741,11743,11745,11747,11749,11752,11754,11756,11758,11760],{"class":314,"line":371},[312,11739,11740],{"class":757}," createOrder",[312,11742,668],{"class":652},[312,11744,11718],{"class":745},[312,11746,750],{"class":757},[312,11748,665],{"class":652},[312,11750,11751],{"class":329},"checkout.createOrder",[312,11753,665],{"class":652},[312,11755,1115],{"class":652},[312,11757,11461],{"class":749},[312,11759,1438],{"class":757},[312,11761,776],{"class":652},[312,11763,11764,11767,11769,11771,11773,11775,11778,11780,11782,11784,11786],{"class":314,"line":382},[312,11765,11766],{"class":757}," processPayment",[312,11768,668],{"class":652},[312,11770,11718],{"class":745},[312,11772,750],{"class":757},[312,11774,665],{"class":652},[312,11776,11777],{"class":329},"checkout.processPayment",[312,11779,665],{"class":652},[312,11781,1115],{"class":652},[312,11783,11481],{"class":749},[312,11785,1438],{"class":757},[312,11787,776],{"class":652},[312,11789,11790,11793,11795,11797,11799,11801,11804,11806,11808,11810,11812],{"class":314,"line":392},[312,11791,11792],{"class":757}," confirm",[312,11794,668],{"class":652},[312,11796,11718],{"class":745},[312,11798,750],{"class":757},[312,11800,665],{"class":652},[312,11802,11803],{"class":329},"checkout.confirm",[312,11805,665],{"class":652},[312,11807,1115],{"class":652},[312,11809,11562],{"class":749},[312,11811,1438],{"class":757},[312,11813,776],{"class":652},[312,11815,11816],{"class":314,"line":937},[312,11817,697],{"class":652},[312,11819,11820],{"class":314,"line":949},[312,11821,339],{"emptyLinePlaceholder":338},[312,11823,11824,11826,11828,11830,11832,11834,11836,11838,11841,11844,11846,11849,11851],{"class":314,"line":29},[312,11825,11370],{"class":661},[312,11827,9209],{"class":661},[312,11829,530],{"class":745},[312,11831,750],{"class":652},[312,11833,11379],{"class":1434},[312,11835,668],{"class":652},[312,11837,11384],{"class":325},[312,11839,11840],{"class":652},"):",[312,11842,11843],{"class":325}," Promise",[312,11845,7172],{"class":652},[312,11847,11848],{"class":325},"ExecutionResult",[312,11850,9272],{"class":652},[312,11852,671],{"class":652},[312,11854,11855,11858,11860,11863,11865,11868],{"class":314,"line":5837},[312,11856,11857],{"class":749}," executionId",[312,11859,1451],{"class":652},[312,11861,11862],{"class":749},"value",[312,11864,1097],{"class":652},[312,11866,11867],{"class":745}," generateId",[312,11869,1566],{"class":757},[312,11871,11872,11875,11877,11879,11881,11883,11886],{"class":314,"line":5843},[312,11873,11874],{"class":749}," step",[312,11876,1451],{"class":652},[312,11878,11862],{"class":749},[312,11880,1097],{"class":652},[312,11882,686],{"class":652},[312,11884,11885],{"class":329},"validating",[312,11887,692],{"class":652},[312,11889,11890],{"class":314,"line":5848},[312,11891,339],{"emptyLinePlaceholder":338},[312,11893,11894],{"class":314,"line":5853},[312,11895,11896],{"class":318}," // Each task runs independently, with its own state and recovery\n",[312,11898,11899,11901,11903,11905,11907,11909,11911,11914,11916,11919,11921,11923],{"class":314,"line":5859},[312,11900,9051],{"class":661},[312,11902,11395],{"class":749},[312,11904,1097],{"class":652},[312,11906,1100],{"class":738},[312,11908,11704],{"class":749},[312,11910,1451],{"class":652},[312,11912,11913],{"class":749},"validate",[312,11915,1451],{"class":652},[312,11917,11918],{"class":745},"run",[312,11920,750],{"class":757},[312,11922,11379],{"class":749},[312,11924,828],{"class":757},[312,11926,11927,11929,11931,11933,11935,11937,11940,11942,11944,11947,11949,11951,11953,11955],{"class":314,"line":7077},[312,11928,9924],{"class":738},[312,11930,1830],{"class":757},[312,11932,11415],{"class":652},[312,11934,11418],{"class":749},[312,11936,1451],{"class":652},[312,11938,11939],{"class":749},"ok",[312,11941,9932],{"class":757},[312,11943,9935],{"class":738},[312,11945,11946],{"class":745}," fail",[312,11948,750],{"class":757},[312,11950,11418],{"class":749},[312,11952,1451],{"class":652},[312,11954,9929],{"class":749},[312,11956,828],{"class":757},[312,11958,11959],{"class":314,"line":7093},[312,11960,339],{"emptyLinePlaceholder":338},[312,11962,11963,11965,11967,11969,11971,11973,11976],{"class":314,"line":7113},[312,11964,11874],{"class":749},[312,11966,1451],{"class":652},[312,11968,11862],{"class":749},[312,11970,1097],{"class":652},[312,11972,686],{"class":652},[312,11974,11975],{"class":329},"creating_order",[312,11977,692],{"class":652},[312,11979,11980,11982,11984,11986,11988,11990,11992,11995,11997,11999,12001,12003,12005,12007],{"class":314,"line":7131},[312,11981,9051],{"class":661},[312,11983,11454],{"class":749},[312,11985,1097],{"class":652},[312,11987,1100],{"class":738},[312,11989,11704],{"class":749},[312,11991,1451],{"class":652},[312,11993,11994],{"class":749},"createOrder",[312,11996,1451],{"class":652},[312,11998,11918],{"class":745},[312,12000,750],{"class":757},[312,12002,11418],{"class":749},[312,12004,1451],{"class":652},[312,12006,9781],{"class":749},[312,12008,828],{"class":757},[312,12010,12011,12013,12015,12017,12019,12021,12023,12025,12027,12029,12031,12033,12035,12037],{"class":314,"line":7136},[312,12012,9924],{"class":738},[312,12014,1830],{"class":757},[312,12016,11415],{"class":652},[312,12018,11486],{"class":749},[312,12020,1451],{"class":652},[312,12022,11939],{"class":749},[312,12024,9932],{"class":757},[312,12026,9935],{"class":738},[312,12028,11946],{"class":745},[312,12030,750],{"class":757},[312,12032,11486],{"class":749},[312,12034,1451],{"class":652},[312,12036,9929],{"class":749},[312,12038,828],{"class":757},[312,12040,12041],{"class":314,"line":7141},[312,12042,339],{"emptyLinePlaceholder":338},[312,12044,12045,12047,12049,12051,12053,12055,12058],{"class":314,"line":7444},[312,12046,11874],{"class":749},[312,12048,1451],{"class":652},[312,12050,11862],{"class":749},[312,12052,1097],{"class":652},[312,12054,686],{"class":652},[312,12056,12057],{"class":329},"processing_payment",[312,12059,692],{"class":652},[312,12061,12062,12064,12066,12068,12070,12072,12074,12077,12079,12081,12083,12085,12087,12089],{"class":314,"line":7451},[312,12063,9051],{"class":661},[312,12065,11474],{"class":749},[312,12067,1097],{"class":652},[312,12069,1100],{"class":738},[312,12071,11704],{"class":749},[312,12073,1451],{"class":652},[312,12075,12076],{"class":749},"processPayment",[312,12078,1451],{"class":652},[312,12080,11918],{"class":745},[312,12082,750],{"class":757},[312,12084,11486],{"class":749},[312,12086,1451],{"class":652},[312,12088,9781],{"class":749},[312,12090,828],{"class":757},[312,12092,12093,12095,12097,12099,12101,12103,12105,12107],{"class":314,"line":7457},[312,12094,9924],{"class":738},[312,12096,1830],{"class":757},[312,12098,11415],{"class":652},[312,12100,11499],{"class":749},[312,12102,1451],{"class":652},[312,12104,11939],{"class":749},[312,12106,9932],{"class":757},[312,12108,653],{"class":652},[312,12110,12111],{"class":314,"line":10852},[312,12112,12113],{"class":318}," // Payment failed but order is already created - handle independently\n",[312,12115,12116,12118,12120,12122,12125,12127,12129,12131,12133,12135,12137,12139,12141,12143,12145,12147,12149,12151],{"class":314,"line":10861},[312,12117,11513],{"class":738},[312,12119,11704],{"class":749},[312,12121,1451],{"class":652},[312,12123,12124],{"class":745},"compensate",[312,12126,750],{"class":757},[312,12128,665],{"class":652},[312,12130,11994],{"class":329},[312,12132,665],{"class":652},[312,12134,1115],{"class":652},[312,12136,11454],{"class":749},[312,12138,1451],{"class":652},[312,12140,9781],{"class":749},[312,12142,1451],{"class":652},[312,12144,11525],{"class":749},[312,12146,1438],{"class":757},[312,12148,1451],{"class":652},[312,12150,11918],{"class":745},[312,12152,1566],{"class":757},[312,12154,12155,12158,12160,12162,12164,12166,12168],{"class":314,"line":10881},[312,12156,12157],{"class":738}," return",[312,12159,11946],{"class":745},[312,12161,750],{"class":757},[312,12163,11499],{"class":749},[312,12165,1451],{"class":652},[312,12167,9929],{"class":749},[312,12169,828],{"class":757},[312,12171,12172],{"class":314,"line":10894},[312,12173,6823],{"class":652},[312,12175,12176],{"class":314,"line":10907},[312,12177,339],{"emptyLinePlaceholder":338},[312,12179,12180,12182,12184,12186,12188,12190,12193],{"class":314,"line":10913},[312,12181,11874],{"class":749},[312,12183,1451],{"class":652},[312,12185,11862],{"class":749},[312,12187,1097],{"class":652},[312,12189,686],{"class":652},[312,12191,12192],{"class":329},"confirming",[312,12194,692],{"class":652},[312,12196,12197,12199,12201,12203,12206,12208,12210,12212,12214,12216,12218],{"class":314,"line":10918},[312,12198,11559],{"class":738},[312,12200,11704],{"class":749},[312,12202,1451],{"class":652},[312,12204,12205],{"class":749},"confirm",[312,12207,1451],{"class":652},[312,12209,11918],{"class":745},[312,12211,750],{"class":757},[312,12213,11486],{"class":749},[312,12215,1451],{"class":652},[312,12217,9781],{"class":749},[312,12219,828],{"class":757},[312,12221,12222],{"class":314,"line":10924},[312,12223,339],{"emptyLinePlaceholder":338},[312,12225,12226,12228,12230,12232,12234,12236,12239],{"class":314,"line":10945},[312,12227,11874],{"class":749},[312,12229,1451],{"class":652},[312,12231,11862],{"class":749},[312,12233,1097],{"class":652},[312,12235,686],{"class":652},[312,12237,12238],{"class":329},"completed",[312,12240,692],{"class":652},[312,12242,12243,12245,12248,12250,12252,12254,12256,12258,12260,12262,12264],{"class":314,"line":10954},[312,12244,9077],{"class":738},[312,12246,12247],{"class":745}," success",[312,12249,750],{"class":757},[312,12251,11486],{"class":749},[312,12253,1451],{"class":652},[312,12255,9781],{"class":749},[312,12257,1115],{"class":652},[312,12259,11474],{"class":749},[312,12261,1451],{"class":652},[312,12263,9781],{"class":749},[312,12265,828],{"class":757},[312,12267,12268],{"class":314,"line":10963},[312,12269,697],{"class":652},[312,12271,12272],{"class":314,"line":10970},[312,12273,339],{"emptyLinePlaceholder":338},[312,12275,12276,12278,12280,12282,12284,12286,12288,12290,12292,12294],{"class":314,"line":10975},[312,12277,1666],{"class":738},[312,12279,1089],{"class":652},[312,12281,530],{"class":749},[312,12283,1115],{"class":652},[312,12285,11639],{"class":749},[312,12287,1115],{"class":652},[312,12289,11669],{"class":749},[312,12291,1115],{"class":652},[312,12293,11704],{"class":749},[312,12295,1689],{"class":652},[312,12297,12298],{"class":314,"line":10980},[312,12299,702],{"class":652},[102,12301,12302],{},"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.",[98,12304,12306],{"id":12305},"real-example-laravel-saas-project","Real Example: Laravel SaaS Project",[102,12308,12309],{},"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.",[102,12311,12312],{},"The original architecture was feature-first:",[113,12314,12315,12318,12321,12324],{},[116,12316,12317],{},"Document upload feature with its own controller and validation",[116,12319,12320],{},"Reviewer assignment with its own controller and notification logic",[116,12322,12323],{},"Review cycle tracking scattered across three model observers",[116,12325,12326],{},"Audit trail implemented as an afterthought in a middleware",[102,12328,12329],{},"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.",[102,12331,12332],{},"I rebuilt the system using an execution-first approach:",[152,12334,12335,12341,12347],{},[116,12336,12337,12340],{},[105,12338,12339],{},"Flow diagram first",": Mapped the complete document lifecycle from upload to final approval, including reject loops, deadline escalations, and withdrawal mid-review",[116,12342,12343,12346],{},[105,12344,12345],{},"State machine",": Defined five document states (Draft, In Review, Changes Requested, Approved, Archived) with explicit transition rules",[116,12348,12349,12352],{},[105,12350,12351],{},"Task decomposition",": Each transition became a task with its own compensation logic",[303,12354,12356],{"className":10274,"code":12355,"language":10276,"meta":308,"style":308},"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 // 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",[221,12357,12358,12365,12369,12379,12393,12407,12421,12435,12441,12445,12456,12468,12480,12490,12498,12503,12531,12575,12604,12645,12654,12658],{"__ignoreMap":308},[312,12359,12360,12362],{"class":314,"line":315},[312,12361,10288],{"class":661},[312,12363,12364],{"class":325}," DocumentExecutionService\n",[312,12366,12367],{"class":314,"line":322},[312,12368,653],{"class":652},[312,12370,12371,12373,12375,12377],{"class":314,"line":16},[312,12372,10306],{"class":661},[312,12374,9209],{"class":661},[312,12376,10704],{"class":745},[312,12378,10707],{"class":652},[312,12380,12381,12383,12386,12388,12391],{"class":314,"line":342},[312,12382,10712],{"class":661},[312,12384,12385],{"class":325}," DocumentStateMachine",[312,12387,10318],{"class":652},[312,12389,12390],{"class":749},"states",[312,12392,776],{"class":652},[312,12394,12395,12397,12400,12402,12405],{"class":314,"line":348},[312,12396,10712],{"class":661},[312,12398,12399],{"class":325}," ReviewAssignmentService",[312,12401,10318],{"class":652},[312,12403,12404],{"class":749},"assignments",[312,12406,776],{"class":652},[312,12408,12409,12411,12414,12416,12419],{"class":314,"line":360},[312,12410,10712],{"class":661},[312,12412,12413],{"class":325}," EscalationService",[312,12415,10318],{"class":652},[312,12417,12418],{"class":749},"escalations",[312,12420,776],{"class":652},[312,12422,12423,12425,12428,12430,12433],{"class":314,"line":365},[312,12424,10712],{"class":661},[312,12426,12427],{"class":325}," AuditService",[312,12429,10318],{"class":652},[312,12431,12432],{"class":749},"audit",[312,12434,776],{"class":652},[312,12436,12437,12439],{"class":314,"line":371},[312,12438,10769],{"class":652},[312,12440,10772],{"class":652},[312,12442,12443],{"class":314,"line":382},[312,12444,339],{"emptyLinePlaceholder":338},[312,12446,12447,12449,12451,12454],{"class":314,"line":392},[312,12448,10306],{"class":661},[312,12450,9209],{"class":661},[312,12452,12453],{"class":745}," rejectDocument",[312,12455,10707],{"class":652},[312,12457,12458,12461,12463,12466],{"class":314,"line":937},[312,12459,12460],{"class":325}," Document",[312,12462,10318],{"class":652},[312,12464,12465],{"class":749},"document",[312,12467,776],{"class":652},[312,12469,12470,12473,12475,12478],{"class":314,"line":949},[312,12471,12472],{"class":325}," Review",[312,12474,10318],{"class":652},[312,12476,12477],{"class":749},"review",[312,12479,776],{"class":652},[312,12481,12482,12485,12487],{"class":314,"line":29},[312,12483,12484],{"class":1842}," string",[312,12486,10318],{"class":652},[312,12488,12489],{"class":749},"reason\n",[312,12491,12492,12494,12496],{"class":314,"line":5837},[312,12493,10825],{"class":652},[312,12495,10828],{"class":325},[312,12497,671],{"class":652},[312,12499,12500],{"class":314,"line":5843},[312,12501,12502],{"class":318}," // State transition determines what happens next, not a controller\n",[312,12504,12505,12507,12509,12511,12513,12515,12517,12519,12521,12524,12526,12529],{"class":314,"line":5848},[312,12506,10520],{"class":738},[312,12508,10404],{"class":652},[312,12510,12390],{"class":749},[312,12512,10352],{"class":652},[312,12514,11065],{"class":745},[312,12516,10410],{"class":652},[312,12518,12465],{"class":749},[312,12520,1115],{"class":652},[312,12522,12523],{"class":325}," DocumentState",[312,12525,10875],{"class":652},[312,12527,12528],{"class":749},"ChangesRequested",[312,12530,828],{"class":652},[312,12532,12533,12536,12539,12541,12544,12546,12548,12550,12552,12554,12557,12559,12561,12563,12565,12567,12569,12572],{"class":314,"line":5853},[312,12534,12535],{"class":652}," ->",[312,12537,12538],{"class":745},"then",[312,12540,750],{"class":652},[312,12542,12543],{"class":661},"fn",[312,12545,1871],{"class":652},[312,12547,1441],{"class":652},[312,12549,10404],{"class":652},[312,12551,12404],{"class":749},[312,12553,10352],{"class":652},[312,12555,12556],{"class":745},"reassign",[312,12558,10410],{"class":652},[312,12560,12465],{"class":749},[312,12562,1115],{"class":652},[312,12564,10318],{"class":652},[312,12566,12477],{"class":749},[312,12568,10352],{"class":652},[312,12570,12571],{"class":749},"reviewer",[312,12573,12574],{"class":652},"))\n",[312,12576,12577,12579,12581,12583,12585,12587,12589,12591,12593,12595,12598,12600,12602],{"class":314,"line":5859},[312,12578,12535],{"class":652},[312,12580,12538],{"class":745},[312,12582,750],{"class":652},[312,12584,12543],{"class":661},[312,12586,1871],{"class":652},[312,12588,1441],{"class":652},[312,12590,10404],{"class":652},[312,12592,12418],{"class":749},[312,12594,10352],{"class":652},[312,12596,12597],{"class":745},"resetDeadline",[312,12599,10410],{"class":652},[312,12601,12465],{"class":749},[312,12603,12574],{"class":652},[312,12605,12606,12608,12611,12613,12615,12617,12620,12622,12624,12626,12628,12630,12633,12635,12637,12639,12641,12643],{"class":314,"line":7077},[312,12607,12535],{"class":652},[312,12609,12610],{"class":745},"onFailure",[312,12612,750],{"class":652},[312,12614,12543],{"class":661},[312,12616,10410],{"class":652},[312,12618,12619],{"class":749},"step",[312,12621,1438],{"class":652},[312,12623,1441],{"class":652},[312,12625,10404],{"class":652},[312,12627,12432],{"class":749},[312,12629,10352],{"class":652},[312,12631,12632],{"class":745},"logFailure",[312,12634,10410],{"class":652},[312,12636,12465],{"class":749},[312,12638,1115],{"class":652},[312,12640,10318],{"class":652},[312,12642,12619],{"class":749},[312,12644,12574],{"class":652},[312,12646,12647,12649,12652],{"class":314,"line":7093},[312,12648,12535],{"class":652},[312,12650,12651],{"class":745},"execute",[312,12653,10383],{"class":652},[312,12655,12656],{"class":314,"line":7113},[312,12657,6823],{"class":652},[312,12659,12660],{"class":314,"line":7131},[312,12661,702],{"class":652},[102,12663,12664],{},"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.",[98,12666,12668],{"id":12667},"tradeoff-table-feature-first-vs-system-first","Tradeoff Table: Feature-First vs System-First",[2605,12670,12671,12684],{},[2608,12672,12673],{},[2611,12674,12675,12678,12681],{},[2614,12676,12677],{},"Dimension",[2614,12679,12680],{},"Feature-First",[2614,12682,12683],{},"System-First",[2627,12685,12686,12697,12708,12719,12730,12741,12752,12763],{},[2611,12687,12688,12691,12694],{},[2632,12689,12690],{},"Time to first feature",[2632,12692,12693],{},"Faster (days instead of weeks)",[2632,12695,12696],{},"Slower initial investment",[2611,12698,12699,12702,12705],{},[2632,12700,12701],{},"Time to ten features",[2632,12703,12704],{},"Slowing down as coupling grows",[2632,12706,12707],{},"Accelerating as patterns reuse",[2611,12709,12710,12713,12716],{},[2632,12711,12712],{},"Edge case handling",[2632,12714,12715],{},"Reactive, patch-by-patch",[2632,12717,12718],{},"Proactive, defined in flow design",[2611,12720,12721,12724,12727],{},[2632,12722,12723],{},"Rework cost per change",[2632,12725,12726],{},"High - changes ripple across scattered state",[2632,12728,12729],{},"Low - changes are confined to task boundaries",[2611,12731,12732,12735,12738],{},[2632,12733,12734],{},"Onboarding new developers",[2632,12736,12737],{},"Steep - implicit flows must be traced",[2632,12739,12740],{},"Shallow - flow diagram is the documentation",[2611,12742,12743,12746,12749],{},[2632,12744,12745],{},"Failure recovery",[2632,12747,12748],{},"Manual - operators must reconstruct state",[2632,12750,12751],{},"Automatic or assisted - state machine knows position",[2611,12753,12754,12757,12760],{},[2632,12755,12756],{},"Testing strategy",[2632,12758,12759],{},"End-to-end only, slow and brittle",[2632,12761,12762],{},"Task-level unit tests + system integration tests",[2611,12764,12765,12768,12771],{},[2632,12766,12767],{},"Refactoring confidence",[2632,12769,12770],{},"Low - afraid to touch tangled state",[2632,12772,12773],{},"High - state transitions are contractually defined",[102,12775,12776],{},"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.",[98,12778,12780],{"id":12779},"how-this-applies-to-ai-systems","How This Applies to AI Systems",[102,12782,12783],{},"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.",[102,12785,12786],{},"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:",[113,12788,12789,12794,12799],{},[116,12790,12791,12793],{},[105,12792,10089],{},": The phase pipeline - detect phase, route to specialist, execute wave, synthesize results",[116,12795,12796,12798],{},[105,12797,10095],{},": Persistent execution context that survives individual agent calls",[116,12800,12801,12803],{},[105,12802,12351],{},": Each agent handles one phase, one deliverable, one failure boundary",[102,12805,12806],{},"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.",[102,12808,12809],{},"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.",[98,12811,12813],{"id":12812},"consulting-signal-sell-system-design-not-feature-delivery","Consulting Signal: Sell System Design, Not Feature Delivery",[102,12815,12816],{},"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.",[102,12818,12819],{},"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?",[102,12821,12822],{},"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.",[98,12824,12826],{"id":12825},"closing","Closing",[102,12828,12829],{},"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.",[102,12831,12832],{},"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.",[102,12834,12835],{},"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.",[2892,12837,12838],{},"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":308,"searchDepth":322,"depth":322,"links":12840},[12841,12842,12843,12848,12849,12850,12851,12852],{"id":10066,"depth":322,"text":10059},{"id":10078,"depth":322,"text":10079},{"id":10117,"depth":322,"text":10118,"children":12844},[12845,12846,12847],{"id":10121,"depth":16,"text":10122},{"id":10258,"depth":16,"text":10259},{"id":11274,"depth":16,"text":11275},{"id":12305,"depth":322,"text":12306},{"id":12667,"depth":322,"text":12668},{"id":12779,"depth":322,"text":12780},{"id":12812,"depth":322,"text":12813},{"id":12825,"depth":322,"text":12826},"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":12856},"11 min read","/blog/39-execution-systems-first-not-features",{"title":10059,"description":12854},"AI Systems Engineering","Building production-grade AI systems that scale beyond demos",{"src":12862,"mime":2974,"alt":12863,"width":2976,"height":12864},"/img/blog/39-execution-systems-first-not-features/banner.svg","Execution system architecture showing flow design, state management, and task decomposition layers",680,"blog/39-execution-systems-first-not-features",[12867,12868,12869,12870,2980,12871],"Architecture","Software Design","Execution Systems","Laravel","Development Practices","SXBdbszkV6tqDiQQzhPOkc2FqpppzH9VKOxMoDrItcw",{"id":12874,"title":12875,"abstract":92,"author":93,"authorUrl":92,"body":12876,"date":14566,"dateUpdated":14566,"description":14567,"excerpt":92,"extension":2954,"featured":338,"headline":92,"image":92,"meta":14568,"navigation":338,"ogImage":92,"path":14569,"seo":14570,"series":14571,"seriesDescription":14572,"seriesOrder":315,"socialImage":14573,"stem":14576,"tags":14577,"__hash__":14578},"blog/blog/20-core-web-vitals-2026-optimization.md","Core Web Vitals 2026: Performance Optimization Strategies",{"type":95,"value":12877,"toc":14542},[12878,12881,12884,12887,12891,12894,12898,12901,12906,12917,12922,12952,13084,13088,13091,13096,13110,13114,13140,13237,13241,13244,13249,13263,13267,13293,13435,13439,13443,13446,13617,13621,13624,13650,13839,13843,13846,13961,13963,13967,13970,14157,14161,14164,14407,14411,14414,14418,14432,14436,14468,14472,14489,14493,14496,14528,14530,14533,14536,14539],[98,12879,12875],{"id":12880},"core-web-vitals-2026-performance-optimization-strategies",[102,12882,12883],{},"Web performance has always been critical, but in 2026, it's more important than ever. Google's Core Web Vitals have evolved into comprehensive metrics that directly impact search rankings, user experience, and conversion rates. After optimizing dozens of websites for peak performance, I've developed a systematic approach to achieving perfect Core Web Vitals scores.",[102,12885,12886],{},"In this comprehensive guide, we'll explore the latest Core Web Vitals metrics, understand how they're measured, and implement proven optimization strategies that deliver real-world results. Whether you're building a Nuxt application, a React site, or any modern web application, these techniques will help you deliver lightning-fast experiences that users and search engines love.",[98,12888,12890],{"id":12889},"understanding-core-web-vitals-in-2026","Understanding Core Web Vitals in 2026",[102,12892,12893],{},"Google has refined Core Web Vitals over the years, and 2026 brings updated thresholds and new metrics that better reflect modern web experiences. The three core metrics remain, but with stricter targets:",[191,12895,12897],{"id":12896},"largest-contentful-paint-lcp-20s-target","Largest Contentful Paint (LCP) - 2.0s Target",[102,12899,12900],{},"LCP measures loading performance by tracking when the largest content element becomes visible. The 2026 target is now 2.0 seconds (down from 2.5s), reflecting user expectations for faster loading.",[102,12902,12903],{},[105,12904,12905],{},"What counts as LCP:",[113,12907,12908,12911,12914],{},[116,12909,12910],{},"Images and video thumbnails",[116,12912,12913],{},"Text blocks (headings, paragraphs)",[116,12915,12916],{},"Background images with significant content",[102,12918,12919],{},[105,12920,12921],{},"Optimization strategies:",[152,12923,12924,12930,12940,12946],{},[116,12925,12926,12929],{},[105,12927,12928],{},"Optimize Images",": Use modern formats (AVIF, WebP), implement responsive images, and lazy-load off-screen content",[116,12931,12932,12935,12936,12939],{},[105,12933,12934],{},"Preload Critical Resources",": Use ",[221,12937,12938],{},""," for LCP elements",[116,12941,12942,12945],{},[105,12943,12944],{},"Implement Streaming SSR",": Send HTML in chunks to start rendering sooner",[116,12947,12948,12951],{},[105,12949,12950],{},"Use Edge Caching",": Serve content from edge locations closer to users",[303,12953,12955],{"className":729,"code":12954,"language":731,"meta":308,"style":308},"// Nuxt 4: Preload LCP image\nuseHead({\n link: [\n {\n rel: \"preload\",\n as: \"image\",\n href: \"/img/hero-banner.avif\",\n imagesrcset:\n \"/img/hero-banner-480.avif 480w, /img/hero-banner-768.avif 768w\",\n imagesizes: \"100vw\",\n },\n ],\n})\n",[221,12956,12957,12962,12971,12980,12984,13000,13016,13032,13040,13051,13067,13071,13078],{"__ignoreMap":308},[312,12958,12959],{"class":314,"line":315},[312,12960,12961],{"class":318},"// Nuxt 4: Preload LCP image\n",[312,12963,12964,12967,12969],{"class":314,"line":322},[312,12965,12966],{"class":745},"useHead",[312,12968,750],{"class":749},[312,12970,653],{"class":652},[312,12972,12973,12976,12978],{"class":314,"line":16},[312,12974,12975],{"class":757}," link",[312,12977,668],{"class":652},[312,12979,6599],{"class":749},[312,12981,12982],{"class":314,"line":342},[312,12983,6724],{"class":652},[312,12985,12986,12989,12991,12993,12996,12998],{"class":314,"line":348},[312,12987,12988],{"class":757}," rel",[312,12990,668],{"class":652},[312,12992,686],{"class":652},[312,12994,12995],{"class":329},"preload",[312,12997,665],{"class":652},[312,12999,776],{"class":652},[312,13001,13002,13005,13007,13009,13012,13014],{"class":314,"line":360},[312,13003,13004],{"class":757}," as",[312,13006,668],{"class":652},[312,13008,686],{"class":652},[312,13010,13011],{"class":329},"image",[312,13013,665],{"class":652},[312,13015,776],{"class":652},[312,13017,13018,13021,13023,13025,13028,13030],{"class":314,"line":365},[312,13019,13020],{"class":757}," href",[312,13022,668],{"class":652},[312,13024,686],{"class":652},[312,13026,13027],{"class":329},"/img/hero-banner.avif",[312,13029,665],{"class":652},[312,13031,776],{"class":652},[312,13033,13034,13037],{"class":314,"line":371},[312,13035,13036],{"class":757}," imagesrcset",[312,13038,13039],{"class":652},":\n",[312,13041,13042,13044,13047,13049],{"class":314,"line":382},[312,13043,6781],{"class":652},[312,13045,13046],{"class":329},"/img/hero-banner-480.avif 480w, /img/hero-banner-768.avif 768w",[312,13048,665],{"class":652},[312,13050,776],{"class":652},[312,13052,13053,13056,13058,13060,13063,13065],{"class":314,"line":392},[312,13054,13055],{"class":757}," imagesizes",[312,13057,668],{"class":652},[312,13059,686],{"class":652},[312,13061,13062],{"class":329},"100vw",[312,13064,665],{"class":652},[312,13066,776],{"class":652},[312,13068,13069],{"class":314,"line":937},[312,13070,815],{"class":652},[312,13072,13073,13076],{"class":314,"line":949},[312,13074,13075],{"class":749}," ]",[312,13077,776],{"class":652},[312,13079,13080,13082],{"class":314,"line":29},[312,13081,825],{"class":652},[312,13083,828],{"class":749},[191,13085,13087],{"id":13086},"interaction-to-next-paint-inp-150ms-target","Interaction to Next Paint (INP) - 150ms Target",[102,13089,13090],{},"INP replaced First Input Delay (FID) in 2024 and has become the primary responsiveness metric. It measures the latency of all user interactions during a page visit, not just the first one. The 2026 target is 150ms.",[102,13092,13093],{},[105,13094,13095],{},"What INP measures:",[113,13097,13098,13101,13104,13107],{},[116,13099,13100],{},"Click events on buttons and links",[116,13102,13103],{},"Keyboard input in form fields",[116,13105,13106],{},"Touch interactions on mobile devices",[116,13108,13109],{},"Scroll interactions",[102,13111,13112],{},[105,13113,12921],{},[152,13115,13116,13122,13128,13134],{},[116,13117,13118,13121],{},[105,13119,13120],{},"Minimize JavaScript Execution",": Break up long tasks, use web workers for heavy computation",[116,13123,13124,13127],{},[105,13125,13126],{},"Optimize Event Handlers",": Debounce scroll events, use passive event listeners",[116,13129,13130,13133],{},[105,13131,13132],{},"Reduce Third-Party Impact",": Load analytics and ads asynchronously",[116,13135,13136,13139],{},[105,13137,13138],{},"Use View Transitions API",": Smooth page transitions without blocking interactions",[303,13141,13143],{"className":729,"code":13142,"language":731,"meta":308,"style":308},"// Optimize event handlers with passive listeners\nonMounted(() => {\n const element = document.querySelector(\".scroll-container\")\n element?.addEventListener(\"scroll\", handleScroll, { passive: true })\n})\n",[221,13144,13145,13150,13163,13191,13231],{"__ignoreMap":308},[312,13146,13147],{"class":314,"line":315},[312,13148,13149],{"class":318},"// Optimize event handlers with passive listeners\n",[312,13151,13152,13155,13157,13159,13161],{"class":314,"line":322},[312,13153,13154],{"class":745},"onMounted",[312,13156,750],{"class":749},[312,13158,1871],{"class":652},[312,13160,1441],{"class":661},[312,13162,671],{"class":652},[312,13164,13165,13167,13170,13172,13175,13177,13180,13182,13184,13187,13189],{"class":314,"line":16},[312,13166,9221],{"class":661},[312,13168,13169],{"class":749}," element",[312,13171,1097],{"class":652},[312,13173,13174],{"class":749}," document",[312,13176,1451],{"class":652},[312,13178,13179],{"class":745},"querySelector",[312,13181,750],{"class":757},[312,13183,665],{"class":652},[312,13185,13186],{"class":329},".scroll-container",[312,13188,665],{"class":652},[312,13190,828],{"class":757},[312,13192,13193,13196,13199,13202,13204,13206,13209,13211,13213,13216,13218,13220,13223,13225,13227,13229],{"class":314,"line":342},[312,13194,13195],{"class":749}," element",[312,13197,13198],{"class":652},"?.",[312,13200,13201],{"class":745},"addEventListener",[312,13203,750],{"class":757},[312,13205,665],{"class":652},[312,13207,13208],{"class":329},"scroll",[312,13210,665],{"class":652},[312,13212,1115],{"class":652},[312,13214,13215],{"class":749}," handleScroll",[312,13217,1115],{"class":652},[312,13219,1089],{"class":652},[312,13221,13222],{"class":757}," passive",[312,13224,668],{"class":652},[312,13226,932],{"class":931},[312,13228,1340],{"class":652},[312,13230,828],{"class":757},[312,13232,13233,13235],{"class":314,"line":348},[312,13234,825],{"class":652},[312,13236,828],{"class":749},[191,13238,13240],{"id":13239},"cumulative-layout-shift-cls-005-target","Cumulative Layout Shift (CLS) - 0.05 Target",[102,13242,13243],{},"CLS measures visual stability by tracking unexpected layout shifts. The target remains 0.05, but measurement has become more sophisticated, better accounting for user-initiated changes.",[102,13245,13246],{},[105,13247,13248],{},"Common causes of layout shift:",[113,13250,13251,13254,13257,13260],{},[116,13252,13253],{},"Images without dimensions",[116,13255,13256],{},"Web fonts causing FOIT/FOUT",[116,13258,13259],{},"Dynamically injected content",[116,13261,13262],{},"Late-loading ads and embeds",[102,13264,13265],{},[105,13266,12921],{},[152,13268,13269,13275,13281,13287],{},[116,13270,13271,13274],{},[105,13272,13273],{},"Set Explicit Dimensions",": Always specify width and height for images and videos",[116,13276,13277,13280],{},[105,13278,13279],{},"Reserve Space for Dynamic Content",": Use CSS aspect-ratio and min-height",[116,13282,13283,13286],{},[105,13284,13285],{},"Optimize Font Loading",": Use font-display: optional or swap with size-adjust",[116,13288,13289,13292],{},[105,13290,13291],{},"Avoid Inserting Content Above Existing Content",": Load ads and embeds in reserved spaces",[303,13294,13298],{"className":13295,"code":13296,"language":13297,"meta":308,"style":308},"language-css shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","/* Reserve space for images */\n.img-container {\n aspect-ratio: 16 / 9;\n background: #f0f0f0;\n}\n\n/* Optimize font loading */\n@font-face {\n font-family: \"Inter\";\n src: url(\"/fonts/inter.woff2\") format(\"woff2\");\n font-display: swap;\n}\n","css",[221,13299,13300,13305,13314,13333,13348,13352,13356,13361,13368,13384,13419,13431],{"__ignoreMap":308},[312,13301,13302],{"class":314,"line":315},[312,13303,13304],{"class":318},"/* Reserve space for images */\n",[312,13306,13307,13309,13312],{"class":314,"line":322},[312,13308,1451],{"class":652},[312,13310,13311],{"class":325},"img-container",[312,13313,671],{"class":652},[312,13315,13316,13320,13322,13325,13328,13331],{"class":314,"line":16},[312,13317,13319],{"class":13318},"sqsOY"," aspect-ratio",[312,13321,668],{"class":652},[312,13323,13324],{"class":1842}," 16",[312,13326,13327],{"class":749}," / ",[312,13329,13330],{"class":1842},"9",[312,13332,10369],{"class":652},[312,13334,13335,13338,13340,13343,13346],{"class":314,"line":342},[312,13336,13337],{"class":13318}," background",[312,13339,668],{"class":652},[312,13341,13342],{"class":652}," #",[312,13344,13345],{"class":749},"f0f0f0",[312,13347,10369],{"class":652},[312,13349,13350],{"class":314,"line":348},[312,13351,702],{"class":652},[312,13353,13354],{"class":314,"line":360},[312,13355,339],{"emptyLinePlaceholder":338},[312,13357,13358],{"class":314,"line":365},[312,13359,13360],{"class":318},"/* Optimize font loading */\n",[312,13362,13363,13366],{"class":314,"line":371},[312,13364,13365],{"class":738},"@font-face",[312,13367,671],{"class":652},[312,13369,13370,13373,13375,13377,13380,13382],{"class":314,"line":382},[312,13371,13372],{"class":13318}," font-family",[312,13374,668],{"class":652},[312,13376,686],{"class":652},[312,13378,13379],{"class":329},"Inter",[312,13381,665],{"class":652},[312,13383,10369],{"class":652},[312,13385,13386,13389,13391,13394,13396,13398,13401,13403,13405,13408,13410,13412,13415,13417],{"class":314,"line":392},[312,13387,13388],{"class":13318}," src",[312,13390,668],{"class":652},[312,13392,13393],{"class":745}," url",[312,13395,750],{"class":652},[312,13397,665],{"class":652},[312,13399,13400],{"class":329},"/fonts/inter.woff2",[312,13402,665],{"class":652},[312,13404,1438],{"class":652},[312,13406,13407],{"class":745}," format",[312,13409,750],{"class":652},[312,13411,665],{"class":652},[312,13413,13414],{"class":329},"woff2",[312,13416,665],{"class":652},[312,13418,10415],{"class":652},[312,13420,13421,13424,13426,13429],{"class":314,"line":937},[312,13422,13423],{"class":13318}," font-display",[312,13425,668],{"class":652},[312,13427,13428],{"class":749}," swap",[312,13430,10369],{"class":652},[312,13432,13433],{"class":314,"line":949},[312,13434,702],{"class":652},[98,13436,13438],{"id":13437},"advanced-optimization-techniques","Advanced Optimization Techniques",[191,13440,13442],{"id":13441},"implementing-speculation-rules","Implementing Speculation Rules",[102,13444,13445],{},"Chrome's Speculation Rules API allows you to prefetch or prerender pages based on user behavior predictions. This can dramatically improve perceived performance for navigation.",[303,13447,13449],{"className":729,"code":13448,"language":731,"meta":308,"style":308},"// Nuxt 4: Enable speculation rules\nuseHead({\n script: [\n {\n type: \"speculationrules\",\n textContent: JSON.stringify({\n prefetch: [\n {\n source: \"document\",\n where: { href_matches: \"/blog/*\" },\n eagerness: \"moderate\",\n },\n ],\n }),\n },\n ],\n})\n",[221,13450,13451,13456,13464,13473,13477,13493,13512,13521,13526,13541,13564,13580,13585,13592,13601,13605,13611],{"__ignoreMap":308},[312,13452,13453],{"class":314,"line":315},[312,13454,13455],{"class":318},"// Nuxt 4: Enable speculation rules\n",[312,13457,13458,13460,13462],{"class":314,"line":322},[312,13459,12966],{"class":745},[312,13461,750],{"class":749},[312,13463,653],{"class":652},[312,13465,13466,13469,13471],{"class":314,"line":16},[312,13467,13468],{"class":757}," script",[312,13470,668],{"class":652},[312,13472,6599],{"class":749},[312,13474,13475],{"class":314,"line":342},[312,13476,6724],{"class":652},[312,13478,13479,13482,13484,13486,13489,13491],{"class":314,"line":348},[312,13480,13481],{"class":757}," type",[312,13483,668],{"class":652},[312,13485,686],{"class":652},[312,13487,13488],{"class":329},"speculationrules",[312,13490,665],{"class":652},[312,13492,776],{"class":652},[312,13494,13495,13498,13500,13503,13505,13508,13510],{"class":314,"line":360},[312,13496,13497],{"class":757}," textContent",[312,13499,668],{"class":652},[312,13501,13502],{"class":749}," JSON",[312,13504,1451],{"class":652},[312,13506,13507],{"class":745},"stringify",[312,13509,750],{"class":749},[312,13511,653],{"class":652},[312,13513,13514,13517,13519],{"class":314,"line":365},[312,13515,13516],{"class":757}," prefetch",[312,13518,668],{"class":652},[312,13520,6599],{"class":749},[312,13522,13523],{"class":314,"line":371},[312,13524,13525],{"class":652}," {\n",[312,13527,13528,13531,13533,13535,13537,13539],{"class":314,"line":382},[312,13529,13530],{"class":757}," source",[312,13532,668],{"class":652},[312,13534,686],{"class":652},[312,13536,12465],{"class":329},[312,13538,665],{"class":652},[312,13540,776],{"class":652},[312,13542,13543,13546,13548,13550,13553,13555,13557,13560,13562],{"class":314,"line":392},[312,13544,13545],{"class":757}," where",[312,13547,668],{"class":652},[312,13549,1089],{"class":652},[312,13551,13552],{"class":757}," href_matches",[312,13554,668],{"class":652},[312,13556,686],{"class":652},[312,13558,13559],{"class":329},"/blog/*",[312,13561,665],{"class":652},[312,13563,8642],{"class":652},[312,13565,13566,13569,13571,13573,13576,13578],{"class":314,"line":937},[312,13567,13568],{"class":757}," eagerness",[312,13570,668],{"class":652},[312,13572,686],{"class":652},[312,13574,13575],{"class":329},"moderate",[312,13577,665],{"class":652},[312,13579,776],{"class":652},[312,13581,13582],{"class":314,"line":949},[312,13583,13584],{"class":652}," },\n",[312,13586,13587,13590],{"class":314,"line":29},[312,13588,13589],{"class":749}," ]",[312,13591,776],{"class":652},[312,13593,13594,13597,13599],{"class":314,"line":5837},[312,13595,13596],{"class":652}," }",[312,13598,1438],{"class":749},[312,13600,776],{"class":652},[312,13602,13603],{"class":314,"line":5843},[312,13604,815],{"class":652},[312,13606,13607,13609],{"class":314,"line":5848},[312,13608,13075],{"class":749},[312,13610,776],{"class":652},[312,13612,13613,13615],{"class":314,"line":5853},[312,13614,825],{"class":652},[312,13616,828],{"class":749},[191,13618,13620],{"id":13619},"optimizing-third-party-scripts","Optimizing Third-Party Scripts",[102,13622,13623],{},"Third-party scripts are often the biggest performance bottleneck. Implement these strategies:",[152,13625,13626,13632,13638,13644],{},[116,13627,13628,13631],{},[105,13629,13630],{},"Load Non-Critical Scripts After Interaction",": Delay analytics until user engages",[116,13633,13634,13637],{},[105,13635,13636],{},"Use Partytown",": Run third-party scripts in a web worker",[116,13639,13640,13643],{},[105,13641,13642],{},"Implement Resource Hints",": Preconnect to third-party domains",[116,13645,13646,13649],{},[105,13647,13648],{},"Monitor Third-Party Impact",": Track performance impact of each script",[303,13651,13653],{"className":729,"code":13652,"language":731,"meta":308,"style":308},"// Load analytics after user interaction\nlet analyticsLoaded = false\n\nfunction loadAnalytics() {\n if (analyticsLoaded) return\n analyticsLoaded = true\n\n // Dynamically import analytics\n import(\"./analytics\").then(({ init }) => init())\n}\n\n// Load on first user interaction\ndocument.addEventListener(\"click\", loadAnalytics, { once: true })\ndocument.addEventListener(\"scroll\", loadAnalytics, { once: true })\n",[221,13654,13655,13660,13673,13677,13688,13703,13712,13716,13721,13756,13760,13764,13769,13805],{"__ignoreMap":308},[312,13656,13657],{"class":314,"line":315},[312,13658,13659],{"class":318},"// Load analytics after user interaction\n",[312,13661,13662,13665,13668,13670],{"class":314,"line":322},[312,13663,13664],{"class":661},"let",[312,13666,13667],{"class":749}," analyticsLoaded ",[312,13669,1799],{"class":652},[312,13671,13672],{"class":931}," false\n",[312,13674,13675],{"class":314,"line":16},[312,13676,339],{"emptyLinePlaceholder":338},[312,13678,13679,13681,13684,13686],{"class":314,"line":342},[312,13680,11006],{"class":661},[312,13682,13683],{"class":745}," loadAnalytics",[312,13685,1871],{"class":652},[312,13687,671],{"class":652},[312,13689,13690,13693,13695,13698,13700],{"class":314,"line":348},[312,13691,13692],{"class":738}," if",[312,13694,1830],{"class":757},[312,13696,13697],{"class":749},"analyticsLoaded",[312,13699,9932],{"class":757},[312,13701,13702],{"class":738},"return\n",[312,13704,13705,13708,13710],{"class":314,"line":360},[312,13706,13707],{"class":749}," analyticsLoaded",[312,13709,1097],{"class":652},[312,13711,1983],{"class":931},[312,13713,13714],{"class":314,"line":365},[312,13715,339],{"emptyLinePlaceholder":338},[312,13717,13718],{"class":314,"line":371},[312,13719,13720],{"class":318}," // Dynamically import analytics\n",[312,13722,13723,13726,13728,13730,13733,13735,13737,13739,13741,13743,13745,13747,13749,13751,13753],{"class":314,"line":382},[312,13724,13725],{"class":652}," import",[312,13727,750],{"class":757},[312,13729,665],{"class":652},[312,13731,13732],{"class":329},"./analytics",[312,13734,665],{"class":652},[312,13736,1438],{"class":757},[312,13738,1451],{"class":652},[312,13740,12538],{"class":745},[312,13742,750],{"class":757},[312,13744,9480],{"class":652},[312,13746,9693],{"class":1434},[312,13748,9486],{"class":652},[312,13750,1441],{"class":661},[312,13752,9693],{"class":745},[312,13754,13755],{"class":757},"())\n",[312,13757,13758],{"class":314,"line":392},[312,13759,702],{"class":652},[312,13761,13762],{"class":314,"line":937},[312,13763,339],{"emptyLinePlaceholder":338},[312,13765,13766],{"class":314,"line":949},[312,13767,13768],{"class":318},"// Load on first user interaction\n",[312,13770,13771,13773,13775,13777,13779,13781,13784,13786,13788,13790,13792,13794,13797,13799,13801,13803],{"class":314,"line":29},[312,13772,12465],{"class":749},[312,13774,1451],{"class":652},[312,13776,13201],{"class":745},[312,13778,750],{"class":749},[312,13780,665],{"class":652},[312,13782,13783],{"class":329},"click",[312,13785,665],{"class":652},[312,13787,1115],{"class":652},[312,13789,13683],{"class":749},[312,13791,1115],{"class":652},[312,13793,1089],{"class":652},[312,13795,13796],{"class":757}," once",[312,13798,668],{"class":652},[312,13800,932],{"class":931},[312,13802,1340],{"class":652},[312,13804,828],{"class":749},[312,13806,13807,13809,13811,13813,13815,13817,13819,13821,13823,13825,13827,13829,13831,13833,13835,13837],{"class":314,"line":5837},[312,13808,12465],{"class":749},[312,13810,1451],{"class":652},[312,13812,13201],{"class":745},[312,13814,750],{"class":749},[312,13816,665],{"class":652},[312,13818,13208],{"class":329},[312,13820,665],{"class":652},[312,13822,1115],{"class":652},[312,13824,13683],{"class":749},[312,13826,1115],{"class":652},[312,13828,1089],{"class":652},[312,13830,13796],{"class":757},[312,13832,668],{"class":652},[312,13834,932],{"class":931},[312,13836,1340],{"class":652},[312,13838,828],{"class":749},[191,13840,13842],{"id":13841},"implementing-progressive-hydration","Implementing Progressive Hydration",[102,13844,13845],{},"Full hydration of complex SPAs can block interactivity. Progressive hydration loads and hydrates components as they become visible or needed.",[303,13847,13849],{"className":729,"code":13848,"language":731,"meta":308,"style":308},"// Nuxt 4: Lazy hydrate components\n\n",[221,13850,13851,13856,13865,13875,13886,13895,13899,13908,13917,13926,13936,13945,13953],{"__ignoreMap":308},[312,13852,13853],{"class":314,"line":315},[312,13854,13855],{"class":318},"// Nuxt 4: Lazy hydrate components\n",[312,13857,13858,13860,13863],{"class":314,"line":322},[312,13859,7172],{"class":749},[312,13861,13862],{"class":325},"template",[312,13864,7187],{"class":749},[312,13866,13867,13870,13873],{"class":314,"line":16},[312,13868,13869],{"class":749}," <",[312,13871,13872],{"class":325},"ClientOnly",[312,13874,7187],{"class":749},[312,13876,13877,13880,13883],{"class":314,"line":342},[312,13878,13879],{"class":652}," <",[312,13881,13882],{"class":749},"LazyHeavyComponent ",[312,13884,13885],{"class":652},"/>\n",[312,13887,13888,13891,13893],{"class":314,"line":348},[312,13889,13890],{"class":652}," {\n // Send to analytics endpoint\n sendToAnalytics(\"LCP\", metric)\n})\n\nonINP((metric) => {\n sendToAnalytics(\"INP\", metric)\n})\n\nonCLS((metric) => {\n sendToAnalytics(\"CLS\", metric)\n})\n",[221,13974,13975,13980,14012,14016,14034,14039,14059,14065,14069,14086,14105,14111,14115,14132,14151],{"__ignoreMap":308},[312,13976,13977],{"class":314,"line":315},[312,13978,13979],{"class":318},"// Track Core Web Vitals with web-vitals library\n",[312,13981,13982,13985,13987,13990,13992,13995,13997,14000,14002,14005,14007,14010],{"class":314,"line":322},[312,13983,13984],{"class":738},"import",[312,13986,1089],{"class":652},[312,13988,13989],{"class":749}," onLCP",[312,13991,1115],{"class":652},[312,13993,13994],{"class":749}," onINP",[312,13996,1115],{"class":652},[312,13998,13999],{"class":749}," onCLS",[312,14001,1340],{"class":652},[312,14003,14004],{"class":738}," from",[312,14006,686],{"class":652},[312,14008,14009],{"class":329},"web-vitals",[312,14011,692],{"class":652},[312,14013,14014],{"class":314,"line":16},[312,14015,339],{"emptyLinePlaceholder":338},[312,14017,14018,14021,14023,14025,14028,14030,14032],{"class":314,"line":342},[312,14019,14020],{"class":745},"onLCP",[312,14022,750],{"class":749},[312,14024,750],{"class":652},[312,14026,14027],{"class":1434},"metric",[312,14029,1438],{"class":652},[312,14031,1441],{"class":661},[312,14033,671],{"class":652},[312,14035,14036],{"class":314,"line":348},[312,14037,14038],{"class":318}," // Send to analytics endpoint\n",[312,14040,14041,14044,14046,14048,14050,14052,14054,14057],{"class":314,"line":360},[312,14042,14043],{"class":745}," sendToAnalytics",[312,14045,750],{"class":757},[312,14047,665],{"class":652},[312,14049,2666],{"class":329},[312,14051,665],{"class":652},[312,14053,1115],{"class":652},[312,14055,14056],{"class":749}," metric",[312,14058,828],{"class":757},[312,14060,14061,14063],{"class":314,"line":365},[312,14062,825],{"class":652},[312,14064,828],{"class":749},[312,14066,14067],{"class":314,"line":371},[312,14068,339],{"emptyLinePlaceholder":338},[312,14070,14071,14074,14076,14078,14080,14082,14084],{"class":314,"line":382},[312,14072,14073],{"class":745},"onINP",[312,14075,750],{"class":749},[312,14077,750],{"class":652},[312,14079,14027],{"class":1434},[312,14081,1438],{"class":652},[312,14083,1441],{"class":661},[312,14085,671],{"class":652},[312,14087,14088,14090,14092,14094,14097,14099,14101,14103],{"class":314,"line":392},[312,14089,14043],{"class":745},[312,14091,750],{"class":757},[312,14093,665],{"class":652},[312,14095,14096],{"class":329},"INP",[312,14098,665],{"class":652},[312,14100,1115],{"class":652},[312,14102,14056],{"class":749},[312,14104,828],{"class":757},[312,14106,14107,14109],{"class":314,"line":937},[312,14108,825],{"class":652},[312,14110,828],{"class":749},[312,14112,14113],{"class":314,"line":949},[312,14114,339],{"emptyLinePlaceholder":338},[312,14116,14117,14120,14122,14124,14126,14128,14130],{"class":314,"line":29},[312,14118,14119],{"class":745},"onCLS",[312,14121,750],{"class":749},[312,14123,750],{"class":652},[312,14125,14027],{"class":1434},[312,14127,1438],{"class":652},[312,14129,1441],{"class":661},[312,14131,671],{"class":652},[312,14133,14134,14136,14138,14140,14143,14145,14147,14149],{"class":314,"line":5837},[312,14135,14043],{"class":745},[312,14137,750],{"class":757},[312,14139,665],{"class":652},[312,14141,14142],{"class":329},"CLS",[312,14144,665],{"class":652},[312,14146,1115],{"class":652},[312,14148,14056],{"class":749},[312,14150,828],{"class":757},[312,14152,14153,14155],{"class":314,"line":5843},[312,14154,825],{"class":652},[312,14156,828],{"class":749},[191,14158,14160],{"id":14159},"performance-budgets","Performance Budgets",[102,14162,14163],{},"Set performance budgets in your CI/CD pipeline to catch regressions before they reach production.",[303,14165,14167],{"className":643,"code":14166,"language":645,"meta":308,"style":308},"{\n \"performance\": {\n \"budgets\": [\n {\n \"path\": \"/*\",\n \"resourceSizes\": [\n { \"resourceType\": \"script\", \"budget\": 150 },\n { \"resourceType\": \"image\", \"budget\": 200 },\n { \"resourceType\": \"total\", \"budget\": 500 }\n ],\n \"resourceCounts\": [{ \"resourceType\": \"third-party\", \"budget\": 5 }]\n }\n ]\n }\n}\n",[221,14168,14169,14173,14186,14199,14204,14224,14237,14273,14306,14340,14345,14390,14394,14399,14403],{"__ignoreMap":308},[312,14170,14171],{"class":314,"line":315},[312,14172,653],{"class":652},[312,14174,14175,14177,14180,14182,14184],{"class":314,"line":322},[312,14176,658],{"class":652},[312,14178,14179],{"class":661},"performance",[312,14181,665],{"class":652},[312,14183,668],{"class":652},[312,14185,671],{"class":652},[312,14187,14188,14190,14193,14195,14197],{"class":314,"line":16},[312,14189,676],{"class":652},[312,14191,14192],{"class":325},"budgets",[312,14194,665],{"class":652},[312,14196,668],{"class":652},[312,14198,6599],{"class":652},[312,14200,14201],{"class":314,"line":342},[312,14202,14203],{"class":652}," {\n",[312,14205,14206,14208,14211,14213,14215,14217,14220,14222],{"class":314,"line":348},[312,14207,6781],{"class":652},[312,14209,14210],{"class":1842},"path",[312,14212,665],{"class":652},[312,14214,668],{"class":652},[312,14216,686],{"class":652},[312,14218,14219],{"class":329},"/*",[312,14221,665],{"class":652},[312,14223,776],{"class":652},[312,14225,14226,14228,14231,14233,14235],{"class":314,"line":360},[312,14227,6781],{"class":652},[312,14229,14230],{"class":1842},"resourceSizes",[312,14232,665],{"class":652},[312,14234,668],{"class":652},[312,14236,6599],{"class":652},[312,14238,14239,14242,14244,14247,14249,14251,14253,14255,14257,14259,14261,14264,14266,14268,14271],{"class":314,"line":365},[312,14240,14241],{"class":652}," {",[312,14243,686],{"class":652},[312,14245,14246],{"class":757},"resourceType",[312,14248,665],{"class":652},[312,14250,668],{"class":652},[312,14252,686],{"class":652},[312,14254,7463],{"class":329},[312,14256,665],{"class":652},[312,14258,1115],{"class":652},[312,14260,686],{"class":652},[312,14262,14263],{"class":757},"budget",[312,14265,665],{"class":652},[312,14267,668],{"class":652},[312,14269,14270],{"class":1842}," 150",[312,14272,8642],{"class":652},[312,14274,14275,14277,14279,14281,14283,14285,14287,14289,14291,14293,14295,14297,14299,14301,14304],{"class":314,"line":371},[312,14276,14241],{"class":652},[312,14278,686],{"class":652},[312,14280,14246],{"class":757},[312,14282,665],{"class":652},[312,14284,668],{"class":652},[312,14286,686],{"class":652},[312,14288,13011],{"class":329},[312,14290,665],{"class":652},[312,14292,1115],{"class":652},[312,14294,686],{"class":652},[312,14296,14263],{"class":757},[312,14298,665],{"class":652},[312,14300,668],{"class":652},[312,14302,14303],{"class":1842}," 200",[312,14305,8642],{"class":652},[312,14307,14308,14310,14312,14314,14316,14318,14320,14323,14325,14327,14329,14331,14333,14335,14338],{"class":314,"line":382},[312,14309,14241],{"class":652},[312,14311,686],{"class":652},[312,14313,14246],{"class":757},[312,14315,665],{"class":652},[312,14317,668],{"class":652},[312,14319,686],{"class":652},[312,14321,14322],{"class":329},"total",[312,14324,665],{"class":652},[312,14326,1115],{"class":652},[312,14328,686],{"class":652},[312,14330,14263],{"class":757},[312,14332,665],{"class":652},[312,14334,668],{"class":652},[312,14336,14337],{"class":1842}," 500",[312,14339,1689],{"class":652},[312,14341,14342],{"class":314,"line":392},[312,14343,14344],{"class":652}," ],\n",[312,14346,14347,14349,14352,14354,14356,14359,14361,14363,14365,14367,14369,14372,14374,14376,14378,14380,14382,14384,14387],{"class":314,"line":937},[312,14348,6781],{"class":652},[312,14350,14351],{"class":1842},"resourceCounts",[312,14353,665],{"class":652},[312,14355,668],{"class":652},[312,14357,14358],{"class":652}," [{",[312,14360,686],{"class":652},[312,14362,14246],{"class":757},[312,14364,665],{"class":652},[312,14366,668],{"class":652},[312,14368,686],{"class":652},[312,14370,14371],{"class":329},"third-party",[312,14373,665],{"class":652},[312,14375,1115],{"class":652},[312,14377,686],{"class":652},[312,14379,14263],{"class":757},[312,14381,665],{"class":652},[312,14383,668],{"class":652},[312,14385,14386],{"class":1842}," 5",[312,14388,14389],{"class":652}," }]\n",[312,14391,14392],{"class":314,"line":949},[312,14393,6818],{"class":652},[312,14395,14396],{"class":314,"line":29},[312,14397,14398],{"class":652}," ]\n",[312,14400,14401],{"class":314,"line":5837},[312,14402,697],{"class":652},[312,14404,14405],{"class":314,"line":5843},[312,14406,702],{"class":652},[98,14408,14410],{"id":14409},"case-study-e-commerce-performance-optimization","Case Study: E-commerce Performance Optimization",[102,14412,14413],{},"Let me share a real-world example of Core Web Vitals optimization for an e-commerce platform.",[191,14415,14417],{"id":14416},"initial-state","Initial State",[113,14419,14420,14423,14426,14429],{},[116,14421,14422],{},"LCP: 4.2s (Poor)",[116,14424,14425],{},"INP: 280ms (Needs Improvement)",[116,14427,14428],{},"CLS: 0.18 (Needs Improvement)",[116,14430,14431],{},"Mobile conversion rate: 1.8%",[191,14433,14435],{"id":14434},"optimization-steps","Optimization Steps",[152,14437,14438,14444,14450,14456,14462],{},[116,14439,14440,14443],{},[105,14441,14442],{},"Image Optimization",": Converted all product images to AVIF, implemented lazy loading",[116,14445,14446,14449],{},[105,14447,14448],{},"Code Splitting",": Split vendor bundles, lazy-loaded non-critical components",[116,14451,14452,14455],{},[105,14453,14454],{},"Edge Caching",": Implemented ISR for product pages, edge caching for static assets",[116,14457,14458,14461],{},[105,14459,14460],{},"Font Optimization",": Switched to system fonts for body text, optimized heading fonts",[116,14463,14464,14467],{},[105,14465,14466],{},"Third-Party Audit",": Removed unused analytics scripts, deferred ad loading",[191,14469,14471],{"id":14470},"results-after-3-months","Results After 3 Months",[113,14473,14474,14477,14480,14483,14486],{},[116,14475,14476],{},"LCP: 1.8s (Good) - 57% improvement",[116,14478,14479],{},"INP: 120ms (Good) - 57% improvement",[116,14481,14482],{},"CLS: 0.03 (Good) - 83% improvement",[116,14484,14485],{},"Mobile conversion rate: 2.6% - 44% increase",[116,14487,14488],{},"Organic traffic: +35%",[98,14490,14492],{"id":14491},"tools-and-resources","Tools and Resources",[102,14494,14495],{},"Essential tools for Core Web Vitals optimization:",[113,14497,14498,14504,14510,14516,14522],{},[116,14499,14500,14503],{},[105,14501,14502],{},"PageSpeed Insights",": Lab and field data for any URL",[116,14505,14506,14509],{},[105,14507,14508],{},"Chrome DevTools",": Performance panel, Lighthouse audits",[116,14511,14512,14515],{},[105,14513,14514],{},"WebPageTest",": Advanced performance testing with custom configurations",[116,14517,14518,14521],{},[105,14519,14520],{},"CrUX Dashboard",": Real user data in Google Data Studio",[116,14523,14524,14527],{},[105,14525,14526],{},"SpeedCurve",": Continuous performance monitoring",[98,14529,3197],{"id":3196},[102,14531,14532],{},"Core Web Vitals are no longer optional—they're essential for search visibility, user experience, and business success. The optimization strategies outlined in this guide have proven effective across dozens of projects, delivering measurable improvements in performance metrics and business outcomes.",[102,14534,14535],{},"Start by measuring your current performance, identify the biggest opportunities, and implement optimizations incrementally. Focus on user-centric metrics rather than chasing perfect scores. Remember, performance optimization is an ongoing process, not a one-time fix.",[102,14537,14538],{},"The web is getting faster, and user expectations continue to rise. By mastering Core Web Vitals optimization, you'll deliver experiences that delight users and drive business results. The time to act is now—your users (and search rankings) will thank you.",[2892,14540,14541],{},"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 .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 .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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sqsOY, html code.shiki .sqsOY{--shiki-light:#8796B0;--shiki-default:#B2CCD6;--shiki-dark:#B2CCD6}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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 .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}",{"title":308,"searchDepth":322,"depth":322,"links":14543},[14544,14545,14550,14555,14559,14564,14565],{"id":12880,"depth":322,"text":12875},{"id":12889,"depth":322,"text":12890,"children":14546},[14547,14548,14549],{"id":12896,"depth":16,"text":12897},{"id":13086,"depth":16,"text":13087},{"id":13239,"depth":16,"text":13240},{"id":13437,"depth":322,"text":13438,"children":14551},[14552,14553,14554],{"id":13441,"depth":16,"text":13442},{"id":13619,"depth":16,"text":13620},{"id":13841,"depth":16,"text":13842},{"id":8687,"depth":322,"text":8688,"children":14556},[14557,14558],{"id":13965,"depth":16,"text":13966},{"id":14159,"depth":16,"text":14160},{"id":14409,"depth":322,"text":14410,"children":14560},[14561,14562,14563],{"id":14416,"depth":16,"text":14417},{"id":14434,"depth":16,"text":14435},{"id":14470,"depth":16,"text":14471},{"id":14491,"depth":322,"text":14492},{"id":3196,"depth":322,"text":3197},"2026-03-10","Master the latest Core Web Vitals metrics and learn proven optimization strategies to deliver lightning-fast web experiences that rank higher and convert better in 2026.",{"readingTime":8418},"/blog/20-core-web-vitals-2026-optimization",{"title":12875,"description":14567},"Web Performance","Comprehensive guide to web performance optimization and monitoring",{"src":14574,"mime":2974,"alt":14575,"width":2976,"height":2977},"/img/blog/20-core-web-vitals-2026-optimization/banner.svg","Core Web Vitals 2026 Optimization - Speed metrics dashboard with green checkmarks and performance graphs on blue-green gradient background","blog/20-core-web-vitals-2026-optimization",[8935,8937,8436,2984,8936],"v-8qijFl74WKoVbUWXVZJt-dTLbphzXlyaiEHjs7wao",["Reactive",14580],{"$scolor-mode":14581,"$snuxt-seo-utils:routeRules":14584,"$stoasts":14585,"$ssite-config":14586},{"preference":14582,"value":14582,"unknown":338,"forced":14583},"system",false,{"head":-1,"seoMeta":-1},[],{"_priority":14587,"defaultLocale":14590,"description":14591,"env":14592,"indexable":338,"name":14593,"url":10061},{"env":14588,"indexable":14589,"url":14589,"name":14589,"description":14589,"defaultLocale":14589},-15,-3,"en","Senior Software Engineer specializing in modern web technologies. Crafting scalable web applications and browser extensions for startups and founders.","production","Muhammad Ubaid Raza - Full Stack Engineer",["Set"],["ShallowReactive",14596],{"blog-post-/blog/22-nuxt-3-to-4-migration-guide-2026":-1,"profile-data":-1,"series-Modern Development":-1,"related-posts-/blog/22-nuxt-3-to-4-migration-guide-2026":-1}]