[{"data":1,"prerenderedAt":201},["ShallowReactive",2],{"blog-blueprints/nuxt-supabase":3},{"id":4,"title":5,"body":6,"category":180,"date":181,"dateModified":182,"description":183,"draft":184,"extension":185,"faq":186,"featured":184,"headerVariant":187,"image":186,"keywords":186,"meta":188,"navigation":189,"ogDescription":190,"ogTitle":186,"path":191,"readTime":192,"schemaOrg":193,"schemaType":194,"seo":195,"sitemap":196,"stem":197,"tags":198,"twitterCard":199,"__hash__":200},"blog/blog/blueprints/nuxt-supabase.md","Nuxt + Supabase Security Blueprint",{"type":7,"value":8,"toc":169},"minimark",[9,20,23,29,34,49,53,62,66,75,84,88,93,96,99,102,105,108,122,157],[10,11,12],"blueprint-summary",{},[13,14,15,19],"p",{},[16,17,18],"strong",{},"To secure a Nuxt + Supabase stack,"," you need to: (1) configure @nuxtjs/supabase module with proper redirect options, (2) use serverSupabaseClient and serverSupabaseUser in server routes, (3) enable RLS on all tables as defense-in-depth, (4) keep the service key server-side only in runtimeConfig, and (5) verify auth in all server API routes. This blueprint covers Nuxt 3 server routes with Supabase integration.",[21,22],"blueprint-meta",{},[24,25,26],"tldr",{},[13,27,28],{},"Nuxt with @nuxtjs/supabase provides great DX but requires understanding server vs client contexts. Key tasks: use serverSupabaseClient in API routes, enable RLS on all tables, protect server routes with middleware, and use useSupabaseUser() for reactive auth state on the client.",[30,31,33],"h2",{"id":32},"module-configuration-nuxt","Module Configuration Nuxt",[35,36,38],"code-block",{"label":37},"nuxt.config.ts",[39,40,45],"pre",{"className":41,"code":43,"language":44},[42],"language-text","export default defineNuxtConfig({\n  modules: ['@nuxtjs/supabase'],\n\n  supabase: {\n    redirectOptions: {\n      login: '/login',\n      callback: '/confirm',\n      exclude: ['/', '/about', '/blog/*'],\n    },\n  },\n\n  runtimeConfig: {\n    // Server-only\n    supabaseServiceKey: process.env.SUPABASE_SERVICE_KEY,\n    public: {\n      supabaseUrl: process.env.SUPABASE_URL,\n      supabaseKey: process.env.SUPABASE_ANON_KEY,\n    },\n  },\n})\n","text",[46,47,43],"code",{"__ignoreMap":48},"",[30,50,52],{"id":51},"server-api-routes-nuxt-supabase","Server API Routes Nuxt Supabase",[35,54,56],{"label":55},"server/api/posts.post.ts",[39,57,60],{"className":58,"code":59,"language":44},[42],"export default defineEventHandler(async (event) => {\n  const client = await serverSupabaseClient(event)\n  const user = await serverSupabaseUser(event)\n\n  if (!user) {\n    throw createError({ statusCode: 401, message: 'Unauthorized' })\n  }\n\n  const body = await readBody(event)\n\n  const { data, error } = await client.from('posts').insert({\n    title: body.title,\n    author_id: user.id,  // Use verified user ID\n  }).select().single()\n\n  if (error) throw createError({ statusCode: 400, message: error.message })\n\n  return data\n})\n",[46,61,59],{"__ignoreMap":48},[30,63,65],{"id":64},"route-middleware-nuxt","Route Middleware Nuxt",[35,67,69],{"label":68},"middleware/auth.ts",[39,70,73],{"className":71,"code":72,"language":44},[42],"export default defineNuxtRouteMiddleware((to) => {\n  const user = useSupabaseUser()\n\n  if (!user.value) {\n    return navigateTo('/login')\n  }\n})\n",[46,74,72],{"__ignoreMap":48},[76,77,78],"warning-box",{},[13,79,80,83],{},[16,81,82],{},"Client middleware is UX only."," Always verify auth server-side in API routes. RLS provides the actual security layer for database access.",[30,85,87],{"id":86},"security-checklist","Security Checklist",[89,90,92],"h4",{"id":91},"pre-launch-checklist","Pre-Launch Checklist",[13,94,95],{},"RLS enabled on all tables",[13,97,98],{},"Auth verified in all server routes",[13,100,101],{},"serverSupabaseClient used server-side",[13,103,104],{},"Service key never exposed to client",[13,106,107],{},"Environment variables configured",[109,110,111,117],"related-articles",{},[112,113],"related-card",{"description":114,"href":115,"title":116},"Client-only SPA","/blog/blueprints/vue-supabase","Vue + Supabase",[112,118],{"description":119,"href":120,"title":121},"Deep dive","/blog/guides/supabase","Supabase Security Guide",[123,124,125,130,133],"stack-comparison",{},[126,127,129],"h3",{"id":128},"alternative-stacks","Alternative Stacks",[13,131,132],{},"Consider these related blueprints:",[134,135,136,143,150],"ul",{},[137,138,139,142],"li",{},[140,141,116],"a",{"href":115}," - Client-only SPA version",[137,144,145,149],{},[140,146,148],{"href":147},"/blog/blueprints/nextjs-supabase-vercel","Next.js + Supabase + Vercel"," - React/Next.js alternative",[137,151,152,156],{},[140,153,155],{"href":154},"/blog/blueprints/sveltekit-supabase","SvelteKit + Supabase"," - Svelte alternative",[158,159,162,166],"cta-box",{"href":160,"label":161},"/","Start Free Scan",[30,163,165],{"id":164},"building-with-this-stack","Building with this stack?",[13,167,168],{},"Scan for RLS and auth issues.",{"title":48,"searchDepth":170,"depth":170,"links":171},2,[172,173,174,175,179],{"id":32,"depth":170,"text":33},{"id":51,"depth":170,"text":52},{"id":64,"depth":170,"text":65},{"id":86,"depth":170,"text":87,"children":176},[177],{"id":128,"depth":178,"text":129},3,{"id":164,"depth":170,"text":165},"blueprints","2026-02-10","2026-02-23","Security guide for Nuxt + Supabase stack. Configure RLS, use @nuxtjs/supabase module, protect server routes and API endpoints, and secure your Nuxt app.",false,"md",null,"purple",{"noindex":189},true,"Complete security configuration for Nuxt apps with Supabase.","/blog/blueprints/nuxt-supabase","10 min read","[object Object]","Article",{"title":5,"description":183},{"loc":191},"blog/blueprints/nuxt-supabase",[],"summary_large_image","1AyPE6fP_5hvYW04v_3xATwpfTn3wZqYViUN2i-eP6E",1775843932099]