Pindrop.js Adapters

Connect Pindrop to a custom backend for real-time sync

An adapter is a plain object with load and save methods. Pass it to Pindrop.init() to replace localStorage with any backend.

typescript
interface PindropAdapter {
  load(): Promise<unknown[]>
  save(comments: unknown[]): Promise<void>
}

Unread state is handled for you

When an adapter is connected, Pindrop automatically tracks which comments each visitor has read in their browser's localStorage. You don't store or return an unread field — the library computes it on load and strips it before calling save. Each visitor gets independent per-device unread state with no auth required.

Supabase Adapter

This is exactly what powers the live demo on the homepage.

1. Create a table in Supabase:

sql
create table demo_comments (
  id integer primary key,
  data jsonb not null default '[]'::jsonb
);
 
insert into demo_comments (id, data) values (1, '[]');

2. Wire the adapter:

typescript
import { Pindrop } from 'pindrop.js'
 
const SUPABASE_URL = 'https://your-project.supabase.co'
const SUPABASE_KEY = 'your-anon-key'
 
const headers = {
  apikey: SUPABASE_KEY,
  Authorization: `Bearer ${SUPABASE_KEY}`,
  'Content-Type': 'application/json',
  Prefer: 'return=representation',
}
 
const adapter = {
  load: async () => {
    const res = await fetch(`${SUPABASE_URL}/rest/v1/demo_comments?id=eq.1`, { headers })
    const data = await res.json()
    return data?.[0]?.data ?? []
  },
  save: async (comments) => {
    await fetch(`${SUPABASE_URL}/rest/v1/demo_comments?id=eq.1`, {
      method: 'PATCH',
      headers,
      body: JSON.stringify({ data: comments }),
    })
  },
}
 
Pindrop.init({ adapter })

No Supabase SDK required — just fetch.

REST API Adapter

typescript
const adapter = {
  load: async () => {
    const res = await fetch('/api/comments')
    return res.json()
  },
  save: async (comments) => {
    await fetch('/api/comments', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(comments),
    })
  },
}

Last updated March 28, 2026