mirror of
https://github.com/supabase/supabase.git
synced 2026-09-09 11:30:17 +08:00
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Docs update ## What is the new behavior? - All 19 guides follow one step order: create project → set up database → create app → AI tooling → add keys → create client → query data → run it → go to production. Added _template.mdx with structure requirements; it is not enforced with a lint check for now - this will be a separate PR before adding new guides. - 4 new partials replace copy-pasted blocks (AI tooling, connection strings, mobile env vars, going to production). - Error handling: return a message instead of a blank page when a query fails. - All guides verified and tested separately - all work as described. What was fixed: wrong env var names in the Hono sample, a Next.js page that redirected to login, missing database permissions in Refine and Hono, and stale file paths and APIs in SvelteKit, Refine, and TanStack. - Astro, Expo, Python, Laravel, and Rails were live but missing from the quickstart grid or listing page. Added, with two new icons. ## Quick links for review Base preview: https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs **Quickstart discovery**: new Astro/Expo/Python/Laravel/Rails entries and icons - [Docs homepage grid](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs) <img width="1998" height="882" alt="CleanShot 2026-08-12 at 12 06 31@2x" src="https://github.com/user-attachments/assets/942eb7e2-1e85-4b20-a6a7-c2b127d31b2b" /> - [Getting started overview](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started) <img width="856" height="878" alt="CleanShot 2026-08-12 at 12 13 30@2x" src="https://github.com/user-attachments/assets/d48091a9-7daf-4796-a521-14116b7479c9" /> ### New shared files: **[apps/docs/content/guides/getting-started/quickstarts/_template.mdx](e311542913/apps/docs/content/guides/getting-started/quickstarts/_template.mdx)** A reference contract the other 19 quickstart guides are checked against. Documents the required frontmatter, the canonical 10-step section order, every guide's deviation from that order (and why), the direct-Postgres exception (Laravel/Rails/RedwoodJS/Spring Boot), and the discovery-surface/icon requirements for adding a new guide. No lint rule enforces it yet; that's a follow-up PR. **[apps/docs/content/_partials/quickstart_ai_tooling.mdx](e311542913/apps/docs/content/_partials/quickstart_ai_tooling.mdx)** Example: [Next.js](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/nextjs#4-set-up-ai-tooling-optional) → "Set up AI tooling" section Shared by all 19 guides: astrojs, expo-react-native, flask, flutter, hono, ios-swiftui, kotlin, laravel, nextjs, nuxtjs, reactjs, redwoodjs, refine, ruby-on-rails, solidjs, spring-boot, sveltekit, tanstack, vue **[apps/docs/content/_partials/quickstart_going_to_production.mdx](e311542913/apps/docs/content/_partials/quickstart_going_to_production.mdx)** Example: [Next.js](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/nextjs#going-to-production) → "Going to production" section Shared by all 19 guides: same full list as above **[apps/docs/content/_partials/quickstart_connection_string.mdx](e311542913/apps/docs/content/_partials/quickstart_connection_string.mdx)** Example: [Laravel](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/laravel#5-set-up-the-postgres-connection-details) → connection string setup step Shared by 3 guides: laravel, ruby-on-rails, spring-boot – the ORM/backend frameworks that connect directly to Postgres rather than through the Data API **[apps/docs/content/_partials/quickstart_mobile_env_note.mdx](e311542913/apps/docs/content/_partials/quickstart_mobile_env_note.mdx)** Example: [iOS SwiftUI](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/ios-swiftui#get-api-details:~:text=This%20guide%20substitutes%20your%20project%20URL%20and%20key%20directly) → environment variables step Shared by 3 guides: ios-swiftui, flutter, kotlin – note Expo React Native is mobile too but doesn't use this partial, since it has its own `EXPO_PUBLIC_` prefix convention inline instead. ## Per guide changes **[Astro](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/astrojs#9-query-supabase-data-from-astro)** Typed query error in the server client sample. **[Expo React Native](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/expo-react-native#8-query-data-from-the-app)** Added an `error` state alongside instruments. Also removed the broken [`--web` verification path](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/expo-react-native#9-start-the-app): expo-sqlite needs Metro wasm + COEP/COOP config the guide never had (CodeRabbit finding). **[Flask](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/flask#7-create-the-supabase-client)** Split "Create the Supabase client" and ["Query data"](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/flask#8-query-data-from-the-app) into their own steps. **[Flutter](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/flutter#9-setup-deep-links-optional)** Reworded the deep-links section; keeps the framework-specific [Android `INTERNET` permission subsection](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/flutter#android) under "Going to production." **[Hono](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/hono#6-declare-supabase-environment-variables)** Split into "Install dependencies," "Declare environment variables," "Set up anonymous sign-ins," and "Query data" as separate steps. Fixes wrong env var names from the previous sample. **[iOS SwiftUI](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/ios-swiftui#8-query-data-from-the-app)** Added an `isLoading` state so the loading overlay doesn't hang forever on a successful empty result (CodeRabbit fix). **[Kotlin](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/kotlin#5-install-dependencies)** Fixed the Compose compiler plugin declaration: `apply false` was missing from the app module (CodeRabbit finding). **[Laravel](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/laravel#5-set-up-the-postgres-connection-details)** Now uses the shared `quickstart_connection_string.mdx` partial for the session-pooler/SSL guidance instead of inline copy. **[Next.js](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/nextjs#6-allow-public-access-to-the-instruments-page)** New step fixing the page that previously redirected to login. Its middleware path check is also now segment-aware so it doesn't over-match paths like `/instruments-private` (CodeRabbit finding). **[Nuxt](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/nuxtjs#7-create-the-supabase-client)** "Create the Supabase client" and ["Query data"](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/nuxtjs#8-query-data-from-the-app) split out as their own steps. **[React](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/reactjs#7-create-the-supabase-client)** Same client-creation/[query-data](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/reactjs#8-query-data-from-the-app) split as the other Vite-based guides. **[RedwoodJS](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/redwoodjs#2-gather-database-connection-strings)** Expanded into explicit transaction-mode/session-mode connection strings, Prisma schema, migration, seed, and scaffold steps; fixes stale file paths and APIs from the previous version. **[Refine](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/refine#8-allow-writes-to-the-instruments-table)** New step fixing the missing RLS grants that made the scaffolded create/edit pages fail. **[Ruby on Rails](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/ruby-on-rails#4-set-up-the-postgres-connection-details)** Now uses `quickstart_connection_string.mdx`; added a [reminder to save the database password](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/ruby-on-rails#1-create-a-supabase-project) before it's needed for the connection string. **[SolidJS](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/solidjs#7-create-the-supabase-client)** Same client-creation/[query-data](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/solidjs#8-query-data-from-the-app) split, adapted to Solid's `resource.error`. **[Spring Boot](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/spring-boot#4-set-up-the-postgres-connection-details)** Connection-string section now uses the shared partial instead of a duplicated inline caution. **[SvelteKit](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/sveltekit#8-query-data-from-the-app)** Updated `load` functions (both `+page.js` and `+page.server.ts` variants) with explicit query-error typing; fixes stale file paths and APIs from the previous version. **[TanStack](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/tanstack#8-query-supabase-data-from-tanstack-start)** `fetchInstruments` now returns and renders the query error instead of silently returning an empty list (CodeRabbit finding); fixes stale file paths and APIs from the previous version. **[Vue](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/vue#7-create-the-supabase-client)** Same client-creation/[query-data](https://docs-git-docs-standardize-framework-quickstarts-supabase.vercel.app/docs/guides/getting-started/quickstarts/vue#8-query-data-from-the-app) split as the other Vite-based guides. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added SolidJS, RedwoodJS, Refine, Laravel, and Ruby on Rails quickstarts. * Added framework discovery entries for Astro, Expo React Native, Python, Laravel, and Rails. * Added optional AI tooling, MCP setup, connection-string, mobile configuration, and production-readiness guidance. * Added a Hono authentication example with anonymous sign-in, user details, and instrument data. * **Documentation** * Expanded setup, environment, authentication, RLS, migration, SSL, and deployment guidance. * **Bug Fixes** * Improved sample error handling for failed data requests. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Miranda Limonczenko <miranda.limonczenko@supabase.io>
213 lines
6.9 KiB
Plaintext
213 lines
6.9 KiB
Plaintext
---
|
|
title: 'Use Supabase with Spring Boot'
|
|
subtitle: 'Learn how to create a Spring Boot project and connect it to your Supabase project.'
|
|
breadcrumb: 'Framework Quickstarts'
|
|
---
|
|
|
|
<AiPrompt id="spring-boot" />
|
|
|
|
## Prerequisites
|
|
|
|
Before you begin, make sure you have:
|
|
|
|
- Java 17 or later, which you can check with `java -version`
|
|
- `curl` and `unzip`, to download and extract the generated project
|
|
|
|
<$Partial path="quickstart_create_project.mdx" />
|
|
|
|
Save your database password securely. You need it for the connection string.
|
|
|
|
<Admonition type="note">
|
|
|
|
This guide uses Spring Boot's own JPA entities and generated schema, not the shared `instruments` sample table used by other quickstarts.
|
|
|
|
</Admonition>
|
|
|
|
## 2. Create a Spring Boot project
|
|
|
|
Use [Spring Initializr](https://start.spring.io) to scaffold a new project with the Web, Spring Data JPA, and Postgres Driver dependencies. Run the following from the directory where you keep your projects.
|
|
|
|
```bash
|
|
curl https://start.spring.io/starter.zip \
|
|
-d dependencies=web,data-jpa,postgresql \
|
|
-d type=maven-project \
|
|
-d language=java \
|
|
-d groupId=com.example \
|
|
-d artifactId=instruments \
|
|
-d name=instruments \
|
|
-o instruments.zip
|
|
unzip instruments.zip -d instruments && cd instruments
|
|
```
|
|
|
|
## 3. Set up AI tooling (optional)
|
|
|
|
<$Partial path="quickstart_ai_tooling.mdx" />
|
|
|
|
## 4. Set up the Postgres connection details
|
|
|
|
<$Partial path="quickstart_connection_string.mdx" />
|
|
|
|
Select the **JDBC** tab to copy the connection string in the right format for Spring Boot.
|
|
|
|
The connection string contains your database password, and `application.properties` is committed with your project. Set the string as an environment variable instead, and set it the same way on whatever platform you deploy to.
|
|
|
|
```bash
|
|
export SUPABASE_DB_URL='jdbc:postgresql://[POOLER-HOST]:5432/postgres?user=postgres.[PROJECT-REF]&password=[YOUR-PASSWORD]&sslmode=require'
|
|
```
|
|
|
|
Then reference the variable, along with the driver, in `src/main/resources/application.properties`.
|
|
|
|
```text name=src/main/resources/application.properties
|
|
spring.datasource.url=${SUPABASE_DB_URL}
|
|
spring.datasource.driver-class-name=org.postgresql.Driver
|
|
spring.jpa.hibernate.ddl-auto=update
|
|
```
|
|
|
|
If the app fails to start with `Unable to determine Dialect without JDBC metadata`, Hibernate couldn't open a connection at all. Look above that line in the logs for the real cause, most commonly `password authentication failed`.
|
|
|
|
## 5. Change the default schema
|
|
|
|
By default Hibernate creates tables in the `public` schema. We recommend changing this as Supabase exposes the `public` schema as a [data API](/docs/guides/api).
|
|
|
|
Create the `app` schema before you start the app. Hibernate creates tables in that schema on startup, but it does not create the schema itself. Run the following in the [SQL Editor](/dashboard/project/_/sql/new):
|
|
|
|
```sql SQL_EDITOR
|
|
create schema if not exists app;
|
|
```
|
|
|
|
Then point Hibernate at the schema in `application.properties`.
|
|
|
|
```text name=src/main/resources/application.properties
|
|
spring.jpa.properties.hibernate.default_schema=app
|
|
```
|
|
|
|
## 6. Create an entity and repository
|
|
|
|
Spring Data JPA maps Java classes to database tables. Create an `Instrument` entity in `src/main/java/com/example/instruments/Instrument.java`. With `spring.jpa.hibernate.ddl-auto=update` set, Hibernate creates the `instruments` table for you when the app starts.
|
|
|
|
```java name=src/main/java/com/example/instruments/Instrument.java
|
|
package com.example.instruments;
|
|
|
|
import jakarta.persistence.Entity;
|
|
import jakarta.persistence.GeneratedValue;
|
|
import jakarta.persistence.GenerationType;
|
|
import jakarta.persistence.Id;
|
|
import jakarta.persistence.Table;
|
|
|
|
@Entity
|
|
@Table(name = "instruments")
|
|
public class Instrument {
|
|
|
|
@Id
|
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
private Long id;
|
|
|
|
private String name;
|
|
|
|
public Instrument() {}
|
|
|
|
public Instrument(String name) {
|
|
this.name = name;
|
|
}
|
|
|
|
public Long getId() {
|
|
return id;
|
|
}
|
|
|
|
public String getName() {
|
|
return name;
|
|
}
|
|
|
|
public void setName(String name) {
|
|
this.name = name;
|
|
}
|
|
}
|
|
```
|
|
|
|
Create an `InstrumentRepository` interface in the same package. Extending `JpaRepository` gives you `findAll`, `save`, and other query methods without writing any implementation.
|
|
|
|
```java name=src/main/java/com/example/instruments/InstrumentRepository.java
|
|
package com.example.instruments;
|
|
|
|
import org.springframework.data.jpa.repository.JpaRepository;
|
|
|
|
public interface InstrumentRepository extends JpaRepository<Instrument, Long> {}
|
|
```
|
|
|
|
## 7. Seed sample data
|
|
|
|
Add a `CommandLineRunner` bean to `InstrumentsApplication.java` that saves some sample instruments the first time the app starts.
|
|
|
|
```java name=src/main/java/com/example/instruments/InstrumentsApplication.java
|
|
package com.example.instruments;
|
|
|
|
import org.springframework.boot.CommandLineRunner;
|
|
import org.springframework.boot.SpringApplication;
|
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
import org.springframework.context.annotation.Bean;
|
|
|
|
@SpringBootApplication
|
|
public class InstrumentsApplication {
|
|
|
|
public static void main(String[] args) {
|
|
SpringApplication.run(InstrumentsApplication.class, args);
|
|
}
|
|
|
|
@Bean
|
|
CommandLineRunner seedInstruments(InstrumentRepository instrumentRepository) {
|
|
return args -> {
|
|
if (instrumentRepository.count() == 0) {
|
|
instrumentRepository.save(new Instrument("violin"));
|
|
instrumentRepository.save(new Instrument("viola"));
|
|
instrumentRepository.save(new Instrument("cello"));
|
|
}
|
|
};
|
|
}
|
|
}
|
|
```
|
|
|
|
## 8. Query data from the app
|
|
|
|
Create an `InstrumentController` that fetches every row from the `instruments` table through the repository and returns it as JSON.
|
|
|
|
```java name=src/main/java/com/example/instruments/InstrumentController.java
|
|
package com.example.instruments;
|
|
|
|
import java.util.List;
|
|
|
|
import org.springframework.web.bind.annotation.GetMapping;
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
|
|
@RestController
|
|
public class InstrumentController {
|
|
|
|
private final InstrumentRepository instrumentRepository;
|
|
|
|
public InstrumentController(InstrumentRepository instrumentRepository) {
|
|
this.instrumentRepository = instrumentRepository;
|
|
}
|
|
|
|
@GetMapping("/instruments")
|
|
public List<Instrument> getInstruments() {
|
|
return instrumentRepository.findAll();
|
|
}
|
|
}
|
|
```
|
|
|
|
## 9. Start the app
|
|
|
|
Run the Spring Boot app, and go to http://localhost:8080/instruments in your browser. You should see the list of instruments.
|
|
|
|
```bash
|
|
./mvnw spring-boot:run
|
|
```
|
|
|
|
<$Partial path="quickstart_going_to_production.mdx" />
|
|
|
|
## Next steps
|
|
|
|
- Set up [Auth](/docs/guides/auth) for your app
|
|
- [Insert more data](/docs/guides/database/import-data) into your database
|
|
- Upload and serve static files using [Storage](/docs/guides/storage)
|
|
- Replace `ddl-auto` with [database migrations](/docs/guides/deployment/database-migrations) before going to production
|