diff --git a/apps/database-new/.env.local.example b/apps/database-new/.env.local.example
new file mode 100644
index 00000000000..693703197a7
--- /dev/null
+++ b/apps/database-new/.env.local.example
@@ -0,0 +1,4 @@
+# Update these with your Supabase details from your project settings > API
+# https://app.supabase.com/project/_/settings/api
+NEXT_PUBLIC_SUPABASE_URL=your-project-url
+NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
diff --git a/apps/database-new/.gitignore b/apps/database-new/.gitignore
new file mode 100644
index 00000000000..fd3dbb571a1
--- /dev/null
+++ b/apps/database-new/.gitignore
@@ -0,0 +1,36 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+.yarn/install-state.gz
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env*.local
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
diff --git a/apps/database-new/README.md b/apps/database-new/README.md
new file mode 100644
index 00000000000..9974f0c7625
--- /dev/null
+++ b/apps/database-new/README.md
@@ -0,0 +1,93 @@
+
+
+ Next.js and Supabase Starter Kit
+
+
+
+ The fastest way to build apps with Next.js and Supabase
+
+
+
+ Features ·
+ Demo ·
+ Deploy to Vercel ·
+ Clone and run locally ·
+ Feedback and issues
+ More Examples
+
+
+
+## Features
+
+- Works across the entire [Next.js](https://nextjs.org) stack
+ - App Router
+ - Pages Router
+ - Middleware
+ - Client
+ - Server
+ - It just works!
+- supabase-ssr. A package to configure Supabase Auth to use cookies
+- Styling with [Tailwind CSS](https://tailwindcss.com)
+- Optional deployment with [Supabase Vercel Integration and Vercel deploy](#deploy-your-own)
+ - Environment variables automatically assigned to Vercel project
+
+## Demo
+
+You can view a fully working demo at [demo-nextjs-with-supabase.vercel.app](https://demo-nextjs-with-supabase.vercel.app/).
+
+## Deploy to Vercel
+
+Vercel deployment will guide you through creating a Supabase account and project.
+
+After installation of the Supabase integration, all relevant environment variables will be assigned to the project so the deployment is fully functioning.
+
+[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fnext.js%2Ftree%2Fcanary%2Fexamples%2Fwith-supabase&project-name=nextjs-with-supabase&repository-name=nextjs-with-supabase&demo-title=nextjs-with-supabase&demo-description=This%20starter%20configures%20Supabase%20Auth%20to%20use%20cookies%2C%20making%20the%20user's%20session%20available%20throughout%20the%20entire%20Next.js%20app%20-%20Client%20Components%2C%20Server%20Components%2C%20Route%20Handlers%2C%20Server%20Actions%20and%20Middleware.&demo-url=https%3A%2F%2Fdemo-nextjs-with-supabase.vercel.app%2F&external-id=https%3A%2F%2Fgithub.com%2Fvercel%2Fnext.js%2Ftree%2Fcanary%2Fexamples%2Fwith-supabase&demo-image=https%3A%2F%2Fdemo-nextjs-with-supabase.vercel.app%2Fopengraph-image.png&integration-ids=oac_VqOgBHqhEoFTPzGkPd7L0iH6)
+
+The above will also clone the Starter kit to your GitHub, you can clone that locally and develop locally.
+
+If you wish to just develop locally and not deploy to Vercel, [follow the steps below](#clone-and-run-locally).
+
+## Clone and run locally
+
+1. You'll first need a Supabase project which can be made [via the Supabase dashboard](https://database.new)
+
+2. Create a Next.js app using the Supabase Starter template npx command
+
+ ```bash
+ npx create-next-app -e with-supabase
+ ```
+
+3. Use `cd` to change into the app's directory
+
+ ```bash
+ cd name-of-new-app
+ ```
+
+4. Rename `.env.local.example` to `.env.local` and update the following:
+
+ ```
+ NEXT_PUBLIC_SUPABASE_URL=[INSERT SUPABASE PROJECT URL]
+ NEXT_PUBLIC_SUPABASE_ANON_KEY=[INSERT SUPABASE PROJECT API ANON KEY]
+ ```
+
+ Both `NEXT_PUBLIC_SUPABASE_URL` and `NEXT_PUBLIC_SUPABASE_ANON_KEY` can be found in [your Supabase project's API settings](https://app.supabase.com/project/_/settings/api)
+
+5. You can now run the Next.js local development server:
+
+ ```bash
+ npm run dev
+ ```
+
+ The starter kit should now be running on [localhost:3000](http://localhost:3000/).
+
+> Check out [the docs for Local Development](https://supabase.com/docs/guides/getting-started/local-development) to also run Supabase locally.
+
+## Feedback and issues
+
+Please file feedback and issues over on the [Supabase GitHub org](https://github.com/supabase/supabase/issues/new/choose).
+
+## More Supabase examples
+
+- [Next.js Subscription Payments Starter](https://github.com/vercel/nextjs-subscription-payments)
+- [Cookie-based Auth and the Next.js 13 App Router (free course)](https://youtube.com/playlist?list=PL5S4mPUpp4OtMhpnp93EFSo42iQ40XjbF)
+- [Supabase Auth and the Next.js App Router](https://github.com/supabase/supabase/tree/master/examples/auth/nextjs)
diff --git a/apps/database-new/app/auth/callback/route.ts b/apps/database-new/app/auth/callback/route.ts
new file mode 100644
index 00000000000..3822631953d
--- /dev/null
+++ b/apps/database-new/app/auth/callback/route.ts
@@ -0,0 +1,20 @@
+import { createClient } from '@/utils/supabase/server'
+import { NextResponse } from 'next/server'
+import { cookies } from 'next/headers'
+
+export async function GET(request: Request) {
+ // The `/auth/callback` route is required for the server-side auth flow implemented
+ // by the Auth Helpers package. It exchanges an auth code for the user's session.
+ // https://supabase.com/docs/guides/auth/auth-helpers/nextjs#managing-sign-in-with-code-exchange
+ const requestUrl = new URL(request.url)
+ const code = requestUrl.searchParams.get('code')
+
+ if (code) {
+ const cookieStore = cookies()
+ const supabase = createClient(cookieStore)
+ await supabase.auth.exchangeCodeForSession(code)
+ }
+
+ // URL to redirect to after sign in process completes
+ return NextResponse.redirect(requestUrl.origin)
+}
diff --git a/apps/database-new/app/favicon.ico b/apps/database-new/app/favicon.ico
new file mode 100644
index 00000000000..718d6fea483
Binary files /dev/null and b/apps/database-new/app/favicon.ico differ
diff --git a/apps/database-new/app/globals.css b/apps/database-new/app/globals.css
new file mode 100644
index 00000000000..50bd9fc3356
--- /dev/null
+++ b/apps/database-new/app/globals.css
@@ -0,0 +1,42 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@layer base {
+ :root {
+ --background: 200 20% 98%;
+ --btn-background: 200 10% 91%;
+ --btn-background-hover: 200 10% 89%;
+ --foreground: 200 50% 3%;
+ }
+
+ @media (prefers-color-scheme: dark) {
+ :root {
+ --background: 200 50% 3%;
+ --btn-background: 200 10% 9%;
+ --btn-background-hover: 200 10% 12%;
+ --foreground: 200 20% 96%;
+ }
+ }
+}
+
+@layer base {
+ * {
+ @apply border-foreground/20;
+ }
+}
+
+.animate-in {
+ animation: animateIn 0.3s ease 0.15s both;
+}
+
+@keyframes animateIn {
+ from {
+ opacity: 0;
+ transform: translateY(10px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
diff --git a/apps/database-new/app/layout.tsx b/apps/database-new/app/layout.tsx
new file mode 100644
index 00000000000..1723001b661
--- /dev/null
+++ b/apps/database-new/app/layout.tsx
@@ -0,0 +1,22 @@
+import { GeistSans } from 'geist/font'
+import './globals.css'
+
+const defaultUrl = process.env.VERCEL_URL
+ ? `https://${process.env.VERCEL_URL}`
+ : 'http://localhost:3000'
+
+export const metadata = {
+ metadataBase: new URL(defaultUrl),
+ title: 'Next.js and Supabase Starter Kit',
+ description: 'The fastest way to build apps with Next.js and Supabase',
+}
+
+export default function RootLayout({ children }: { children: React.ReactNode }) {
+ return (
+
+
+ {children}
+
+
+ )
+}
diff --git a/apps/database-new/app/login/page.tsx b/apps/database-new/app/login/page.tsx
new file mode 100644
index 00000000000..fb9b7364ec9
--- /dev/null
+++ b/apps/database-new/app/login/page.tsx
@@ -0,0 +1,112 @@
+import Link from 'next/link'
+import { headers, cookies } from 'next/headers'
+import { createClient } from '@/utils/supabase/server'
+import { redirect } from 'next/navigation'
+
+export default function Login({ searchParams }: { searchParams: { message: string } }) {
+ const signIn = async (formData: FormData) => {
+ 'use server'
+
+ const email = formData.get('email') as string
+ const password = formData.get('password') as string
+ const cookieStore = cookies()
+ const supabase = createClient(cookieStore)
+
+ const { error } = await supabase.auth.signInWithPassword({
+ email,
+ password,
+ })
+
+ if (error) {
+ return redirect('/login?message=Could not authenticate user')
+ }
+
+ return redirect('/')
+ }
+
+ const signUp = async (formData: FormData) => {
+ 'use server'
+
+ const origin = headers().get('origin')
+ const email = formData.get('email') as string
+ const password = formData.get('password') as string
+ const cookieStore = cookies()
+ const supabase = createClient(cookieStore)
+
+ const { error } = await supabase.auth.signUp({
+ email,
+ password,
+ options: {
+ emailRedirectTo: `${origin}/auth/callback`,
+ },
+ })
+
+ if (error) {
+ return redirect('/login?message=Could not authenticate user')
+ }
+
+ return redirect('/login?message=Check email to continue sign in process')
+ }
+
+ return (
+
+
+
+
+ {' '}
+ Back
+
+
+
+
+ )
+}
diff --git a/apps/database-new/app/opengraph-image.png b/apps/database-new/app/opengraph-image.png
new file mode 100644
index 00000000000..57595e662c3
Binary files /dev/null and b/apps/database-new/app/opengraph-image.png differ
diff --git a/apps/database-new/app/page.tsx b/apps/database-new/app/page.tsx
new file mode 100644
index 00000000000..01aa7f0d420
--- /dev/null
+++ b/apps/database-new/app/page.tsx
@@ -0,0 +1,57 @@
+import DeployButton from '../components/DeployButton'
+import AuthButton from '../components/AuthButton'
+import { createClient } from '@/utils/supabase/server'
+import ConnectSupabaseSteps from '@/components/ConnectSupabaseSteps'
+import SignUpUserSteps from '@/components/SignUpUserSteps'
+import Header from '@/components/Header'
+import { cookies } from 'next/headers'
+
+export default async function Index() {
+ const cookieStore = cookies()
+
+ const canInitSupabaseClient = () => {
+ // This function is just for the interactive tutorial.
+ // Feel free to remove it once you have Supabase connected.
+ try {
+ createClient(cookieStore)
+ return true
+ } catch (e) {
+ return false
+ }
+ }
+
+ const isSupabaseConnected = canInitSupabaseClient()
+
+ return (
+
+
+
+
+ {isSupabaseConnected &&
}
+
+
+
+
+
+
+ Next steps
+ {isSupabaseConnected ? : }
+
+
+
+
+
+ )
+}
diff --git a/apps/database-new/app/twitter-image.png b/apps/database-new/app/twitter-image.png
new file mode 100644
index 00000000000..57595e662c3
Binary files /dev/null and b/apps/database-new/app/twitter-image.png differ
diff --git a/apps/database-new/components/AuthButton.tsx b/apps/database-new/components/AuthButton.tsx
new file mode 100644
index 00000000000..6e16b474ed3
--- /dev/null
+++ b/apps/database-new/components/AuthButton.tsx
@@ -0,0 +1,40 @@
+import { createClient } from '@/utils/supabase/server'
+import Link from 'next/link'
+import { cookies } from 'next/headers'
+import { redirect } from 'next/navigation'
+
+export default async function AuthButton() {
+ const cookieStore = cookies()
+ const supabase = createClient(cookieStore)
+
+ const {
+ data: { user },
+ } = await supabase.auth.getUser()
+
+ const signOut = async () => {
+ 'use server'
+
+ const cookieStore = cookies()
+ const supabase = createClient(cookieStore)
+ await supabase.auth.signOut()
+ return redirect('/login')
+ }
+
+ return user ? (
+
+ Hey, {user.email}!
+
+
+ ) : (
+
+ Login
+
+ )
+}
diff --git a/apps/database-new/components/Code.tsx b/apps/database-new/components/Code.tsx
new file mode 100644
index 00000000000..312d04ab8e2
--- /dev/null
+++ b/apps/database-new/components/Code.tsx
@@ -0,0 +1,58 @@
+'use client'
+
+import { useState } from 'react'
+
+const CopyIcon = () => (
+
+
+
+
+)
+
+const CheckIcon = () => (
+
+
+
+)
+
+export default function Code({ code }: { code: string }) {
+ const [icon, setIcon] = useState(CopyIcon)
+
+ const copy = async () => {
+ await navigator?.clipboard?.writeText(code)
+ setIcon(CheckIcon)
+ setTimeout(() => setIcon(CopyIcon), 2000)
+ }
+
+ return (
+
+
+ {icon}
+
+ {code}
+
+ )
+}
diff --git a/apps/database-new/components/ConnectSupabaseSteps.tsx b/apps/database-new/components/ConnectSupabaseSteps.tsx
new file mode 100644
index 00000000000..5a15faa5c62
--- /dev/null
+++ b/apps/database-new/components/ConnectSupabaseSteps.tsx
@@ -0,0 +1,59 @@
+import Step from './Step'
+
+export default function ConnectSupabaseSteps() {
+ return (
+
+
+
+ Head over to{' '}
+
+ database.new
+ {' '}
+ and create a new Supabase project.
+
+
+
+
+
+ Rename the{' '}
+
+ .env.example
+ {' '}
+ file in your Next.js app to{' '}
+
+ .env.local
+ {' '}
+ and populate with values from{' '}
+
+ your Supabase project's API Settings
+
+ .
+
+
+
+
+
+ You may need to quit your Next.js development server and run{' '}
+
+ npm run dev
+ {' '}
+ again to load the new environment variables.
+
+
+
+
+ You may need to refresh the page for Next.js to load the new environment variables.
+
+
+ )
+}
diff --git a/apps/database-new/components/DeployButton.tsx b/apps/database-new/components/DeployButton.tsx
new file mode 100644
index 00000000000..3ed637059b4
--- /dev/null
+++ b/apps/database-new/components/DeployButton.tsx
@@ -0,0 +1,15 @@
+export default function DeployButton() {
+ return (
+
+
+
+
+ Deploy to Vercel
+
+ )
+}
diff --git a/apps/database-new/components/Header.tsx b/apps/database-new/components/Header.tsx
new file mode 100644
index 00000000000..50e63d53e48
--- /dev/null
+++ b/apps/database-new/components/Header.tsx
@@ -0,0 +1,44 @@
+import NextLogo from './NextLogo'
+import SupabaseLogo from './SupabaseLogo'
+
+export default function Header() {
+ return (
+
+
+
Supabase and Next.js Starter Template
+
+ The fastest way to build apps with{' '}
+
+ Supabase
+ {' '}
+ and{' '}
+
+ Next.js
+
+
+
+
+ )
+}
diff --git a/apps/database-new/components/NextLogo.tsx b/apps/database-new/components/NextLogo.tsx
new file mode 100644
index 00000000000..9e9c92f49ae
--- /dev/null
+++ b/apps/database-new/components/NextLogo.tsx
@@ -0,0 +1,40 @@
+export default function NextLogo() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/database-new/components/SignUpUserSteps.tsx b/apps/database-new/components/SignUpUserSteps.tsx
new file mode 100644
index 00000000000..c5c28d14b2d
--- /dev/null
+++ b/apps/database-new/components/SignUpUserSteps.tsx
@@ -0,0 +1,112 @@
+import Link from 'next/link'
+import Step from './Step'
+import Code from '@/components/Code'
+
+const create = `
+create table notes (
+ id serial primary key,
+ title text
+);
+
+insert into notes(title)
+values
+ ('Today I created a Supabase project.'),
+ ('I added some data and queried it from Next.js.'),
+ ('It was awesome!');
+`.trim()
+
+const server = `
+import { createClient } from '@/utils/supabase/server'
+import { cookies } from 'next/headers'
+
+export default async function Page() {
+ const cookieStore = cookies()
+ const supabase = createClient(cookieStore)
+ const { data: notes } = await supabase.from('notes').select()
+
+ return {JSON.stringify(notes, null, 2)}
+}
+`.trim()
+
+const client = `
+'use client'
+
+import { createClient } from '@/utils/supabase/client'
+import { useEffect, useState } from 'react'
+
+export default function Page() {
+ const [notes, setNotes] = useState(null)
+ const supabase = createClient()
+
+ useEffect(() => {
+ const getData = async () => {
+ const { data } = await supabase.from('notes').select()
+ setNotes(data)
+ }
+ getData()
+ }, [])
+
+ return {JSON.stringify(notes, null, 2)}
+}
+`.trim()
+
+export default function SignUpUserSteps() {
+ return (
+
+
+
+ Head over to the{' '}
+
+ Login
+ {' '}
+ page and sign up your first user. It's okay if this is just you for now. Your awesome idea
+ will have plenty of users later!
+
+
+
+
+
+ Head over to the{' '}
+
+ Table Editor
+ {' '}
+ for your Supabase project to create a table and insert some example data. If you're stuck
+ for creativity, you can copy and paste the following into the{' '}
+
+ SQL Editor
+ {' '}
+ and click RUN!
+
+
+
+
+
+
+ To create a Supabase client and query data from an Async Server Component, create a new
+ page.tsx file at{' '}
+
+ /app/notes/page.tsx
+ {' '}
+ and add the following.
+
+
+ Alternatively, you can use a Client Component.
+
+
+
+
+ You're ready to launch your product to the world! 🚀
+
+
+ )
+}
diff --git a/apps/database-new/components/Step.tsx b/apps/database-new/components/Step.tsx
new file mode 100644
index 00000000000..6702a02964b
--- /dev/null
+++ b/apps/database-new/components/Step.tsx
@@ -0,0 +1,14 @@
+export default function Step({ title, children }: { title: string; children: React.ReactNode }) {
+ return (
+
+
+
+ {title}
+
+ {children}
+
+ )
+}
diff --git a/apps/database-new/components/SupabaseLogo.tsx b/apps/database-new/components/SupabaseLogo.tsx
new file mode 100644
index 00000000000..7d7dbe8207f
--- /dev/null
+++ b/apps/database-new/components/SupabaseLogo.tsx
@@ -0,0 +1,102 @@
+export default function SupabaseLogo() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/apps/database-new/middleware.ts b/apps/database-new/middleware.ts
new file mode 100644
index 00000000000..25571510874
--- /dev/null
+++ b/apps/database-new/middleware.ts
@@ -0,0 +1,25 @@
+import { NextResponse, type NextRequest } from 'next/server'
+import { createClient } from '@/utils/supabase/middleware'
+
+export async function middleware(request: NextRequest) {
+ try {
+ // This `try/catch` block is only here for the interactive tutorial.
+ // Feel free to remove once you have Supabase connected.
+ const { supabase, response } = createClient(request)
+
+ // Refresh session if expired - required for Server Components
+ // https://supabase.com/docs/guides/auth/auth-helpers/nextjs#managing-session-with-middleware
+ await supabase.auth.getSession()
+
+ return response
+ } catch (e) {
+ // If you are here, a Supabase client could not be created!
+ // This is likely because you have not set up environment variables.
+ // Check out http://localhost:3000 for Next Steps.
+ return NextResponse.next({
+ request: {
+ headers: request.headers,
+ },
+ })
+ }
+}
diff --git a/apps/database-new/next.config.js b/apps/database-new/next.config.js
new file mode 100644
index 00000000000..950e2f42ec3
--- /dev/null
+++ b/apps/database-new/next.config.js
@@ -0,0 +1,8 @@
+/** @type {import('next').NextConfig} */
+const nextConfig = {
+ experimental: {
+ serverActions: true,
+ },
+}
+
+module.exports = nextConfig
diff --git a/apps/database-new/package.json b/apps/database-new/package.json
new file mode 100644
index 00000000000..abd2e60f222
--- /dev/null
+++ b/apps/database-new/package.json
@@ -0,0 +1,25 @@
+{
+ "private": true,
+ "scripts": {
+ "dev": "next dev --port 3002",
+ "build": "next build",
+ "start": "next start"
+ },
+ "dependencies": {
+ "@supabase/ssr": "latest",
+ "@supabase/supabase-js": "latest",
+ "autoprefixer": "10.4.15",
+ "geist": "^1.0.0",
+ "next": "^13.5.3",
+ "postcss": "8.4.29",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "tailwindcss": "3.3.3",
+ "typescript": "^5.2.2"
+ },
+ "devDependencies": {
+ "@types/node": "^18.11.9",
+ "@types/react": "^18.2.24",
+ "encoding": "^0.1.13"
+ }
+}
diff --git a/apps/database-new/postcss.config.js b/apps/database-new/postcss.config.js
new file mode 100644
index 00000000000..33ad091d26d
--- /dev/null
+++ b/apps/database-new/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
diff --git a/apps/database-new/tailwind.config.js b/apps/database-new/tailwind.config.js
new file mode 100644
index 00000000000..bd94e9ca9bc
--- /dev/null
+++ b/apps/database-new/tailwind.config.js
@@ -0,0 +1,17 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+ content: ['./app/**/*.{js,ts,jsx,tsx,mdx}', './components/**/*.{js,ts,jsx,tsx,mdx}'],
+ theme: {
+ extend: {
+ colors: {
+ background: 'hsl(var(--background))',
+ foreground: 'hsl(var(--foreground))',
+ btn: {
+ background: 'hsl(var(--btn-background))',
+ 'background-hover': 'hsl(var(--btn-background-hover))',
+ },
+ },
+ },
+ },
+ plugins: [],
+}
diff --git a/apps/database-new/tsconfig.json b/apps/database-new/tsconfig.json
new file mode 100644
index 00000000000..e06a4454ab0
--- /dev/null
+++ b/apps/database-new/tsconfig.json
@@ -0,0 +1,28 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ],
+ "paths": {
+ "@/*": ["./*"]
+ }
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
+ "exclude": ["node_modules"]
+}
diff --git a/apps/database-new/utils/supabase/client.ts b/apps/database-new/utils/supabase/client.ts
new file mode 100644
index 00000000000..5456942560c
--- /dev/null
+++ b/apps/database-new/utils/supabase/client.ts
@@ -0,0 +1,7 @@
+import { createBrowserClient } from '@supabase/ssr'
+
+export const createClient = () =>
+ createBrowserClient(
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
+ )
diff --git a/apps/database-new/utils/supabase/middleware.ts b/apps/database-new/utils/supabase/middleware.ts
new file mode 100644
index 00000000000..3365525ed6d
--- /dev/null
+++ b/apps/database-new/utils/supabase/middleware.ts
@@ -0,0 +1,61 @@
+import { createServerClient, type CookieOptions } from '@supabase/ssr'
+import { type NextRequest, NextResponse } from 'next/server'
+
+export const createClient = (request: NextRequest) => {
+ // Create an unmodified response
+ let response = NextResponse.next({
+ request: {
+ headers: request.headers,
+ },
+ })
+
+ const supabase = createServerClient(
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
+ {
+ cookies: {
+ get(name: string) {
+ return request.cookies.get(name)?.value
+ },
+ set(name: string, value: string, options: CookieOptions) {
+ // If the cookie is updated, update the cookies for the request and response
+ request.cookies.set({
+ name,
+ value,
+ ...options,
+ })
+ response = NextResponse.next({
+ request: {
+ headers: request.headers,
+ },
+ })
+ response.cookies.set({
+ name,
+ value,
+ ...options,
+ })
+ },
+ remove(name: string, options: CookieOptions) {
+ // If the cookie is removed, update the cookies for the request and response
+ request.cookies.set({
+ name,
+ value: '',
+ ...options,
+ })
+ response = NextResponse.next({
+ request: {
+ headers: request.headers,
+ },
+ })
+ response.cookies.set({
+ name,
+ value: '',
+ ...options,
+ })
+ },
+ },
+ }
+ )
+
+ return { supabase, response }
+}
diff --git a/apps/database-new/utils/supabase/server.ts b/apps/database-new/utils/supabase/server.ts
new file mode 100644
index 00000000000..0edfaa0df8d
--- /dev/null
+++ b/apps/database-new/utils/supabase/server.ts
@@ -0,0 +1,34 @@
+import { createServerClient, type CookieOptions } from '@supabase/ssr'
+import { cookies } from 'next/headers'
+
+export const createClient = (cookieStore: ReturnType) => {
+ return createServerClient(
+ process.env.NEXT_PUBLIC_SUPABASE_URL!,
+ process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
+ {
+ cookies: {
+ get(name: string) {
+ return cookieStore.get(name)?.value
+ },
+ set(name: string, value: string, options: CookieOptions) {
+ try {
+ cookieStore.set({ name, value, ...options })
+ } catch (error) {
+ // The `set` method was called from a Server Component.
+ // This can be ignored if you have middleware refreshing
+ // user sessions.
+ }
+ },
+ remove(name: string, options: CookieOptions) {
+ try {
+ cookieStore.set({ name, value: '', ...options })
+ } catch (error) {
+ // The `delete` method was called from a Server Component.
+ // This can be ignored if you have middleware refreshing
+ // user sessions.
+ }
+ },
+ },
+ }
+ )
+}
diff --git a/package-lock.json b/package-lock.json
index ddef18ad0de..e66da846f44 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -27,6 +27,97 @@
"npm": ">=9.0.0 <10.0.0"
}
},
+ "apps/database-new": {
+ "dependencies": {
+ "@supabase/ssr": "latest",
+ "@supabase/supabase-js": "latest",
+ "autoprefixer": "10.4.15",
+ "geist": "^1.0.0",
+ "next": "^13.5.3",
+ "postcss": "8.4.29",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "tailwindcss": "3.3.3",
+ "typescript": "^5.2.2"
+ },
+ "devDependencies": {
+ "@types/node": "^18.11.9",
+ "@types/react": "^18.2.24",
+ "encoding": "^0.1.13"
+ }
+ },
+ "apps/database-new/node_modules/@types/node": {
+ "version": "18.18.9",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.9.tgz",
+ "integrity": "sha512-0f5klcuImLnG4Qreu9hPj/rEfFq6YRc5n2mAjSsH+ec/mJL+3voBH0+8T7o8RpFjH7ovc+TRsL/c7OYIQsPTfQ==",
+ "dev": true,
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
+ },
+ "apps/database-new/node_modules/autoprefixer": {
+ "version": "10.4.15",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.15.tgz",
+ "integrity": "sha512-KCuPB8ZCIqFdA4HwKXsvz7j6gvSDNhDP7WnUjBleRkKjPdvCmHFuQ77ocavI8FT6NdvlBnE2UFr2H4Mycn8Vew==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "browserslist": "^4.21.10",
+ "caniuse-lite": "^1.0.30001520",
+ "fraction.js": "^4.2.0",
+ "normalize-range": "^0.1.2",
+ "picocolors": "^1.0.0",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
+ "apps/database-new/node_modules/postcss": {
+ "version": "8.4.29",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz",
+ "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.6",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
"apps/docs": {
"version": "0.0.0",
"dependencies": {
@@ -10259,6 +10350,18 @@
"resolved": "https://registry.npmjs.org/@supabase/shared-types/-/shared-types-0.1.51.tgz",
"integrity": "sha512-ZCm3sdxFwFDIOakciAH+or1gWQ6SKqiSWmmejsUCyH5QfMl4ngFc6hZcNEky5+NJ5wI7YtukUpvKihNVR0iNSg=="
},
+ "node_modules/@supabase/ssr": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.0.10.tgz",
+ "integrity": "sha512-eVs7+bNlff8Fd79x8K3Jbfpmf8P8QRA1Z6rUDN+fi4ReWvRBZyWOFfR6eqlsX6vTjvGgTiEqujFSkv2PYW5kbQ==",
+ "dependencies": {
+ "cookie": "^0.5.0",
+ "ramda": "^0.29.0"
+ },
+ "peerDependencies": {
+ "@supabase/supabase-js": "^2.33.1"
+ }
+ },
"node_modules/@supabase/storage-js": {
"version": "2.5.4",
"resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.5.4.tgz",
@@ -11590,9 +11693,9 @@
"dev": true
},
"node_modules/@types/react": {
- "version": "18.2.24",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.24.tgz",
- "integrity": "sha512-Ee0Jt4sbJxMu1iDcetZEIKQr99J1Zfb6D4F3qfUWoR1JpInkY1Wdg4WwCyBjL257D0+jGqSl1twBjV8iCaC0Aw==",
+ "version": "18.2.37",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.37.tgz",
+ "integrity": "sha512-RGAYMi2bhRgEXT3f4B92WTohopH6bIXw05FuGlmJEnv/omEn190+QYEIYxIAuIBdKgboYYdVved2p1AxZVQnaw==",
"dependencies": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@@ -15234,7 +15337,6 @@
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
"integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
- "dev": true,
"engines": {
"node": ">= 0.6"
}
@@ -16345,6 +16447,10 @@
"node": ">=12"
}
},
+ "node_modules/database-new": {
+ "resolved": "apps/database-new",
+ "link": true
+ },
"node_modules/date-fns": {
"version": "2.30.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
@@ -17097,7 +17203,7 @@
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
- "optional": true,
+ "devOptional": true,
"dependencies": {
"iconv-lite": "^0.6.2"
}
@@ -19321,6 +19427,14 @@
"node": ">=8"
}
},
+ "node_modules/geist": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/geist/-/geist-1.1.0.tgz",
+ "integrity": "sha512-UwZH+ekwAt1T5XYlviFD+jUXFeRRawDDT8RtpJ//IHTPXlVIO6BCcZ8M0Pxg1K/FT3H8HLn3KJqMsPLHbo1HNg==",
+ "peerDependencies": {
+ "next": "^13.2 || ^14"
+ }
+ },
"node_modules/generate-password": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/generate-password/-/generate-password-1.7.0.tgz",
@@ -31316,7 +31430,6 @@
"version": "0.29.0",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.29.0.tgz",
"integrity": "sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==",
- "dev": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/ramda"