Dashboard

Todo + RLS

A minimal todo app where each user only sees their own rows.

What you'll build

Sign up → create todos scoped to uid() → list only your rows using the anon key + session.

1. Schema

Run in SQL editor or Migrations:

schema.sql
CREATE TABLE todos (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL,
  title TEXT NOT NULL,
  done BOOLEAN NOT NULL DEFAULT false,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX todos_user_id_idx ON todos (user_id);

2. Policies

policies.sql
ALTER TABLE todos ENABLE ROW LEVEL SECURITY;

CREATE POLICY "users manage own todos"
  ON todos
  FOR ALL
  TO authenticated
  USING (uid() = user_id)
  WITH CHECK (uid() = user_id);

Or use the table editor → Policies tab (roles: authenticated, using/with check: uid() = user_id).

3. Client

Pick your framework — selection is remembered across examples.

app/todos/page.tsx
'use client';

import { useEffect, useState } from 'react';
import { createClient } from 'voltbase-js';

const voltbase = createClient(
  process.env.NEXT_PUBLIC_VOLTBASE_URL!,
  process.env.NEXT_PUBLIC_VOLTBASE_ANON_KEY!,
);

type Todo = { id: string; title: string; done: boolean };

export default function TodosPage() {
  const [todos, setTodos] = useState<Todo[]>([]);
  const [title, setTitle] = useState('');

  useEffect(() => {
    void load();
  }, []);

  async function load() {
    const { data } = await voltbase
      .from('todos')
      .select('*')
      .order('created_at', 'desc');
    setTodos((data as Todo[]) ?? []);
  }

  async function addTodo() {
    const user = voltbase.auth.getUser();
    if (!user) {
      await voltbase.auth.signUp({
        email: 'you@example.com',
        password: 'password123',
      });
    }
    await voltbase.from('todos').insert({
      user_id: voltbase.auth.getUser()!.id,
      title,
    });
    setTitle('');
    await load();
  }

  return (
    <div>
      <input value={title} onChange={(e) => setTitle(e.target.value)} />
      <button onClick={() => void addTodo()}>Add</button>
      <ul>
        {todos.map((t) => (
          <li key={t.id}>{t.title}</li>
        ))}
      </ul>
    </div>
  );
}
Need env + client setup first? See the matching framework quickstart.