[{"data":1,"prerenderedAt":1049},["ShallowReactive",2],{"navigation":3,"/blog/mastering-nuxt-3-performance-optimization":22,"/blog/mastering-nuxt-3-performance-optimization-surround":1045},[4],{"title":5,"path":6,"stem":7,"children":8,"page":21},"Blog","/blog","blog",[9,13,17],{"title":10,"path":11,"stem":12},"🔥 Built from Real-World Needs – My Custom UI Package is Here!","/blog/building-scalable-vue-component-libraries","blog/building-scalable-vue-component-libraries",{"title":14,"path":15,"stem":16},"🔥 Cookie Authentication: How It Works & What Are the Risks?","/blog/cookie-authentication-security","blog/cookie-authentication-security",{"title":18,"path":19,"stem":20},"From Nuxt 2 to Vue 3: My Journey of Migration and Growth","/blog/mastering-nuxt-3-performance-optimization","blog/mastering-nuxt-3-performance-optimization",false,{"id":23,"title":18,"author":24,"body":28,"date":1031,"description":1032,"extension":1033,"image":1034,"meta":1035,"minRead":246,"navigation":230,"path":19,"seo":1043,"stem":20,"__hash__":1044},"blog/blog/mastering-nuxt-3-performance-optimization.md",{"name":25,"avatar":26},"Mohamed Eslam",{"src":27,"alt":25},"/profile-img.jpg",{"type":29,"value":30,"toc":996},"minimark",[31,35,40,45,48,52,55,59,62,66,69,73,77,80,84,96,100,107,111,114,118,122,125,129,132,136,139,143,147,150,154,205,209,326,330,477,481,829,833,837,860,864,884,888,908,912,945,949,952,955,959,962,973,977,980,983,986,992],[32,33,34],"p",{},"Recently, I've been working on upgrading a project from Nuxt 2 to Vue 3 only, and replacing Vuex with Pinia. The experience was full of challenges, but I learned so much from it!",[36,37,39],"h2",{"id":38},"why-i-decided-to-upgrade-and-leave-nuxt-behind","Why I Decided to Upgrade and Leave Nuxt Behind",[41,42,44],"h3",{"id":43},"better-performance-and-composition-api-support","✅ Better Performance and Composition API Support",[32,46,47],{},"Vue 3 offers superior performance and much better support for the Composition API, making the development experience significantly smoother.",[41,49,51],{"id":50},"pinia-vs-vuex","✅ Pinia vs Vuex",[32,53,54],{},"Pinia is much simpler than Vuex and doesn't require mutations like Vuex does, making state management much more straightforward and intuitive.",[41,56,58],{"id":57},"nuxt-2-limitations","✅ Nuxt 2 Limitations",[32,60,61],{},"Nuxt 2 relies on Vue 2, and its support is declining. I needed to take a step forward and transition directly to Vue 3 without depending on Nuxt.",[41,63,65],{"id":64},"project-requirements","✅ Project Requirements",[32,67,68],{},"The project requirements specifically needed Vue 3 only to work with Laravel Mix, which was a key factor in my decision.",[36,70,72],{"id":71},"the-biggest-challenges-i-faced","The Biggest Challenges I Faced",[41,74,76],{"id":75},"losing-nuxt-features","🔹 Losing Nuxt Features",[32,78,79],{},"In Nuxt, I had ready-made features like auto-imports, file-based routing, and SSR. With Vue 3, I had to configure everything manually, which was quite a learning curve.",[41,81,83],{"id":82},"vue-router-changes","🔹 Vue Router Changes",[32,85,86,87,91,92,95],{},"Instead of NuxtLink, I now had to use ",[88,89,90],"code",{},"createRouter"," with ",[88,93,94],{},"createWebHistory()",". This was a significant change in how I defined routes and handled navigation.",[41,97,99],{"id":98},"converting-components-from-options-api-to-composition-api","🔹 Converting Components from Options API to Composition API",[32,101,102,103,106],{},"The ",[88,104,105],{},"setup()"," function completely changed my way of thinking about component structure. But honestly, it makes the code cleaner and much easier to read.",[41,108,110],{"id":109},"migrating-from-vuex-to-pinia","🔹 Migrating from Vuex to Pinia",[32,112,113],{},"Vuex relied on mutations and actions, but Pinia makes state management more direct and easier to work with. The transition was smoother than expected.",[36,115,117],{"id":116},"what-i-gained-from-this-experience","What I Gained from This Experience",[41,119,121],{"id":120},"deeper-understanding-of-vue-core-concepts","💡 Deeper Understanding of Vue Core Concepts",[32,123,124],{},"Leaving Nuxt 2 behind helped me understand Vue's core concepts much more deeply. I now have a better grasp of what's happening under the hood.",[41,126,128],{"id":127},"gradual-migration-is-key","💡 Gradual Migration is Key",[32,130,131],{},"There's no need to rush the upgrade process. Try everything step by step to ensure your app works without issues. This approach saved me from many potential problems.",[41,133,135],{"id":134},"documentation-is-your-best-friend","💡 Documentation is Your Best Friend",[32,137,138],{},"Reading the documentation before starting the migration helped me tremendously. It's essential to understand the changes before diving in.",[36,140,142],{"id":141},"the-migration-process","The Migration Process",[41,144,146],{"id":145},"step-1-planning-and-preparation","Step 1: Planning and Preparation",[32,148,149],{},"I started by thoroughly reading the Vue 3 migration guide and understanding the breaking changes. This preparation phase was crucial for a smooth transition.",[41,151,153],{"id":152},"step-2-setting-up-vue-3","Step 2: Setting Up Vue 3",[155,156,161],"pre",{"className":157,"code":158,"language":159,"meta":160,"style":160},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Installing Vue 3 and related packages\nnpm install vue@3 vue-router@4 pinia@2\nnpm install -D @vitejs/plugin-vue\n","bash","",[88,162,163,172,192],{"__ignoreMap":160},[164,165,168],"span",{"class":166,"line":167},"line",1,[164,169,171],{"class":170},"sHwdD","# Installing Vue 3 and related packages\n",[164,173,175,179,183,186,189],{"class":166,"line":174},2,[164,176,178],{"class":177},"sBMFI","npm",[164,180,182],{"class":181},"sfazB"," install",[164,184,185],{"class":181}," vue@3",[164,187,188],{"class":181}," vue-router@4",[164,190,191],{"class":181}," pinia@2\n",[164,193,195,197,199,202],{"class":166,"line":194},3,[164,196,178],{"class":177},[164,198,182],{"class":181},[164,200,201],{"class":181}," -D",[164,203,204],{"class":181}," @vitejs/plugin-vue\n",[41,206,208],{"id":207},"step-3-router-configuration","Step 3: Router Configuration",[155,210,214],{"className":211,"code":212,"language":213,"meta":160,"style":160},"language-javascript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","// Before (Nuxt 2)\n// Nuxt handled routing automatically\n\n// After (Vue 3)\nimport { createRouter, createWebHistory } from 'vue-router'\n\nconst routes = [\n  {\n    path: '/',\n    name: 'Home',\n    component: () => import('@/views/Home.vue')\n  },\n  // ... more routes\n]\n\nconst router = createRouter({\n  history: createWebHistory(),\n  routes\n})\n","javascript",[88,215,216,221,226,232,238,244,249,255,261,267,273,279,285,291,297,302,308,314,320],{"__ignoreMap":160},[164,217,218],{"class":166,"line":167},[164,219,220],{},"// Before (Nuxt 2)\n",[164,222,223],{"class":166,"line":174},[164,224,225],{},"// Nuxt handled routing automatically\n",[164,227,228],{"class":166,"line":194},[164,229,231],{"emptyLinePlaceholder":230},true,"\n",[164,233,235],{"class":166,"line":234},4,[164,236,237],{},"// After (Vue 3)\n",[164,239,241],{"class":166,"line":240},5,[164,242,243],{},"import { createRouter, createWebHistory } from 'vue-router'\n",[164,245,247],{"class":166,"line":246},6,[164,248,231],{"emptyLinePlaceholder":230},[164,250,252],{"class":166,"line":251},7,[164,253,254],{},"const routes = [\n",[164,256,258],{"class":166,"line":257},8,[164,259,260],{},"  {\n",[164,262,264],{"class":166,"line":263},9,[164,265,266],{},"    path: '/',\n",[164,268,270],{"class":166,"line":269},10,[164,271,272],{},"    name: 'Home',\n",[164,274,276],{"class":166,"line":275},11,[164,277,278],{},"    component: () => import('@/views/Home.vue')\n",[164,280,282],{"class":166,"line":281},12,[164,283,284],{},"  },\n",[164,286,288],{"class":166,"line":287},13,[164,289,290],{},"  // ... more routes\n",[164,292,294],{"class":166,"line":293},14,[164,295,296],{},"]\n",[164,298,300],{"class":166,"line":299},15,[164,301,231],{"emptyLinePlaceholder":230},[164,303,305],{"class":166,"line":304},16,[164,306,307],{},"const router = createRouter({\n",[164,309,311],{"class":166,"line":310},17,[164,312,313],{},"  history: createWebHistory(),\n",[164,315,317],{"class":166,"line":316},18,[164,318,319],{},"  routes\n",[164,321,323],{"class":166,"line":322},19,[164,324,325],{},"})\n",[41,327,329],{"id":328},"step-4-state-management-with-pinia","Step 4: State Management with Pinia",[155,331,333],{"className":211,"code":332,"language":213,"meta":160,"style":160},"// Before (Vuex)\nexport default {\n  state: {\n    user: null\n  },\n  mutations: {\n    SET_USER(state, user) {\n      state.user = user\n    }\n  },\n  actions: {\n    async fetchUser({ commit }) {\n      const user = await api.getUser()\n      commit('SET_USER', user)\n    }\n  }\n}\n\n// After (Pinia)\nexport const useUserStore = defineStore('user', () => {\n  const user = ref(null)\n  \n  const fetchUser = async () => {\n    user.value = await api.getUser()\n  }\n  \n  return { user, fetchUser }\n})\n",[88,334,335,340,345,350,355,359,364,369,374,379,383,388,393,398,403,407,412,417,421,426,432,438,444,450,456,461,466,472],{"__ignoreMap":160},[164,336,337],{"class":166,"line":167},[164,338,339],{},"// Before (Vuex)\n",[164,341,342],{"class":166,"line":174},[164,343,344],{},"export default {\n",[164,346,347],{"class":166,"line":194},[164,348,349],{},"  state: {\n",[164,351,352],{"class":166,"line":234},[164,353,354],{},"    user: null\n",[164,356,357],{"class":166,"line":240},[164,358,284],{},[164,360,361],{"class":166,"line":246},[164,362,363],{},"  mutations: {\n",[164,365,366],{"class":166,"line":251},[164,367,368],{},"    SET_USER(state, user) {\n",[164,370,371],{"class":166,"line":257},[164,372,373],{},"      state.user = user\n",[164,375,376],{"class":166,"line":263},[164,377,378],{},"    }\n",[164,380,381],{"class":166,"line":269},[164,382,284],{},[164,384,385],{"class":166,"line":275},[164,386,387],{},"  actions: {\n",[164,389,390],{"class":166,"line":281},[164,391,392],{},"    async fetchUser({ commit }) {\n",[164,394,395],{"class":166,"line":287},[164,396,397],{},"      const user = await api.getUser()\n",[164,399,400],{"class":166,"line":293},[164,401,402],{},"      commit('SET_USER', user)\n",[164,404,405],{"class":166,"line":299},[164,406,378],{},[164,408,409],{"class":166,"line":304},[164,410,411],{},"  }\n",[164,413,414],{"class":166,"line":310},[164,415,416],{},"}\n",[164,418,419],{"class":166,"line":316},[164,420,231],{"emptyLinePlaceholder":230},[164,422,423],{"class":166,"line":322},[164,424,425],{},"// After (Pinia)\n",[164,427,429],{"class":166,"line":428},20,[164,430,431],{},"export const useUserStore = defineStore('user', () => {\n",[164,433,435],{"class":166,"line":434},21,[164,436,437],{},"  const user = ref(null)\n",[164,439,441],{"class":166,"line":440},22,[164,442,443],{},"  \n",[164,445,447],{"class":166,"line":446},23,[164,448,449],{},"  const fetchUser = async () => {\n",[164,451,453],{"class":166,"line":452},24,[164,454,455],{},"    user.value = await api.getUser()\n",[164,457,459],{"class":166,"line":458},25,[164,460,411],{},[164,462,464],{"class":166,"line":463},26,[164,465,443],{},[164,467,469],{"class":166,"line":468},27,[164,470,471],{},"  return { user, fetchUser }\n",[164,473,475],{"class":166,"line":474},28,[164,476,325],{},[41,478,480],{"id":479},"step-5-component-migration","Step 5: Component Migration",[155,482,486],{"className":483,"code":484,"language":485,"meta":160,"style":160},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C!-- Before (Options API) -->\n\u003Ctemplate>\n  \u003Cdiv>{{ message }}\u003C/div>\n\u003C/template>\n\n\u003Cscript>\nexport default {\n  data() {\n    return {\n      message: 'Hello Vue 2!'\n    }\n  },\n  methods: {\n    updateMessage() {\n      this.message = 'Updated!'\n    }\n  }\n}\n\u003C/script>\n\n\u003C!-- After (Composition API) -->\n\u003Ctemplate>\n  \u003Cdiv>{{ message }}\u003C/div>\n\u003C/template>\n\n\u003Cscript setup>\nimport { ref } from 'vue'\n\nconst message = ref('Hello Vue 3!')\n\nconst updateMessage = () => {\n  message.value = 'Updated!'\n}\n\u003C/script>\n","vue",[88,487,488,493,506,528,537,541,550,562,572,579,596,600,604,613,622,640,644,648,652,660,664,669,677,693,701,705,717,740,744,772,777,795,815,820],{"__ignoreMap":160},[164,489,490],{"class":166,"line":167},[164,491,492],{"class":170},"\u003C!-- Before (Options API) -->\n",[164,494,495,499,503],{"class":166,"line":174},[164,496,498],{"class":497},"sMK4o","\u003C",[164,500,502],{"class":501},"swJcz","template",[164,504,505],{"class":497},">\n",[164,507,508,511,514,517,521,524,526],{"class":166,"line":194},[164,509,510],{"class":497},"  \u003C",[164,512,513],{"class":501},"div",[164,515,516],{"class":497},">{{",[164,518,520],{"class":519},"sTEyZ"," message ",[164,522,523],{"class":497},"}}\u003C/",[164,525,513],{"class":501},[164,527,505],{"class":497},[164,529,530,533,535],{"class":166,"line":234},[164,531,532],{"class":497},"\u003C/",[164,534,502],{"class":501},[164,536,505],{"class":497},[164,538,539],{"class":166,"line":240},[164,540,231],{"emptyLinePlaceholder":230},[164,542,543,545,548],{"class":166,"line":246},[164,544,498],{"class":497},[164,546,547],{"class":501},"script",[164,549,505],{"class":497},[164,551,552,556,559],{"class":166,"line":251},[164,553,555],{"class":554},"s7zQu","export",[164,557,558],{"class":554}," default",[164,560,561],{"class":497}," {\n",[164,563,564,567,570],{"class":166,"line":257},[164,565,566],{"class":501},"  data",[164,568,569],{"class":497},"()",[164,571,561],{"class":497},[164,573,574,577],{"class":166,"line":263},[164,575,576],{"class":554},"    return",[164,578,561],{"class":497},[164,580,581,584,587,590,593],{"class":166,"line":269},[164,582,583],{"class":501},"      message",[164,585,586],{"class":497},":",[164,588,589],{"class":497}," '",[164,591,592],{"class":181},"Hello Vue 2!",[164,594,595],{"class":497},"'\n",[164,597,598],{"class":166,"line":275},[164,599,378],{"class":497},[164,601,602],{"class":166,"line":281},[164,603,284],{"class":497},[164,605,606,609,611],{"class":166,"line":287},[164,607,608],{"class":501},"  methods",[164,610,586],{"class":497},[164,612,561],{"class":497},[164,614,615,618,620],{"class":166,"line":293},[164,616,617],{"class":501},"    updateMessage",[164,619,569],{"class":497},[164,621,561],{"class":497},[164,623,624,627,630,633,635,638],{"class":166,"line":299},[164,625,626],{"class":497},"      this.",[164,628,629],{"class":519},"message",[164,631,632],{"class":497}," =",[164,634,589],{"class":497},[164,636,637],{"class":181},"Updated!",[164,639,595],{"class":497},[164,641,642],{"class":166,"line":304},[164,643,378],{"class":497},[164,645,646],{"class":166,"line":310},[164,647,411],{"class":497},[164,649,650],{"class":166,"line":316},[164,651,416],{"class":497},[164,653,654,656,658],{"class":166,"line":322},[164,655,532],{"class":497},[164,657,547],{"class":501},[164,659,505],{"class":497},[164,661,662],{"class":166,"line":428},[164,663,231],{"emptyLinePlaceholder":230},[164,665,666],{"class":166,"line":434},[164,667,668],{"class":170},"\u003C!-- After (Composition API) -->\n",[164,670,671,673,675],{"class":166,"line":440},[164,672,498],{"class":497},[164,674,502],{"class":501},[164,676,505],{"class":497},[164,678,679,681,683,685,687,689,691],{"class":166,"line":446},[164,680,510],{"class":497},[164,682,513],{"class":501},[164,684,516],{"class":497},[164,686,520],{"class":519},[164,688,523],{"class":497},[164,690,513],{"class":501},[164,692,505],{"class":497},[164,694,695,697,699],{"class":166,"line":452},[164,696,532],{"class":497},[164,698,502],{"class":501},[164,700,505],{"class":497},[164,702,703],{"class":166,"line":458},[164,704,231],{"emptyLinePlaceholder":230},[164,706,707,709,711,715],{"class":166,"line":463},[164,708,498],{"class":497},[164,710,547],{"class":501},[164,712,714],{"class":713},"spNyl"," setup",[164,716,505],{"class":497},[164,718,719,722,725,728,731,734,736,738],{"class":166,"line":468},[164,720,721],{"class":554},"import",[164,723,724],{"class":497}," {",[164,726,727],{"class":519}," ref",[164,729,730],{"class":497}," }",[164,732,733],{"class":554}," from",[164,735,589],{"class":497},[164,737,485],{"class":181},[164,739,595],{"class":497},[164,741,742],{"class":166,"line":474},[164,743,231],{"emptyLinePlaceholder":230},[164,745,747,750,752,755,758,761,764,767,769],{"class":166,"line":746},29,[164,748,749],{"class":713},"const",[164,751,520],{"class":519},[164,753,754],{"class":497},"=",[164,756,727],{"class":757},"s2Zo4",[164,759,760],{"class":519},"(",[164,762,763],{"class":497},"'",[164,765,766],{"class":181},"Hello Vue 3!",[164,768,763],{"class":497},[164,770,771],{"class":519},")\n",[164,773,775],{"class":166,"line":774},30,[164,776,231],{"emptyLinePlaceholder":230},[164,778,780,782,785,787,790,793],{"class":166,"line":779},31,[164,781,749],{"class":713},[164,783,784],{"class":519}," updateMessage ",[164,786,754],{"class":497},[164,788,789],{"class":497}," ()",[164,791,792],{"class":713}," =>",[164,794,561],{"class":497},[164,796,798,801,804,807,809,811,813],{"class":166,"line":797},32,[164,799,800],{"class":519},"  message",[164,802,803],{"class":497},".",[164,805,806],{"class":519},"value",[164,808,632],{"class":497},[164,810,589],{"class":497},[164,812,637],{"class":181},[164,814,595],{"class":497},[164,816,818],{"class":166,"line":817},33,[164,819,416],{"class":497},[164,821,823,825,827],{"class":166,"line":822},34,[164,824,532],{"class":497},[164,826,547],{"class":501},[164,828,505],{"class":497},[36,830,832],{"id":831},"key-benefits-of-the-migration","Key Benefits of the Migration",[41,834,836],{"id":835},"performance-improvements","🚀 Performance Improvements",[838,839,840,848,854],"ul",{},[841,842,843,847],"li",{},[844,845,846],"strong",{},"Smaller Bundle Size",": Vue 3's tree-shaking is more effective",[841,849,850,853],{},[844,851,852],{},"Faster Rendering",": Improved virtual DOM implementation",[841,855,856,859],{},[844,857,858],{},"Better Memory Management",": Reduced memory leaks and better garbage collection",[41,861,863],{"id":862},"️-developer-experience","🛠️ Developer Experience",[838,865,866,872,878],{},[841,867,868,871],{},[844,869,870],{},"TypeScript Support",": Better TypeScript integration out of the box",[841,873,874,877],{},[844,875,876],{},"Composition API",": More flexible and reusable logic",[841,879,880,883],{},[844,881,882],{},"Better Tooling",": Enhanced DevTools and debugging capabilities",[41,885,887],{"id":886},"modern-features","📱 Modern Features",[838,889,890,896,902],{},[841,891,892,895],{},[844,893,894],{},"Teleport",": Better modal and popup handling",[841,897,898,901],{},[844,899,900],{},"Fragments",": Multiple root nodes in components",[841,903,904,907],{},[844,905,906],{},"Suspense",": Better async component handling",[36,909,911],{"id":910},"lessons-learned","Lessons Learned",[913,914,915,921,927,933,939],"ol",{},[841,916,917,920],{},[844,918,919],{},"Plan Thoroughly",": Don't start migration without a solid plan",[841,922,923,926],{},[844,924,925],{},"Test Incrementally",": Migrate one component at a time",[841,928,929,932],{},[844,930,931],{},"Keep Backups",": Always have a working version to fall back to",[841,934,935,938],{},[844,936,937],{},"Document Changes",": Keep track of what you've changed and why",[841,940,941,944],{},[844,942,943],{},"Team Communication",": Ensure everyone understands the migration process",[36,946,948],{"id":947},"current-status","Current Status",[32,950,951],{},"Now the project is running smoothly with Vue 3 and Pinia! 😍",[32,953,954],{},"The migration was challenging but incredibly rewarding. I now have a much deeper understanding of Vue's ecosystem and feel more confident working with modern Vue applications.",[36,956,958],{"id":957},"looking-forward","Looking Forward",[32,960,961],{},"This experience has opened up new possibilities for future projects. I'm now considering:",[838,963,964,967,970],{},[841,965,966],{},"Exploring Nuxt 3 for new projects (best of both worlds!)",[841,968,969],{},"Implementing more advanced Vue 3 features",[841,971,972],{},"Sharing knowledge with other developers going through similar migrations",[36,974,976],{"id":975},"questions-for-you","Questions for You",[32,978,979],{},"Have you tried doing an upgrade before? Or have you considered leaving Nuxt to work with Vue only? I'd love to hear about your experiences and maybe share some tips!",[32,981,982],{},"What migration challenges have you faced, and how did you overcome them? Let's discuss in the comments! 💪🔥",[984,985],"hr",{},[32,987,988],{},[989,990,991],"em",{},"This post was originally shared on LinkedIn. Follow me for more insights on Vue development and migration strategies!",[993,994,995],"style",{},"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 .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}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}",{"title":160,"searchDepth":174,"depth":174,"links":997},[998,1004,1010,1015,1022,1027,1028,1029,1030],{"id":38,"depth":174,"text":39,"children":999},[1000,1001,1002,1003],{"id":43,"depth":194,"text":44},{"id":50,"depth":194,"text":51},{"id":57,"depth":194,"text":58},{"id":64,"depth":194,"text":65},{"id":71,"depth":174,"text":72,"children":1005},[1006,1007,1008,1009],{"id":75,"depth":194,"text":76},{"id":82,"depth":194,"text":83},{"id":98,"depth":194,"text":99},{"id":109,"depth":194,"text":110},{"id":116,"depth":174,"text":117,"children":1011},[1012,1013,1014],{"id":120,"depth":194,"text":121},{"id":127,"depth":194,"text":128},{"id":134,"depth":194,"text":135},{"id":141,"depth":174,"text":142,"children":1016},[1017,1018,1019,1020,1021],{"id":145,"depth":194,"text":146},{"id":152,"depth":194,"text":153},{"id":207,"depth":194,"text":208},{"id":328,"depth":194,"text":329},{"id":479,"depth":194,"text":480},{"id":831,"depth":174,"text":832,"children":1023},[1024,1025,1026],{"id":835,"depth":194,"text":836},{"id":862,"depth":194,"text":863},{"id":886,"depth":194,"text":887},{"id":910,"depth":174,"text":911},{"id":947,"depth":174,"text":948},{"id":957,"depth":174,"text":958},{"id":975,"depth":174,"text":976},"2025-04-25T00:00:00.000Z","A detailed account of my experience upgrading a project from Nuxt 2 to Vue 3, replacing Vuex with Pinia, and the valuable lessons learned along the way.","md","https://fiverr-res.cloudinary.com/images/t_main1,q_auto,f_auto,q_auto,f_auto/gigs/315813903/original/b71203fbbb69ff891b0863275fb3a275a81ea566/migrate-vue-2-to-vue-3-seamlessly-expert-vuejs-developer.png",{"tags":1036},[1037,1038,1039,1040,1041,1042],"Vue 3","Nuxt","Pinia","Migration","Web Development","State Management",{"title":18,"description":1032},"szVkHNvdOYKvJQ6TlU2KB5oJjytmUQik0BIEzyPqRbY",[1046,1048],{"title":14,"path":15,"stem":16,"description":1047,"children":-1},"A comprehensive guide to cookie-based authentication systems, how they work, security risks, and how to avoid them. Includes advanced penetration testing insights and real-world attack scenarios.",null,1782857531467]