[{"data":1,"prerenderedAt":82},["ShallowReactive",2],{"blog-vue-3-composition-api-patterns":3,"blogs-all":19},{"data":4},{"slug":5,"category":6,"title":7,"description":8,"cover":9,"tags":10,"readTime":13,"date":14,"updatedAt":15,"seo":16,"content":18},"vue-3-composition-api-patterns","Frontend","Vue 3 Composition API Patterns I Use Every Day","Practical composable patterns — async state management, form handling, and reusable logic that keeps Vue 3 codebases clean without premature abstraction.",null,[11,12,6],"Vue","TypeScript","5 min read","2026-04-05","2026-08-07",{"title":7,"description":17,"ogImage":9},"Practical composables for async state, form validation, and reusable logic in Vue 3 — patterns I use in every Nuxt project, with real code.","## Why I Left the Options API\n\nThe Options API isn't bad. For small components it's perfectly readable. But when a component grows past a hundred lines, you feel it — logic that belongs together gets split across `data`, `computed`, `methods`, and multiple lifecycle hooks.\n\nComposition API organizes code by feature, not by hook type. Once I switched, I didn't go back.\n\n## Async State: One Pattern for Everything\n\nEvery async operation in my Vue components gets wrapped in this composable. Loading state, error state, and the execute function — all in one place, consistent across the entire app.\n\n```ts\n\u002F\u002F app\u002Fcomposables\u002FuseAsync.ts\nexport function useAsync\u003CT>(fn: () => Promise\u003CT>) {\n  const data    = ref\u003CT | null>(null)\n  const loading = ref(false)\n  const error   = ref\u003Cstring | null>(null)\n\n  async function execute(): Promise\u003Cvoid> {\n    loading.value = true\n    error.value   = null\n    try {\n      data.value = await fn()\n    } catch (e: unknown) {\n      error.value = e instanceof Error ? e.message : 'Something went wrong'\n    } finally {\n      loading.value = false\n    }\n  }\n\n  return { data: readonly(data), loading: readonly(loading), error: readonly(error), execute }\n}\n```\n\nIn a component:\n\n```vue\n\u003Cscript setup lang=\"ts\">\nconst { data: projects, loading, execute: load } = useAsync(\n  () => $fetch('\u002Fapi\u002Fv1\u002Fprojects')\n)\n\nonMounted(load)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cdiv v-if=\"loading\">Loading...\u003C\u002Fdiv>\n  \u003CProjectList v-else :projects=\"projects ?? []\" \u002F>\n\u003C\u002Ftemplate>\n```\n\n## Form State That Handles Validation\n\nFor forms I want reactive field values, server-side validation errors mapped to fields, and a clean reset function.\n\n```ts\n\u002F\u002F app\u002Fcomposables\u002FuseForm.ts\nexport function useForm\u003CT extends Record\u003Cstring, any>>(initial: T) {\n  const form   = reactive({ ...initial })\n  const errors = reactive\u003CPartial\u003CRecord\u003Ckeyof T, string>>>({})\n\n  function reset() {\n    Object.assign(form, initial)\n    Object.keys(errors).forEach(k => delete errors[k as keyof T])\n  }\n\n  function setErrors(serverErrors: Record\u003Cstring, string[]>) {\n    Object.keys(serverErrors).forEach(key => {\n      (errors as any)[key] = serverErrors[key][0] \u002F\u002F take first message per field\n    })\n  }\n\n  return { form, errors, reset, setErrors }\n}\n```\n\n```vue\n\u003Cscript setup lang=\"ts\">\nconst { form, errors, reset, setErrors } = useForm({ email: '', password: '' })\n\nasync function submit() {\n  try {\n    await $fetch('\u002Fapi\u002Flogin', { method: 'POST', body: form })\n  } catch (e: any) {\n    setErrors(e.data?.errors ?? {})\n  }\n}\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cinput v-model=\"form.email\" \u002F>\n  \u003Cspan v-if=\"errors.email\" class=\"text-red-500\">{{ errors.email }}\u003C\u002Fspan>\n\u003C\u002Ftemplate>\n```\n\n## The Naming Rule\n\nEach composable should do one thing. The name should say what that thing is — `useAuth`, `useForm`, `useActiveSection`, `useAsync`.\n\nIf I'm struggling to name a composable, it's doing too much. That's usually the signal to break it apart.\n\nThe Composition API's real advantage isn't just reuse — it's being able to read a component and know exactly which external logic it depends on, by name, without hunting through a mixed bag of options.",{"data":20},[21,34,46,56,68,79],{"slug":22,"category":23,"title":24,"description":25,"cover":9,"tags":26,"readTime":30,"date":31,"updatedAt":15,"seo":32},"prompt-engineering-for-developers","AI","Prompt Engineering for Developers: What Actually Works in Production","Practical techniques I use when integrating Claude and OpenAI APIs into real applications — output format control, system prompts, few-shot examples, and defensive parsing.",[23,27,28,29],"Claude API","OpenAI","Laravel","8 min read","2026-05-18",{"title":24,"description":33,"ogImage":9},"Format control, system prompts, few-shot examples, defensive parsing — practical prompt engineering from a year of integrating Claude and OpenAI APIs.",{"slug":35,"category":36,"title":37,"description":38,"cover":9,"tags":39,"readTime":30,"date":42,"updatedAt":15,"seo":43},"mysql-query-optimization-laravel","Database","MySQL Query Optimization in Laravel: What I Fixed in Production","Real slow-query problems I diagnosed and fixed in a production SaaS — N+1 queries, missing indexes, Eloquent gotchas, and when to drop to raw SQL.",[29,40,36,41],"MySQL","Performance","2026-05-10",{"title":44,"description":45,"ogImage":9},"MySQL Query Optimization in Laravel: Real Production Fixes","N+1 queries, missing indexes, Eloquent gotchas — real slow-query problems I diagnosed and fixed in a production Laravel SaaS. Before and after code included.",{"slug":47,"category":23,"title":48,"description":49,"cover":9,"tags":50,"readTime":52,"date":53,"updatedAt":15,"seo":54},"building-ai-features-in-laravel","Building AI Features in Laravel with the Claude API","How I integrated Claude API into a SaaS platform to automate repetitive data entry workflows — and what I got wrong before I got it right.",[29,23,27,51],"SaaS","6 min read","2026-05-01",{"title":48,"description":55,"ogImage":9},"How I integrated Claude API into a Laravel SaaS to automate data entry — queues, caching, defensive parsing, and real production lessons from SP360.",{"slug":57,"category":58,"title":59,"description":60,"cover":9,"tags":61,"readTime":64,"date":65,"updatedAt":15,"seo":66},"nuxt-4-full-stack-with-laravel-api","Full-Stack","Nuxt 4 + Laravel API: The Full-Stack Setup I Actually Ship","How I structure a Nuxt 4 frontend with a Laravel REST API — auth composable, consistent response shape, error handling, and the lessons from two years of running this in production.",[62,29,58,63],"Nuxt","API","7 min read","2026-04-18",{"title":59,"description":67,"ogImage":9},"My production-tested Nuxt 4 + Laravel 11 setup — $fetch composable, Sanctum cookie auth, consistent API responses, lessons from two years running this stack.",{"slug":69,"category":70,"title":71,"description":72,"cover":9,"tags":73,"readTime":64,"date":76,"updatedAt":15,"seo":77},"laravel-queue-jobs-real-world","Backend","Laravel Queues in Production: What Nobody Tells You","Beyond the docs — real patterns for reliable queue jobs, retry strategies, and monitoring that I use in a production SaaS application.",[29,74,70,75],"Queues","Production","2026-04-15",{"title":71,"description":78,"ogImage":9},"Real patterns for reliable Laravel queue jobs — timeouts, idempotency, cache locks, and Horizon config I use in a production SaaS application.",{"slug":5,"category":6,"title":7,"description":8,"cover":9,"tags":80,"readTime":13,"date":14,"updatedAt":15,"seo":81},[11,12,6],{"title":7,"description":17,"ogImage":9},1787446403386]