[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"header-categories":3,"post-environment-variables-configuration-management":73,"parsed-post-ad6af943-1ec0-434d-8b6a-54c3a4383240":147},{"success":4,"data":5},true,{"items":6,"pagination":70},[7,16,24,32,40,48,56,63],{"id":8,"name":9,"description":10,"parentId":11,"createdAt":12,"updatedAt":12,"parent":11,"children":13,"_count":14},"ai-future","AI & The Future","Artificial intelligence and emerging technology",null,"2026-07-24T06:02:45.990Z",[],{"posts":15},1,{"id":17,"name":18,"description":19,"parentId":11,"createdAt":20,"updatedAt":20,"parent":11,"children":21,"_count":22},"tools-productivity","Tools & Productivity","Developer tools and workflow optimization","2026-07-24T06:02:45.712Z",[],{"posts":23},7,{"id":25,"name":26,"description":27,"parentId":11,"createdAt":28,"updatedAt":28,"parent":11,"children":29,"_count":30},"career","Career & Growth","Professional development for developers","2026-07-24T06:02:45.486Z",[],{"posts":31},3,{"id":33,"name":34,"description":35,"parentId":11,"createdAt":36,"updatedAt":36,"parent":11,"children":37,"_count":38},"opinion","Opinion & Analysis","Industry analysis and technical opinions","2026-07-24T06:02:45.272Z",[],{"posts":39},6,{"id":41,"name":42,"description":43,"parentId":11,"createdAt":44,"updatedAt":44,"parent":11,"children":45,"_count":46},"tutorials","Tutorials","Step-by-step learning guides","2026-07-24T06:02:44.965Z",[],{"posts":47},21,{"id":49,"name":50,"description":51,"parentId":11,"createdAt":52,"updatedAt":52,"parent":11,"children":53,"_count":54},"software-engineering","Software Engineering","Best practices, patterns, and principles","2026-07-24T06:02:44.689Z",[],{"posts":55},24,{"id":57,"name":58,"description":59,"parentId":11,"createdAt":60,"updatedAt":60,"parent":11,"children":61,"_count":62},"devops-cloud","DevOps & Cloud","Infrastructure, deployment, and cloud computing","2026-07-24T06:02:44.453Z",[],{"posts":39},{"id":64,"name":65,"description":66,"parentId":11,"createdAt":67,"updatedAt":67,"parent":11,"children":68,"_count":69},"web-development","Web Development","Frontend and backend web development tutorials and guides","2026-07-24T06:02:44.169Z",[],{"posts":55},{"page":15,"limit":71,"total":71,"totalPages":15,"hasNext":72,"hasPrev":72},8,false,{"success":4,"data":74},{"id":75,"slug":76,"title":77,"excerpt":78,"content":79,"status":80,"visibility":81,"featuredImage":82,"canonicalUrl":11,"readingTime":23,"viewCount":83,"commentEnabled":4,"publishedAt":84,"scheduledAt":11,"createdAt":85,"updatedAt":86,"seoTitle":87,"seoDescription":78,"seoKeywords":11,"authorId":88,"author":89,"coAuthors":94,"tags":95,"categories":111,"comments":114,"_count":115,"relatedPosts":117},"ad6af943-1ec0-434d-8b6a-54c3a4383240","environment-variables-configuration-management","Environment Variables and Configuration Management","Manage application configuration properly across development, staging, and production with validation, type safety, and security.","## The Config Hierarchy\n\nConfiguration should flow from least to most specific:\n\n1. **Defaults** (in code) → lowest priority\n2. **Config files** (.env.local, config.yaml)\n3. **Environment variables** → highest priority\n\n## Validated Configuration with Zod\n\nNever trust raw `process.env`:\n\n```typescript\n\u002F\u002F config\u002Fenv.ts\nimport { z } from 'zod'\n\nconst EnvSchema = z.object({\n  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),\n  DATABASE_URL: z.string().url(),\n  REDIS_URL: z.string().url().optional(),\n  AUTH_SECRET: z.string().min(32),\n  PORT: z.coerce.number().default(3000),\n  SMTP_HOST: z.string().optional(),\n  SMTP_PORT: z.coerce.number().optional(),\n  LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),\n})\n\nexport type Env = z.infer\u003Ctypeof EnvSchema>\n\nfunction validateEnv(): Env {\n  const result = EnvSchema.safeParse(process.env)\n\n  if (!result.success) {\n    console.error('❌ Invalid environment variables:')\n    console.error(result.error.format())\n    process.exit(1)\n  }\n\n  return result.data\n}\n\nexport const env = validateEnv()\n```\n\n::callout{icon=\"i-lucide-shield-check\" color=\"success\"}\nValidate at startup. Fail fast with a clear error message listing exactly which variables are missing or invalid. Don't discover config issues at 3am under load.\n::\n\n## Nuxt Runtime Config\n\n```typescript\n\u002F\u002F nuxt.config.ts\nexport default defineNuxtConfig({\n  runtimeConfig: {\n    \u002F\u002F Server-only (never exposed to client)\n    databaseUrl: '',\n    authSecret: '',\n\n    \u002F\u002F Public (available in client)\n    public: {\n      siteUrl: 'http:\u002F\u002Flocalhost:3000',\n      apiBase: '\u002Fapi',\n    },\n  },\n})\n```\n\nEnvironment variables automatically override with `NUXT_` prefix:\n- `NUXT_DATABASE_URL` → `runtimeConfig.databaseUrl`\n- `NUXT_PUBLIC_SITE_URL` → `runtimeConfig.public.siteUrl`\n\n## .env File Management\n\n```bash\n# .env.example (committed to git — documentation)\nDATABASE_URL=postgres:\u002F\u002Fuser:pass@localhost:5432\u002Fmydb\nAUTH_SECRET=change-me-to-at-least-32-characters\nREDIS_URL=redis:\u002F\u002Flocalhost:6379\n\n# .env (NOT committed — local overrides)\nDATABASE_URL=postgres:\u002F\u002Freal:creds@prod-host:5432\u002Fprod\n\n# .env.test (committed — test configuration)\nDATABASE_URL=postgres:\u002F\u002Ftest:test@localhost:5432\u002Ftest_db\n```\n\n## The .env.example Pattern\n\n```bash\n#!\u002Fbin\u002Fbash\n# scripts\u002Fcheck-env.sh — Run in CI to verify env is complete\n\nrequired_vars=(\n  \"DATABASE_URL\"\n  \"AUTH_SECRET\"\n  \"REDIS_URL\"\n)\n\nmissing=()\nfor var in \"${required_vars[@]}\"; do\n  if [ -z \"${!var}\" ]; then\n    missing+=(\"$var\")\n  fi\ndone\n\nif [ ${#missing[@]} -ne 0 ]; then\n  echo \"❌ Missing environment variables:\"\n  printf '  - %s\\n' \"${missing[@]}\"\n  exit 1\nfi\n```\n\n## Security Rules\n\n1. **Never commit secrets** — Use .gitignore, audit with git-secrets\n2. **Different secrets per environment** — Dev ≠ Staging ≠ Prod\n3. **Rotate regularly** — Especially after team changes\n4. **Least privilege** — Each service gets only the vars it needs\n5. **Encrypt at rest** — Use secrets managers (AWS SSM, Vault, Doppler)\n\n## Summary\n\nGood config management: validate early, fail clearly, separate secrets from code, and make environments self-documenting with .env.example.\n","published","public","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1559028012-481c04fa702d?w=1200&q=80",1564,"2026-05-04T06:04:21.021Z","2026-07-24T06:04:21.024Z","2026-07-28T13:21:44.316Z","Environment Variables and Configuration Management | BitBlog","fddb5d93-7a2c-4d86-a06a-fa32e73a01c6",{"email":90,"bio":91,"id":88,"name":92,"avatarUrl":93},"mbeahessilfieprince@gmail.com","Fullstack Software Developer ","Mbeah Essilfie","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F93322394?v=4",[],[96,101,106],{"id":97,"name":98,"color":99,"description":100},"nodejs","Node.js","#339933","JavaScript runtime built on V8",{"id":102,"name":103,"color":104,"description":105},"devops","DevOps","#ff6c37","Development and Operations",{"id":107,"name":108,"color":109,"description":110},"security","Security","#d63031","Web security best practices",[112,113],{"id":57,"name":58,"description":59},{"id":49,"name":50,"description":51},[],{"comments":116},0,[118,127,137],{"id":119,"slug":120,"title":121,"excerpt":122,"featuredImage":123,"viewCount":124,"readingTime":71,"publishedAt":125,"author":126},"2997028f-4d22-4eb7-9d86-894a54cb559a","building-type-safe-apis-nuxt3-prisma","Building Type-Safe APIs with Nuxt 3 and Prisma","Learn how to build end-to-end type-safe APIs using Nuxt 3 server routes and Prisma ORM for a seamless developer experience.","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1498050108023-c5249f4df085?w=1200&q=80",1922,"2026-07-23T06:02:46.910Z",{"id":88,"name":92,"avatarUrl":93},{"id":128,"slug":129,"title":130,"excerpt":131,"featuredImage":132,"viewCount":133,"readingTime":134,"publishedAt":135,"author":136},"da9e4553-8b0d-411e-b4ec-f9684017e163","mastering-tailwind-css-design-systems","Mastering Tailwind CSS: From Utility Classes to Design Systems","Go beyond basic utility classes and learn how to build cohesive, maintainable design systems with Tailwind CSS.","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1555066931-4365d14bab8c?w=1200&q=80",257,10,"2026-07-21T06:02:49.268Z",{"id":88,"name":92,"avatarUrl":93},{"id":138,"slug":139,"title":140,"excerpt":141,"featuredImage":142,"viewCount":143,"readingTime":144,"publishedAt":145,"author":146},"50add5fc-4026-4267-b917-7f71ea9e35b0","complete-guide-vue3-composables","The Complete Guide to Vue 3 Composables","Understand the power of Vue 3's Composition API through practical, real-world composable patterns that you can use today.","https:\u002F\u002Fimages.unsplash.com\u002Fphoto-1517694712202-14dd9538aa97?w=1200&q=80",990,12,"2026-07-19T06:02:51.753Z",{"id":88,"name":92,"avatarUrl":93},{"data":148,"body":150,"toc":416},{"title":149,"description":149},"",{"type":151,"children":152},"root",[153,162,168,204,210,224,236,247,253,261,274,311,317,327,333,341,347,400,406,411],{"type":154,"tag":155,"props":156,"children":158},"element","h2",{"id":157},"the-config-hierarchy",[159],{"type":160,"value":161},"text","The Config Hierarchy",{"type":154,"tag":163,"props":164,"children":165},"p",{},[166],{"type":160,"value":167},"Configuration should flow from least to most specific:",{"type":154,"tag":169,"props":170,"children":171},"ol",{},[172,184,194],{"type":154,"tag":173,"props":174,"children":175},"li",{},[176,182],{"type":154,"tag":177,"props":178,"children":179},"strong",{},[180],{"type":160,"value":181},"Defaults",{"type":160,"value":183}," (in code) → lowest priority",{"type":154,"tag":173,"props":185,"children":186},{},[187,192],{"type":154,"tag":177,"props":188,"children":189},{},[190],{"type":160,"value":191},"Config files",{"type":160,"value":193}," (.env.local, config.yaml)",{"type":154,"tag":173,"props":195,"children":196},{},[197,202],{"type":154,"tag":177,"props":198,"children":199},{},[200],{"type":160,"value":201},"Environment variables",{"type":160,"value":203}," → highest priority",{"type":154,"tag":155,"props":205,"children":207},{"id":206},"validated-configuration-with-zod",[208],{"type":160,"value":209},"Validated Configuration with Zod",{"type":154,"tag":163,"props":211,"children":212},{},[213,215,222],{"type":160,"value":214},"Never trust raw ",{"type":154,"tag":216,"props":217,"children":219},"code",{"className":218},[],[220],{"type":160,"value":221},"process.env",{"type":160,"value":223},":",{"type":154,"tag":225,"props":226,"children":231},"pre",{"className":227,"code":228,"language":229,"meta":149,"style":230},"language-typescript","\u002F\u002F config\u002Fenv.ts\nimport { z } from 'zod'\n\nconst EnvSchema = z.object({\n  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),\n  DATABASE_URL: z.string().url(),\n  REDIS_URL: z.string().url().optional(),\n  AUTH_SECRET: z.string().min(32),\n  PORT: z.coerce.number().default(3000),\n  SMTP_HOST: z.string().optional(),\n  SMTP_PORT: z.coerce.number().optional(),\n  LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),\n})\n\nexport type Env = z.infer\u003Ctypeof EnvSchema>\n\nfunction validateEnv(): Env {\n  const result = EnvSchema.safeParse(process.env)\n\n  if (!result.success) {\n    console.error('❌ Invalid environment variables:')\n    console.error(result.error.format())\n    process.exit(1)\n  }\n\n  return result.data\n}\n\nexport const env = validateEnv()\n","typescript","undefined",[232],{"type":154,"tag":216,"props":233,"children":234},{"__ignoreMap":149},[235],{"type":160,"value":228},{"type":154,"tag":237,"props":238,"children":241},"callout",{"color":239,"icon":240},"success","i-lucide-shield-check",[242],{"type":154,"tag":163,"props":243,"children":244},{},[245],{"type":160,"value":246},"Validate at startup. Fail fast with a clear error message listing exactly which variables are missing or invalid. Don't discover config issues at 3am under load.",{"type":154,"tag":155,"props":248,"children":250},{"id":249},"nuxt-runtime-config",[251],{"type":160,"value":252},"Nuxt Runtime Config",{"type":154,"tag":225,"props":254,"children":256},{"className":227,"code":255,"language":229,"meta":149,"style":230},"\u002F\u002F nuxt.config.ts\nexport default defineNuxtConfig({\n  runtimeConfig: {\n    \u002F\u002F Server-only (never exposed to client)\n    databaseUrl: '',\n    authSecret: '',\n\n    \u002F\u002F Public (available in client)\n    public: {\n      siteUrl: 'http:\u002F\u002Flocalhost:3000',\n      apiBase: '\u002Fapi',\n    },\n  },\n})\n",[257],{"type":154,"tag":216,"props":258,"children":259},{"__ignoreMap":149},[260],{"type":160,"value":255},{"type":154,"tag":163,"props":262,"children":263},{},[264,266,272],{"type":160,"value":265},"Environment variables automatically override with ",{"type":154,"tag":216,"props":267,"children":269},{"className":268},[],[270],{"type":160,"value":271},"NUXT_",{"type":160,"value":273}," prefix:",{"type":154,"tag":275,"props":276,"children":277},"ul",{},[278,295],{"type":154,"tag":173,"props":279,"children":280},{},[281,287,289],{"type":154,"tag":216,"props":282,"children":284},{"className":283},[],[285],{"type":160,"value":286},"NUXT_DATABASE_URL",{"type":160,"value":288}," → ",{"type":154,"tag":216,"props":290,"children":292},{"className":291},[],[293],{"type":160,"value":294},"runtimeConfig.databaseUrl",{"type":154,"tag":173,"props":296,"children":297},{},[298,304,305],{"type":154,"tag":216,"props":299,"children":301},{"className":300},[],[302],{"type":160,"value":303},"NUXT_PUBLIC_SITE_URL",{"type":160,"value":288},{"type":154,"tag":216,"props":306,"children":308},{"className":307},[],[309],{"type":160,"value":310},"runtimeConfig.public.siteUrl",{"type":154,"tag":155,"props":312,"children":314},{"id":313},"env-file-management",[315],{"type":160,"value":316},".env File Management",{"type":154,"tag":225,"props":318,"children":322},{"className":319,"code":320,"language":321,"meta":149,"style":230},"language-bash","# .env.example (committed to git — documentation)\nDATABASE_URL=postgres:\u002F\u002Fuser:pass@localhost:5432\u002Fmydb\nAUTH_SECRET=change-me-to-at-least-32-characters\nREDIS_URL=redis:\u002F\u002Flocalhost:6379\n\n# .env (NOT committed — local overrides)\nDATABASE_URL=postgres:\u002F\u002Freal:creds@prod-host:5432\u002Fprod\n\n# .env.test (committed — test configuration)\nDATABASE_URL=postgres:\u002F\u002Ftest:test@localhost:5432\u002Ftest_db\n","bash",[323],{"type":154,"tag":216,"props":324,"children":325},{"__ignoreMap":149},[326],{"type":160,"value":320},{"type":154,"tag":155,"props":328,"children":330},{"id":329},"the-envexample-pattern",[331],{"type":160,"value":332},"The .env.example Pattern",{"type":154,"tag":225,"props":334,"children":336},{"className":319,"code":335,"language":321,"meta":149,"style":230},"#!\u002Fbin\u002Fbash\n# scripts\u002Fcheck-env.sh — Run in CI to verify env is complete\n\nrequired_vars=(\n  \"DATABASE_URL\"\n  \"AUTH_SECRET\"\n  \"REDIS_URL\"\n)\n\nmissing=()\nfor var in \"${required_vars[@]}\"; do\n  if [ -z \"${!var}\" ]; then\n    missing+=(\"$var\")\n  fi\ndone\n\nif [ ${#missing[@]} -ne 0 ]; then\n  echo \"❌ Missing environment variables:\"\n  printf '  - %s\\n' \"${missing[@]}\"\n  exit 1\nfi\n",[337],{"type":154,"tag":216,"props":338,"children":339},{"__ignoreMap":149},[340],{"type":160,"value":335},{"type":154,"tag":155,"props":342,"children":344},{"id":343},"security-rules",[345],{"type":160,"value":346},"Security Rules",{"type":154,"tag":169,"props":348,"children":349},{},[350,360,370,380,390],{"type":154,"tag":173,"props":351,"children":352},{},[353,358],{"type":154,"tag":177,"props":354,"children":355},{},[356],{"type":160,"value":357},"Never commit secrets",{"type":160,"value":359}," — Use .gitignore, audit with git-secrets",{"type":154,"tag":173,"props":361,"children":362},{},[363,368],{"type":154,"tag":177,"props":364,"children":365},{},[366],{"type":160,"value":367},"Different secrets per environment",{"type":160,"value":369}," — Dev ≠ Staging ≠ Prod",{"type":154,"tag":173,"props":371,"children":372},{},[373,378],{"type":154,"tag":177,"props":374,"children":375},{},[376],{"type":160,"value":377},"Rotate regularly",{"type":160,"value":379}," — Especially after team changes",{"type":154,"tag":173,"props":381,"children":382},{},[383,388],{"type":154,"tag":177,"props":384,"children":385},{},[386],{"type":160,"value":387},"Least privilege",{"type":160,"value":389}," — Each service gets only the vars it needs",{"type":154,"tag":173,"props":391,"children":392},{},[393,398],{"type":154,"tag":177,"props":394,"children":395},{},[396],{"type":160,"value":397},"Encrypt at rest",{"type":160,"value":399}," — Use secrets managers (AWS SSM, Vault, Doppler)",{"type":154,"tag":155,"props":401,"children":403},{"id":402},"summary",[404],{"type":160,"value":405},"Summary",{"type":154,"tag":163,"props":407,"children":408},{},[409],{"type":160,"value":410},"Good config management: validate early, fail clearly, separate secrets from code, and make environments self-documenting with .env.example.",{"type":154,"tag":412,"props":413,"children":414},"style",{},[415],{"type":160,"value":149},{"title":149,"searchDepth":417,"depth":417,"links":418},2,[419,420,421,422,423,424,425],{"id":157,"depth":417,"text":161},{"id":206,"depth":417,"text":209},{"id":249,"depth":417,"text":252},{"id":313,"depth":417,"text":316},{"id":329,"depth":417,"text":332},{"id":343,"depth":417,"text":346},{"id":402,"depth":417,"text":405}]