> 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/integrating-supabase.md).

# Integrating Supabase

This guide explains how to integrate Supabase in the Appintos (mini app) WebView environment. The Supabase JS client works regardless of framework. The code example is **Vite (React + TypeScript)** based.

***

### Overview

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

***

### 1. Preparation

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

### 2. Create a Supabase project

1. In the Supabase dashboard, **New project**to create a new project.
2. Set the project name, database password, and region, then finish creating it.
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, it is recommended to manage Supabase connection information with environment variables. In the project root, `.env` create a file and write it as follows.

```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 as follows.

```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**

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

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

### 5. Database usage example

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

In the Supabase dashboard's **Table Editor**create the `users` table, and `id`(int8, primary key) and `name`add 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

* Reading data (`.select()`)
  * `users` from the table `id`loads the row where id is 1 only once.
  * If a row exists `name` display the value on the screen.
* Writing data (`.upsert()`)
  * the entered name `users` saves it to the table.
  * If there is no row, it creates a new one; if there is, it overwrites it.

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

* Real-time subscription: `.channel()`, `.on()`lets the UI update automatically when data changes.
* File storage: `supabase.storage`lets you upload images or files.
* Authentication integration: `With supabase.auth`you can store data per user.
  {% endhint %}

### 6. Security checklist

* Manage sensitive information with environment variables
  * Supabase URL, publishable key, etc. should not be written directly in code, but `.env`manage them with
* Do not upload environment files to Git, etc.
  * `.env` The file `.gitignore`must be added.
  * If a key is exposed, immediately reissue the key in the Supabase dashboard.
* **Be sure to set Row Level Security (RLS)**
  * By default, RLS is disabled for all Supabase tables.
  * When RLS is off, anyone can access the entire table with just the publishable key.
  * Before deployment, be sure to enable RLS and set policies so that only authenticated users can access it.
  * Supabase dashboard **Table Editor → select table → RLS** can be configured 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**

varies by SDK version.\
\
SDK 3.x\
`https://<appName>.web.tossmini.com` — live service environment \
`https://<appName>.private-web.tossmini.com` — Console QR test environment\
\
SDK 1.x \~ 2.x\
`https://<appName>.apps.tossmini.com` — live service 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/integrating-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.
