> For the complete documentation index, see [llms.txt](https://developers-apps-in-toss.toss.im/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers-apps-in-toss.toss.im/ai-vibe-coding/en/integration/connecting-supabase.md).

# Connecting Supabase

This guide explains how to integrate Supabase in the Apps in Toss (mini-app) WebView environment. The Supabase JS client works regardless of framework. The code examples are **Vite (React + TypeScript)** based.

***

### Overview

Supabase is an open-source backend service that provides authentication, databases (PostgreSQL), file storage, real-time subscriptions, and more. You can use it the same way in the Apps in Toss WebView environment, but **security settings and environment variable management**are important.

***

### 1. Getting started

* Supabase account ([supabase.com](https://supabase.com))
* a project made with Vite (React + TypeScript)
* Node.js, npm (or yarn, pnpm)

### 2. Create a Supabase project

1. In the Supabase dashboard, **New project**click to create a new project.
2. Set the project name, database password, and region, then complete the creation.
3. Once the project is ready, you can check the following information in the dashboard.

```
Project URL     : https://<project-id>.supabase.co
Publishable key : sb_publishable_xxxxxxxxxxxx
```

### 3. Set environment variables

For security, we recommend managing your Supabase connection details as environment variables. In the project root, `.env` create a file and write it like this.

```bash
VITE_SUPABASE_URL=https://<project-id>.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=sb_publishable_xxxxxxxxxxxx
```

### 4. Install and initialize Supabase

`src/supabase/client.ts` create a file and initialize the Supabase client like this.

```bash
npm install @supabase/supabase-js
```

```ts
import { createClient } from '@supabase/supabase-js';

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
const supabasePublishableKey = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY;

export const supabase = createClient(supabaseUrl, supabasePublishableKey);
```

{% hint style="info" %}
**Note**

A publishable key is a public key that can be exposed to clients, like Stripe's `pk_live_...`, or Firebase's `apiKey`. However, **you must set up RLS (Row Level Security) policies** . Without RLS, anyone with only the publishable key can read and write the entire table.

`secret` is a private key that bypasses all RLS. Use it only on the server and never expose it to the client.
{% endhint %}

### 5. Database usage example

Once the Supabase client is initialized, you can read or write data inside React components. Below is the simplest example of reading and saving a single row in `App.tsx`.

In the Supabase dashboard's **Table Editor**create a `users` table and add `id`(int8, primary key) and `name`(text) columns.

```tsx
import { useState, useEffect } from 'react';
import { supabase } from './supabase/client';

function App() {
  const [name, setName] = useState('');
  const [savedName, setSavedName] = useState('');

  // Read data from Supabase
  useEffect(() => {
    const fetchData = async () => {
      const { data } = await supabase.from('users').select('name').eq('id', 1).single();
      if (data) {
        setSavedName(data.name);
      }
    };
    fetchData();
  }, []);

  // Write data to Supabase
  const handleSave = async () => {
    await supabase.from('users').upsert({ id: 1, name });
    setSavedName(name);
    setName('');
  };

  return (
    <div style={{ padding: 24 }}>
      <h1>Simple Supabase Example</h1>
      <input value={name} onChange={(e) => setName(e.target.value)} placeholder="Enter name" />
      <button onClick={handleSave}>Save</button>
      <p>Saved name: {savedName || '(none)'}</p>

  );
}

export default App;
```

#### How it works

* Read data (`.select()`)
  * `users` fetches a row `id`where the id is 1 from the table, once.
  * If the row exists, `name` the value is displayed on screen.
* Write data (`.upsert()`)
  * the entered name to `users` the table.
  * If the row does not exist, it is created; if it does, it is overwritten.

{% hint style="info" %}
**Additional Supabase features**

* Real-time subscriptions: `.channel()`, `.on()`Using these, the UI updates automatically when data changes.
* File storage: `supabase.storage`lets you upload images or files.
* Authentication integration: `supabase.auth`used together with this, it enables user-specific data storage.
  {% endhint %}

### 6. Security checklist

* Manage sensitive information as environment variables
  * Do not write Supabase URL, publishable key, etc. directly in code; manage them `.env`with
* Do not upload environment files to Git, etc.
  * `.env` Be sure to add the `.gitignore`file.
  * If a key is exposed, immediately reissue the key in the Supabase dashboard.
* **Be sure to set Row Level Security (RLS)**
  * All tables in Supabase have RLS disabled by default.
  * When RLS is off, anyone with only the publishable key can access the entire table.
  * Before deployment, be sure to enable RLS and set policies so only authenticated users can access it.
  * Supabase dashboard **Table Editor → select table → RLS** You can configure it in the tab.
* Check origin restrictions
  * In the Supabase dashboard's **Authentication → URL Configuration**set the allowed domains here.
  * Allowing only the mini-app (WebView) domain can prevent unauthorized access.

{% hint style="info" %}
**Allowed domains**

Depend on the SDK version.\
\
SDK 3.x\
`https://<appName>.web.tossmini.com` — production environment \
`https://<appName>.private-web.tossmini.com` — console QR test environment\
\
SDK 1.x \~ 2.x\
`https://<appName>.apps.tossmini.com` — production environment \
`https://<appName>.private-apps.tossmini.com` — console QR test environment
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers-apps-in-toss.toss.im/ai-vibe-coding/en/integration/connecting-supabase.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
