[{"data":1,"prerenderedAt":187},["ShallowReactive",2],{"blog-blueprints/react-supabase":3},{"id":4,"title":5,"body":6,"category":167,"date":168,"dateModified":168,"description":169,"draft":170,"extension":171,"faq":172,"featured":170,"headerVariant":173,"image":172,"keywords":172,"meta":174,"navigation":175,"ogDescription":176,"ogTitle":172,"path":177,"readTime":178,"schemaOrg":179,"schemaType":180,"seo":181,"sitemap":182,"stem":183,"tags":184,"twitterCard":185,"__hash__":186},"blog/blog/blueprints/react-supabase.md","React + Supabase Security Blueprint",{"type":7,"value":8,"toc":157},"minimark",[9,20,23,29,34,49,58,62,71,75,80,83,86,89,92,95,109,145],[10,11,12],"blueprint-summary",{},[13,14,15,19],"p",{},[16,17,18],"strong",{},"To secure a React + Supabase SPA,"," you need to: (1) enable Row Level Security (RLS) on ALL tables since SPAs have no server layer, (2) write and test RLS policies thoroughly before launch, (3) implement auth state management with proper session handling, (4) use only the anon key in client code (never service_role), and (5) understand that client-side route protection is UX only-RLS is your actual security. This blueprint covers pure SPA security patterns.",[21,22],"blueprint-meta",{},[24,25,26],"tldr",{},[13,27,28],{},"React SPAs with Supabase rely entirely on RLS for data security since there's no server-side code. Key tasks: enable RLS on all tables with proper policies, use auth context for session management, remember that route protection is UX-only (RLS is your actual security), and never expose the service_role key.",[30,31,33],"h2",{"id":32},"rls-is-your-security-supabase","RLS is Your Security Supabase",[35,36,38],"code-block",{"label":37},"RLS policies for React SPA",[39,40,45],"pre",{"className":41,"code":43,"language":44},[42],"language-text","-- Users can only access their own data\nCREATE POLICY \"User data isolation\"\n  ON user_data FOR ALL\n  USING (auth.uid() = user_id);\n\n-- Public read, authenticated write\nCREATE POLICY \"Public posts\"\n  ON posts FOR SELECT\n  USING (true);\n\nCREATE POLICY \"Authenticated create\"\n  ON posts FOR INSERT\n  WITH CHECK (auth.uid() = author_id);\n","text",[46,47,43],"code",{"__ignoreMap":48},"",[50,51,52],"warning-box",{},[13,53,54,57],{},[16,55,56],{},"Critical:"," In a React SPA, there's no server to protect you. RLS is your only security layer. If RLS is misconfigured, data is exposed.",[30,59,61],{"id":60},"auth-context-react","Auth Context React",[35,63,65],{"label":64},"useAuth hook",[39,66,69],{"className":67,"code":68,"language":44},[42],"import { useEffect, useState } from 'react';\nimport { supabase } from './supabase';\n\nexport function useAuth() {\n  const [user, setUser] = useState(null);\n  const [loading, setLoading] = useState(true);\n\n  useEffect(() => {\n    supabase.auth.getSession().then(({ data }) => {\n      setUser(data.session?.user ?? null);\n      setLoading(false);\n    });\n\n    const { data: { subscription } } = supabase.auth.onAuthStateChange(\n      (_event, session) => setUser(session?.user ?? null)\n    );\n\n    return () => subscription.unsubscribe();\n  }, []);\n\n  return { user, loading };\n}\n",[46,70,68],{"__ignoreMap":48},[30,72,74],{"id":73},"security-checklist","Security Checklist",[76,77,79],"h4",{"id":78},"pre-launch-checklist","Pre-Launch Checklist",[13,81,82],{},"RLS enabled on all tables",[13,84,85],{},"RLS policies tested thoroughly",[13,87,88],{},"Auth state properly handled",[13,90,91],{},"Only anon key in client code",[13,93,94],{},"Environment variables for deployment",[96,97,98,104],"related-articles",{},[99,100],"related-card",{"description":101,"href":102,"title":103},"With server-side","/blog/blueprints/nextjs-supabase-vercel","Next.js + Supabase",[99,105],{"description":106,"href":107,"title":108},"Deep dive","/blog/guides/supabase","Supabase Security Guide",[110,111,112,117,120],"stack-comparison",{},[113,114,116],"h3",{"id":115},"alternative-stacks","Alternative Stacks",[13,118,119],{},"Consider these related blueprints:",[121,122,123,131,138],"ul",{},[124,125,126,130],"li",{},[127,128,129],"a",{"href":102},"Next.js + Supabase + Vercel"," - With server-side rendering",[124,132,133,137],{},[127,134,136],{"href":135},"/blog/blueprints/react-firebase","React + Firebase"," - Firebase/Firestore alternative",[124,139,140,144],{},[127,141,143],{"href":142},"/blog/blueprints/vue-supabase","Vue + Supabase"," - Vue framework alternative",[146,147,150,154],"cta-box",{"href":148,"label":149},"/","Start Free Scan",[30,151,153],{"id":152},"building-with-this-stack","Building with this stack?",[13,155,156],{},"Scan for RLS issues.",{"title":48,"searchDepth":158,"depth":158,"links":159},2,[160,161,162,166],{"id":32,"depth":158,"text":33},{"id":60,"depth":158,"text":61},{"id":73,"depth":158,"text":74,"children":163},[164],{"id":115,"depth":165,"text":116},3,{"id":152,"depth":158,"text":153},"blueprints","2026-02-10","Security guide for React + Supabase stack. Configure RLS, handle authentication, protect client-side data, and secure your React SPA.",false,"md",null,"purple",{"noindex":175},true,"Complete security configuration for React apps with Supabase.","/blog/blueprints/react-supabase","9 min read","[object Object]","Article",{"title":5,"description":169},{"loc":177},"blog/blueprints/react-supabase",[],"summary_large_image","XsM4ZdbxPc-ZB9zEtqJPyZtpaGRv3mX1LBJKpBh7S4A",1775843932116]