diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
index c5f57524b8f..6a210a4cf67 100644
--- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
+++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
@@ -469,6 +469,7 @@ export const platform = {
items: [
{ name: 'Compute Add-ons', url: '/guides/platform/compute-add-ons', items: [] },
{ name: 'Custom Domains', url: '/guides/platform/custom-domains', items: [] },
+ { name: 'Database Backups', url: '/guides/platform/backups', items: [] },
],
},
{
diff --git a/apps/docs/components/index.tsx b/apps/docs/components/index.tsx
index 4351050cbf0..c5a5aa3752a 100644
--- a/apps/docs/components/index.tsx
+++ b/apps/docs/components/index.tsx
@@ -27,6 +27,9 @@ import RefHeaderSection from './reference/RefHeaderSection'
// Ref version specific
import CliGlobalFlagsHandler from '~/components/reference/enrichments/cli/CliGlobalFlagsHandler'
+import Options from '~/components/Options'
+import Param from '~/components/Params'
+
const components = {
Admonition,
Button,
@@ -68,6 +71,8 @@ const components = {
code: (props: any) => ,
RefHeaderSection: (props: any) => ,
CliGlobalFlagsHandler: () => ,
+ Options,
+ Param,
}
export default components
diff --git a/apps/docs/data/authProviders.ts b/apps/docs/data/authProviders.ts
index f9a32a71454..95c2f6b2dbf 100644
--- a/apps/docs/data/authProviders.ts
+++ b/apps/docs/data/authProviders.ts
@@ -1,26 +1,8 @@
const authProviders = [
- // {
- // name: 'Email',
- // // logo: '/img/libraries/dart-icon.svg',
- // href: '/docs/guides/auth/auth-apple',
- // official: true,
- // supporter: 'Supabase',
- // platform: true,
- // selfHosted: true,
- // },
- // {
- // name: 'Magic Links',
- // // logo: '/img/libraries/dart-icon.svg',
- // href: '/docs/guides/auth/auth-apple',
- // official: true,
- // supporter: 'Supabase',
- // platform: true,
- // selfHosted: true,
- // },
{
name: 'Apple',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-apple',
+ href: '/guides/auth/social-login/auth-apple',
official: true,
supporter: 'Supabase',
platform: true,
@@ -29,7 +11,7 @@ const authProviders = [
{
name: 'Azure',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-azure',
+ href: '/guides/auth/social-login/auth-azure',
official: false,
supporter: 'TBD',
platform: true,
@@ -38,7 +20,7 @@ const authProviders = [
{
name: 'Bitbucket',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-bitbucket',
+ href: '/guides/auth/social-login/auth-bitbucket',
official: true,
supporter: 'Supabase',
platform: true,
@@ -47,7 +29,7 @@ const authProviders = [
{
name: 'Discord',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-discord',
+ href: '/guides/auth/social-login/auth-discord',
official: true,
supporter: 'Supabase',
platform: true,
@@ -56,7 +38,7 @@ const authProviders = [
{
name: 'Facebook',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-facebook',
+ href: '/guides/auth/social-login/auth-facebook',
official: true,
supporter: 'Supabase',
platform: true,
@@ -65,7 +47,7 @@ const authProviders = [
{
name: 'GitHub',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-github',
+ href: '/guides/auth/social-login/auth-github',
official: true,
supporter: 'Supabase',
platform: true,
@@ -74,7 +56,7 @@ const authProviders = [
{
name: 'GitLab',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-gitlab',
+ href: '/guides/auth/social-login/auth-gitlab',
official: true,
supporter: 'Supabase',
platform: true,
@@ -83,7 +65,7 @@ const authProviders = [
{
name: 'Google',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-google',
+ href: '/guides/auth/social-login/auth-google',
official: true,
supporter: 'Supabase',
platform: true,
@@ -91,7 +73,7 @@ const authProviders = [
},
{
name: 'Keycloak',
- href: '/guides/auth/auth-keycloak',
+ href: '/guides/auth/social-login/auth-keycloak',
official: true,
supporter: 'Supabase',
platform: true,
@@ -100,7 +82,7 @@ const authProviders = [
{
name: 'LinkedIn',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-linkedin',
+ href: '/guides/auth/social-login/auth-linkedin',
official: true,
supporter: 'Supabase',
platform: true,
@@ -109,7 +91,7 @@ const authProviders = [
{
name: 'MessageBird',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-messagebird',
+ href: '/guides/auth/phone-login/messagebird',
official: false,
supporter: 'MessageBird',
platform: true,
@@ -118,7 +100,7 @@ const authProviders = [
{
name: 'Notion',
// logo: '/img/libraries/notion-icon.svg',
- href: '/guides/auth/auth-notion',
+ href: '/guides/auth/social-login/auth-notion',
official: true,
supporter: 'Supabase',
platform: true,
@@ -127,7 +109,7 @@ const authProviders = [
{
name: 'Slack',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-slack',
+ href: '/guides/auth/social-login/auth-slack',
official: true,
supporter: 'Supabase',
platform: true,
@@ -136,7 +118,7 @@ const authProviders = [
{
name: 'Spotify',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-spotify',
+ href: '/guides/auth/social-login/auth-spotify',
official: true,
supporter: 'Supabase',
platform: true,
@@ -145,7 +127,7 @@ const authProviders = [
{
name: 'Twitter',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-twitter',
+ href: '/guides/auth/social-login/auth-twitter',
official: true,
supporter: 'Supabase',
platform: true,
@@ -154,7 +136,7 @@ const authProviders = [
{
name: 'Twitch',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-twitch',
+ href: '/guides/auth/social-login/auth-twitch',
official: true,
supporter: 'Supabase',
platform: true,
@@ -163,7 +145,7 @@ const authProviders = [
{
name: 'Zoom',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-zoom',
+ href: '/guides/auth/social-login/auth-zoom',
official: true,
supporter: 'Supabase',
platform: true,
@@ -172,7 +154,7 @@ const authProviders = [
{
name: 'Twilio',
// logo: '/img/libraries/dart-icon.svg',
- href: '/guides/auth/auth-twilio',
+ href: '/guides/auth/phone-login/twilio',
official: true,
supporter: 'Supabase',
platform: true,
@@ -180,7 +162,7 @@ const authProviders = [
},
{
name: 'Vonage',
- href: '/guides/auth/auth-vonage',
+ href: '/guides/auth/phone-login/vonage',
official: false,
supporter: 'Supabase',
platform: true,
diff --git a/apps/docs/lib/refGenerator/helpers.ts b/apps/docs/lib/refGenerator/helpers.ts
index 77a7aa16755..6af5b8eb539 100644
--- a/apps/docs/lib/refGenerator/helpers.ts
+++ b/apps/docs/lib/refGenerator/helpers.ts
@@ -60,6 +60,8 @@ function recurseThroughParams(paramDefinition: any) {
children = dereferenced.children
} else if (dereferenced.type?.declaration?.children) {
children = dereferenced.type.declaration.children
+ } else if (dereferenced.type?.type === 'query') {
+ // skip: ignore types created from `typeof` for now, like `type Fetch = typeof fetch`
} else if (dereferenced.type?.type === 'union') {
// skip: we don't want to show unions as nested parameters
} else if (Object.keys(dereferenced).length === 0) {
diff --git a/apps/docs/pages/guides/auth/auth-helpers/nextjs-server-components.mdx b/apps/docs/pages/guides/auth/auth-helpers/nextjs-server-components.mdx
index 346c8d7f3bc..10fa7f73f31 100644
--- a/apps/docs/pages/guides/auth/auth-helpers/nextjs-server-components.mdx
+++ b/apps/docs/pages/guides/auth/auth-helpers/nextjs-server-components.mdx
@@ -95,7 +95,7 @@ Create a new file at `/utils/supabase-browser.ts` and populate with the followin
```ts
import { createBrowserSupabaseClient } from '@supabase/auth-helpers-nextjs'
-import { Database } from '../db_types'
+import { Database } from '../lib/database.types'
export default createBrowserSupabaseClient()
```
@@ -109,7 +109,7 @@ Create a new file at `/utils/supabase-server.ts` and populate with the following
```ts title="/utils/supabase-server.ts"
import { headers, cookies } from 'next/headers'
import { createServerComponentSupabaseClient } from '@supabase/auth-helpers-nextjs'
-import { Database } from '../db_types'
+import { Database } from '../lib/database.types'
export default () =>
createServerComponentSupabaseClient({
@@ -139,6 +139,8 @@ Middleware runs before every route declared in the `matcher` array. Since we don
>
+Create a new file at `/pages/middleware.js` and populate with the following:
+
```jsx title="middleware.js"
import { createMiddlewareSupabaseClient } from '@supabase/auth-helpers-nextjs'
import { NextResponse } from 'next/server'
@@ -164,6 +166,8 @@ export const config = {
+Create a new file at `/middleware.ts` (a sibling of /pages) and populate with the following:
+
```tsx title="middleware.ts"
import { createMiddlewareSupabaseClient } from '@supabase/auth-helpers-nextjs'
import { NextResponse } from 'next/server'
@@ -254,7 +258,7 @@ export default async function RootLayout({ children }) {
}
```
-We don't want Next.js to cache this `session` value, so we need to export a `revalidate` value of `0`.
+We don't want Next.js to cache this `session` value, so we need to export a `revalidate` value of `0` in the layout file.
```jsx
export const revalidate = 0
@@ -641,7 +645,7 @@ Create a new file at `/app/realtime/posts.tsx` and populate with the following:
'use client'
import { useEffect, useState } from 'react'
-import { Database } from '../../db_types'
+import { Database } from '../lib/database.types'
import supabase from '../../utils/supabase-browser'
type Post = Database['public']['Tables']['posts']['Row']
diff --git a/apps/docs/pages/guides/database/extensions/uuid-ossp.mdx b/apps/docs/pages/guides/database/extensions/uuid-ossp.mdx
index 2731ae221a2..167e9b92807 100644
--- a/apps/docs/pages/guides/database/extensions/uuid-ossp.mdx
+++ b/apps/docs/pages/guides/database/extensions/uuid-ossp.mdx
@@ -10,8 +10,8 @@ The `uuid-ossp` extension can be used to generate a `UUID`.
## Overview
-A `UUID` is a "Universally Unique Identifer" and it is, for practical purposes, unique.
-This makes them particularly well suited as Primary Keys. It is occasionally referred to as a `GUID`, which stands for "Globally Unique Identifer".
+A `UUID` is a "Universally Unique Identifier" and it is, for practical purposes, unique.
+This makes them particularly well suited as Primary Keys. It is occasionally referred to as a `GUID`, which stands for "Globally Unique Identifier".
## Usage
diff --git a/apps/docs/pages/guides/database/tables.mdx b/apps/docs/pages/guides/database/tables.mdx
index 010b104a2a4..78d1b62115a 100644
--- a/apps/docs/pages/guides/database/tables.mdx
+++ b/apps/docs/pages/guides/database/tables.mdx
@@ -265,7 +265,7 @@ For example if you had the following situations:
- You have a list of `movies`.
- A movie can have several `actors`.
-- An `actor` can perfom in several movies.
+- An `actor` can perform in several movies.
+
{webapps.map((item) => {
return (
@@ -150,13 +150,13 @@ export const resources = [
{
title: 'Features',
hasLightIcon: true,
- href: '/features',
+ href: '/guides/getting-started/features',
description: 'A non-exhaustive list of features that Supabase provides for every project.',
},
{
title: 'Architecture',
hasLightIcon: true,
- href: '/architecture',
+ href: '/guides/getting-started/architecture',
description: "An overview of Supabase's architecture and product principles.",
},
]
diff --git a/apps/docs/pages/guides/getting-started/features.mdx b/apps/docs/pages/guides/getting-started/features.mdx
index 4b10f3830ba..c1e1a0dcfc9 100755
--- a/apps/docs/pages/guides/getting-started/features.mdx
+++ b/apps/docs/pages/guides/getting-started/features.mdx
@@ -60,11 +60,11 @@ Build passwordless logins for your application or website.[Docs](/docs/guides/au
### Social Logins
-Provide social logins - everything from Apple, to GitHub, to Slack. [Docs](/docs/guides/auth/auth-apple).
+Provide social logins - everything from Apple, to GitHub, to Slack. [Docs](/docs/guides/auth/social-login).
### Phone Logins
-Provide phone logins using a 3rd-party SMS provider. [Docs](/docs/guides/auth/auth-twilio).
+Provide phone logins using a third-party SMS provider. [Docs](/docs/guides/auth/phone-login).
### Row Level Security
diff --git a/apps/docs/pages/guides/getting-started/tutorials/with-angular.mdx b/apps/docs/pages/guides/getting-started/tutorials/with-angular.mdx
index b0d5fc21c93..8f2754453f9 100644
--- a/apps/docs/pages/guides/getting-started/tutorials/with-angular.mdx
+++ b/apps/docs/pages/guides/getting-started/tutorials/with-angular.mdx
@@ -205,7 +205,7 @@ export class AuthComponent implements OnInit {
-
```
### Account page
diff --git a/apps/docs/pages/guides/getting-started/tutorials/with-flutter.mdx b/apps/docs/pages/guides/getting-started/tutorials/with-flutter.mdx
index db3e028ad30..6a73c7aa8ab 100644
--- a/apps/docs/pages/guides/getting-started/tutorials/with-flutter.mdx
+++ b/apps/docs/pages/guides/getting-started/tutorials/with-flutter.mdx
@@ -50,7 +50,9 @@ Add `io.supabase.flutterquickstart://login-callback/` as a new [redirect URL](ht
That is it on Supabase's end and the rest are platform specific settings:
-For Android, add an intent-filter to enable deep linking:
+For Android, edit the `android/app/src/main/AndroidManifest.xml` file.
+
+Add an intent-filter to enable deep linking:
```xml title=android/app/src/main/AndroidManifest.xml
@@ -75,7 +77,9 @@ For Android, add an intent-filter to enable deep linking:
```
-For iOS add CFBundleURLTypes to enable deep linking:
+For iOS, edit the ios/Runner/Info.plist file.
+
+Add CFBundleURLTypes to enable deep linking:
```xml title=ios/Runner/Info.plist"
diff --git a/apps/docs/pages/guides/getting-started/tutorials/with-react.mdx b/apps/docs/pages/guides/getting-started/tutorials/with-react.mdx
index 1f7804f15ab..7d1418b7146 100644
--- a/apps/docs/pages/guides/getting-started/tutorials/with-react.mdx
+++ b/apps/docs/pages/guides/getting-started/tutorials/with-react.mdx
@@ -37,7 +37,7 @@ Then let's install the only additional dependency: [supabase-js](https://github.
npm install @supabase/supabase-js
```
-And finally we want to save the environment variables in a `.env`.
+And finally we want to save the environment variables in a `.env.local` file.
All we need are the API URL and the `anon` key that you copied [earlier](#get-the-api-keys).
```bash title=.env
@@ -48,6 +48,8 @@ REACT_APP_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY
Now that we have the API credentials in place, let's create a helper file to initialize the Supabase client. These variables will be exposed
on the browser, and that's completely fine since we have [Row Level Security](/docs/guides/auth#row-level-security) enabled on our Database.
+Create and edit `src/supabaseClient.js`:
+
```js title=src/supabaseClient.js
import { createClient } from '@supabase/supabase-js'
@@ -64,6 +66,8 @@ You can find the full contents of this file [here](https://raw.githubusercontent
Let's set up a React component to manage logins and sign ups. We'll use Magic Links, so users can sign in with their email without using passwords.
+Create and edit `src/Auth.js`:
+
```jsx title=src/Auth.js
import { useState } from 'react'
import { supabase } from './supabaseClient'
@@ -120,7 +124,7 @@ export default function Auth() {
After a user is signed in we can allow them to edit their profile details and manage their account.
-Let's create a new component for that called `Account.js`.
+Let's create a new component for that called `src/Account.js`.
```jsx title=src/Account.js
import { useState, useEffect } from 'react'
@@ -234,7 +238,7 @@ export default Account
### Launch!
-Now that we have all the components in place, let's update `App.js`:
+Now that we have all the components in place, let's update `src/App.js`:
```jsx title=src/App.js
import './index.css'
@@ -282,6 +286,8 @@ Every Supabase project is configured with [Storage](/docs/guides/storage) for ma
Let's create an avatar for the user so that they can upload a profile photo. We can start by creating a new component:
+Create and edit `src/Avatar.js`:
+
```jsx title=src/Avatar.js
import { useEffect, useState } from 'react'
import { supabase } from './supabaseClient'
@@ -367,7 +373,7 @@ export default function Avatar({ url, size, onUpload }) {
### Add the new widget
-And then we can add the widget to the Account page:
+And then we can add the widget to the Account page at `src/Account.js`:
```jsx title=src/Account.js
// Import the new component
@@ -376,7 +382,7 @@ import Avatar from './Avatar'
// ...
return (
-
+
@@ -861,7 +791,7 @@ ion-content {
--padding-start: 5%;
--padding-end: 5%;
--background: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0.7)),
- url("https://images.unsplash.com/photo-1508964942454-1a56651d54ac?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1035&q=80")
+ url('https://images.unsplash.com/photo-1508964942454-1a56651d54ac?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1035&q=80')
no-repeat;
}
```
@@ -894,49 +824,46 @@ Go ahead now and start the **src/app/services/data.service.ts** like this:
```ts
/* eslint-disable @typescript-eslint/naming-convention */
-import { Injectable } from "@angular/core";
-import { SupabaseClient, createClient } from "@supabase/supabase-js";
-import { Subject } from "rxjs";
-import { environment } from "src/environments/environment";
+import { Injectable } from '@angular/core'
+import { SupabaseClient, createClient } from '@supabase/supabase-js'
+import { Subject } from 'rxjs'
+import { environment } from 'src/environments/environment'
-const GROUPS_DB = "groups";
-const MESSAGES_DB = "messages";
+const GROUPS_DB = 'groups'
+const MESSAGES_DB = 'messages'
export interface Message {
- created_at: string;
- group_id: number;
- id: number;
- text: string;
- user_id: string;
+ created_at: string
+ group_id: number
+ id: number
+ text: string
+ user_id: string
}
@Injectable({
- providedIn: "root",
+ providedIn: 'root',
})
export class DataService {
- private supabase: SupabaseClient;
+ private supabase: SupabaseClient
constructor() {
- this.supabase = createClient(
- environment.supabaseUrl,
- environment.supabaseKey
- );
+ this.supabase = createClient(environment.supabaseUrl, environment.supabaseKey)
}
getGroups() {
return this.supabase
.from(GROUPS_DB)
.select(`title,id, users:creator ( email )`)
- .then((result) => result.data);
+ .then((result) => result.data)
}
async createGroup(title) {
const newgroup = {
creator: (await this.supabase.auth.getUser()).data.user.id,
title,
- };
+ }
- return this.supabase.from(GROUPS_DB).insert(newgroup).select().single();
+ return this.supabase.from(GROUPS_DB).insert(newgroup).select().single()
}
}
```
@@ -956,24 +883,20 @@ This will then bring a user to the messages page since we defined the route "/gr
Now go ahead and bring up the **src/app/pages/groups/groups.page.ts** and change it to:
```ts
-import { Router } from "@angular/router";
-import { AuthService } from "./../../services/auth.service";
-import {
- AlertController,
- NavController,
- LoadingController,
-} from "@ionic/angular";
-import { DataService } from "./../../services/data.service";
-import { Component, OnInit } from "@angular/core";
+import { Router } from '@angular/router'
+import { AuthService } from './../../services/auth.service'
+import { AlertController, NavController, LoadingController } from '@ionic/angular'
+import { DataService } from './../../services/data.service'
+import { Component, OnInit } from '@angular/core'
@Component({
- selector: "app-groups",
- templateUrl: "./groups.page.html",
- styleUrls: ["./groups.page.scss"],
+ selector: 'app-groups',
+ templateUrl: './groups.page.html',
+ styleUrls: ['./groups.page.scss'],
})
export class GroupsPage implements OnInit {
- user = this.authService.getCurrentUser();
- groups = [];
+ user = this.authService.getCurrentUser()
+ groups = []
constructor(
private authService: AuthService,
@@ -987,53 +910,52 @@ export class GroupsPage implements OnInit {
ngOnInit() {}
async ionViewWillEnter() {
- this.groups = await this.data.getGroups();
+ this.groups = await this.data.getGroups()
}
async createGroup() {
const alert = await this.alertController.create({
- header: "Start Chat Group",
- message:
- "Enter a name for your group. Note that all groups are public in this app!",
+ header: 'Start Chat Group',
+ message: 'Enter a name for your group. Note that all groups are public in this app!',
inputs: [
{
- type: "text",
- name: "title",
- placeholder: "My cool group",
+ type: 'text',
+ name: 'title',
+ placeholder: 'My cool group',
},
],
buttons: [
{
- text: "Cancel",
- role: "cancel",
+ text: 'Cancel',
+ role: 'cancel',
},
{
- text: "Create group",
+ text: 'Create group',
handler: async (data) => {
- const loading = await this.loadingController.create();
- await loading.present();
+ const loading = await this.loadingController.create()
+ await loading.present()
- const newGroup = await this.data.createGroup(data.title);
+ const newGroup = await this.data.createGroup(data.title)
if (newGroup) {
- this.groups = await this.data.getGroups();
- await loading.dismiss();
+ this.groups = await this.data.getGroups()
+ await loading.dismiss()
- this.router.navigateByUrl(`/groups/${newGroup.data.id}`);
+ this.router.navigateByUrl(`/groups/${newGroup.data.id}`)
}
},
},
],
- });
+ })
- await alert.present();
+ await alert.present()
}
signOut() {
- this.authService.signOut();
+ this.authService.signOut()
}
openLogin() {
- this.navController.navigateBack("/");
+ this.navController.navigateBack('/')
}
}
```
@@ -1057,9 +979,7 @@ Continue with the **src/app/pages/groups/groups.page.html** now and change it to
-
- Sign in
-
+ Sign in
@@ -1105,55 +1025,48 @@ For all of that bring up the **src/app/services/data.service.ts** and change it
```ts
/* eslint-disable @typescript-eslint/naming-convention */
-import { Injectable } from "@angular/core";
-import {
- SupabaseClient,
- createClient,
- RealtimeChannel,
-} from "@supabase/supabase-js";
-import { Subject } from "rxjs";
-import { environment } from "src/environments/environment";
+import { Injectable } from '@angular/core'
+import { SupabaseClient, createClient, RealtimeChannel } from '@supabase/supabase-js'
+import { Subject } from 'rxjs'
+import { environment } from 'src/environments/environment'
-const GROUPS_DB = "groups";
-const MESSAGES_DB = "messages";
+const GROUPS_DB = 'groups'
+const MESSAGES_DB = 'messages'
export interface Message {
- created_at: string;
- group_id: number;
- id: number;
- text: string;
- user_id: string;
+ created_at: string
+ group_id: number
+ id: number
+ text: string
+ user_id: string
}
@Injectable({
- providedIn: "root",
+ providedIn: 'root',
})
export class DataService {
- private supabase: SupabaseClient;
+ private supabase: SupabaseClient
// ADD
- private realtimeChannel: RealtimeChannel;
+ private realtimeChannel: RealtimeChannel
constructor() {
- this.supabase = createClient(
- environment.supabaseUrl,
- environment.supabaseKey
- );
+ this.supabase = createClient(environment.supabaseUrl, environment.supabaseKey)
}
getGroups() {
return this.supabase
.from(GROUPS_DB)
.select(`title,id, users:creator ( email )`)
- .then((result) => result.data);
+ .then((result) => result.data)
}
async createGroup(title) {
const newgroup = {
creator: (await this.supabase.auth.getUser()).data.user.id,
title,
- };
+ }
- return this.supabase.from(GROUPS_DB).insert(newgroup).select().single();
+ return this.supabase.from(GROUPS_DB).insert(newgroup).select().single()
}
// ADD NEW FUNCTIONS
@@ -1163,7 +1076,7 @@ export class DataService {
.select(`created_at, title, id, users:creator ( email, id )`)
.match({ id })
.single()
- .then((result) => result.data);
+ .then((result) => result.data)
}
async addGroupMessage(groupId, message) {
@@ -1171,9 +1084,9 @@ export class DataService {
text: message,
user_id: (await this.supabase.auth.getUser()).data.user.id,
group_id: groupId,
- };
+ }
- return this.supabase.from(MESSAGES_DB).insert(newMessage);
+ return this.supabase.from(MESSAGES_DB).insert(newMessage)
}
getGroupMessages(groupId) {
@@ -1182,41 +1095,41 @@ export class DataService {
.select(`created_at, text, id, users:user_id ( email, id )`)
.match({ group_id: groupId })
.limit(25) // Limit to 25 messages for our app
- .then((result) => result.data);
+ .then((result) => result.data)
}
listenToGroup(groupId) {
- const changes = new Subject();
+ const changes = new Subject()
this.realtimeChannel = this.supabase
- .channel("public:messages")
+ .channel('public:messages')
.on(
- "postgres_changes",
- { event: "*", schema: "public", table: "messages" },
+ 'postgres_changes',
+ { event: '*', schema: 'public', table: 'messages' },
async (payload) => {
- console.log("DB CHANGE: ", payload);
+ console.log('DB CHANGE: ', payload)
if (payload.new && (payload.new as Message).group_id === +groupId) {
- const msgId = (payload.new as any).id;
+ const msgId = (payload.new as any).id
const msg = await this.supabase
.from(MESSAGES_DB)
.select(`created_at, text, id, users:user_id ( email, id )`)
.match({ id: msgId })
.single()
- .then((result) => result.data);
- changes.next(msg);
+ .then((result) => result.data)
+ changes.next(msg)
}
}
)
- .subscribe();
+ .subscribe()
- return changes.asObservable();
+ return changes.asObservable()
}
unsubscribeGroupChanges() {
if (this.realtimeChannel) {
- this.supabase.removeChannel(this.realtimeChannel);
+ this.supabase.removeChannel(this.realtimeChannel)
}
}
}
@@ -1233,29 +1146,23 @@ Finally, we need to make sure we end our realtime listening when we leave the pa
Bring up the **src/app/pages/messages/messages.page.ts** and change it to:
```ts
-import { AuthService } from "./../../services/auth.service";
-import { DataService } from "./../../services/data.service";
-import {
- AfterViewInit,
- Component,
- OnDestroy,
- OnInit,
- ViewChild,
-} from "@angular/core";
-import { ActivatedRoute } from "@angular/router";
-import { IonContent } from "@ionic/angular";
+import { AuthService } from './../../services/auth.service'
+import { DataService } from './../../services/data.service'
+import { AfterViewInit, Component, OnDestroy, OnInit, ViewChild } from '@angular/core'
+import { ActivatedRoute } from '@angular/router'
+import { IonContent } from '@ionic/angular'
@Component({
- selector: "app-messages",
- templateUrl: "./messages.page.html",
- styleUrls: ["./messages.page.scss"],
+ selector: 'app-messages',
+ templateUrl: './messages.page.html',
+ styleUrls: ['./messages.page.scss'],
})
export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
- @ViewChild(IonContent) content: IonContent;
- group = null;
- messages = [];
- currentUserId = null;
- messageText = "";
+ @ViewChild(IonContent) content: IonContent
+ group = null
+ messages = []
+ currentUserId = null
+ messageText = ''
constructor(
private route: ActivatedRoute,
@@ -1264,33 +1171,33 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
) {}
async ngOnInit() {
- const groupid = this.route.snapshot.paramMap.get("groupid");
- this.group = await this.data.getGroupById(groupid);
- this.currentUserId = this.authService.getCurrentUserId();
- this.messages = await this.data.getGroupMessages(groupid);
+ const groupid = this.route.snapshot.paramMap.get('groupid')
+ this.group = await this.data.getGroupById(groupid)
+ this.currentUserId = this.authService.getCurrentUserId()
+ this.messages = await this.data.getGroupMessages(groupid)
this.data.listenToGroup(groupid).subscribe((msg) => {
- this.messages.push(msg);
+ this.messages.push(msg)
setTimeout(() => {
- this.content.scrollToBottom(200);
- }, 100);
- });
+ this.content.scrollToBottom(200)
+ }, 100)
+ })
}
ngAfterViewInit(): void {
setTimeout(() => {
- this.content.scrollToBottom(200);
- }, 300);
+ this.content.scrollToBottom(200)
+ }, 300)
}
loadMessages() {}
async sendMessage() {
- await this.data.addGroupMessage(this.group.id, this.messageText);
- this.messageText = "";
+ await this.data.addGroupMessage(this.group.id, this.messageText)
+ this.messageText = ''
}
ngOnDestroy(): void {
- this.data.unsubscribeGroupChanges();
+ this.data.unsubscribeGroupChanges()
}
}
```
@@ -1317,16 +1224,10 @@ For this, open up the **src/app/pages/messages/messages.page.html** and change i
-
+ {{ message.text }}
-
- {{ message.created_at | date:'shortTime' }}
-
+
{{ message.created_at | date:'shortTime' }}
{{ message.text }}
-
- {{ message.created_at | date:'shortTime' }}
-
+
{{ message.created_at | date:'shortTime' }}
@@ -1356,12 +1255,7 @@ For this, open up the **src/app/pages/messages/messages.page.html** and change i
-
+
@@ -1375,7 +1269,7 @@ Now we can add the finishing touches to that screen with some CSS to give the pa
```scss
ion-content {
- --background: url("../../../assets/pattern.png") no-repeat;
+ --background: url('../../../assets/pattern.png') no-repeat;
}
.message-input {
@@ -1437,20 +1331,15 @@ That guard will check the Observable of our service, filter out the initial stat
Bring up our **src/app/guards/auth.guard.ts** and change it to this:
```ts
-import { AuthService } from "./../services/auth.service";
-import { Injectable } from "@angular/core";
-import {
- ActivatedRouteSnapshot,
- CanActivate,
- Router,
- UrlTree,
-} from "@angular/router";
-import { Observable } from "rxjs";
-import { filter, map, take } from "rxjs/operators";
-import { ToastController } from "@ionic/angular";
+import { AuthService } from './../services/auth.service'
+import { Injectable } from '@angular/core'
+import { ActivatedRouteSnapshot, CanActivate, Router, UrlTree } from '@angular/router'
+import { Observable } from 'rxjs'
+import { filter, map, take } from 'rxjs/operators'
+import { ToastController } from '@ionic/angular'
@Injectable({
- providedIn: "root",
+ providedIn: 'root',
})
export class AuthGuard implements CanActivate {
constructor(
@@ -1465,19 +1354,19 @@ export class AuthGuard implements CanActivate {
take(1), // Otherwise the Observable doesn't complete!
map((isAuthenticated) => {
if (isAuthenticated) {
- return true;
+ return true
} else {
this.toastController
.create({
- message: "You are not allowed to access this!",
+ message: 'You are not allowed to access this!',
duration: 2000,
})
- .then((toast) => toast.present());
+ .then((toast) => toast.present())
- return this.router.createUrlTree(["/groups"]);
+ return this.router.createUrlTree(['/groups'])
}
})
- );
+ )
}
}
```
@@ -1577,39 +1466,35 @@ Once we got that information we can call the `setSession` function that we just
To achieve this, bring up the **src/app/app.component.ts** and change it to:
```ts
-import { AuthService } from "src/app/services/auth.service";
-import { Router } from "@angular/router";
-import { Component, NgZone } from "@angular/core";
-import { App, URLOpenListenerEvent } from "@capacitor/app";
+import { AuthService } from 'src/app/services/auth.service'
+import { Router } from '@angular/router'
+import { Component, NgZone } from '@angular/core'
+import { App, URLOpenListenerEvent } from '@capacitor/app'
@Component({
- selector: "app-root",
- templateUrl: "app.component.html",
- styleUrls: ["app.component.scss"],
+ selector: 'app-root',
+ templateUrl: 'app.component.html',
+ styleUrls: ['app.component.scss'],
})
export class AppComponent {
- constructor(
- private zone: NgZone,
- private router: Router,
- private authService: AuthService
- ) {
- this.setupListener();
+ constructor(private zone: NgZone, private router: Router, private authService: AuthService) {
+ this.setupListener()
}
setupListener() {
- App.addListener("appUrlOpen", async (data: URLOpenListenerEvent) => {
- console.log("app opened with URL: ", data);
+ App.addListener('appUrlOpen', async (data: URLOpenListenerEvent) => {
+ console.log('app opened with URL: ', data)
- const openUrl = data.url;
- const access = openUrl.split("#access_token=").pop().split("&")[0];
- const refresh = openUrl.split("&refresh_token=").pop().split("&")[0];
+ const openUrl = data.url
+ const access = openUrl.split('#access_token=').pop().split('&')[0]
+ const refresh = openUrl.split('&refresh_token=').pop().split('&')[0]
- await this.authService.setSession(access, refresh);
+ await this.authService.setSession(access, refresh)
this.zone.run(() => {
- this.router.navigateByUrl("/groups", { replaceUrl: true });
- });
- });
+ this.router.navigateByUrl('/groups', { replaceUrl: true })
+ })
+ })
}
}
```
@@ -1628,7 +1513,7 @@ We've come a long way and covered everything from setting up tables, to defining
You can [find the full code of this tutorial on Github](https://github.com/saimon24/supa-chat) where you just need to insert your own Supabase instance and then create the tables with the included SQL file, plus updating the authentication settings as we did in the tutorial
-Although we can now use magic link auth, something probably even better fitting for native apps would be [phone auth with Twilio](https://supabase.com/docs/guides/auth/auth-twilio) that's also easily possible with Supabase - just like tons of other authentication providers!
+Although we can now use magic link auth, something probably even better fitting for native apps would be [phone auth with Twilio](https://supabase.com/docs/guides/auth/phone-login/twilio) that's also easily possible with Supabase - just like tons of other authentication providers!
Protecting your Ionic Angular app with Supabase is a breeze, and through the security rules, you can make sure your data and tables are protected in the best possible way.
diff --git a/apps/www/_blog/2022-12-07-supabase-beta-november-2022.mdx b/apps/www/_blog/2022-12-07-supabase-beta-november-2022.mdx
index e60f479dff9..f06bbaea941 100644
--- a/apps/www/_blog/2022-12-07-supabase-beta-november-2022.mdx
+++ b/apps/www/_blog/2022-12-07-supabase-beta-november-2022.mdx
@@ -46,7 +46,7 @@ Plus, we published three new functions examples: [Generate OG Images](https://gi
- Conda support (`conda install -c conda-forge supabase` and everything else in py)
-## Content storm ⛈
+## Content storm

diff --git a/apps/www/_blog/2022-12-10-postgres-crdt.mdx b/apps/www/_blog/2022-12-10-postgres-crdt.mdx
index 36dd3a90cbc..066544d0003 100644
--- a/apps/www/_blog/2022-12-10-postgres-crdt.mdx
+++ b/apps/www/_blog/2022-12-10-postgres-crdt.mdx
@@ -1,47 +1,49 @@
---
title: 'pg_crdt - an experimental CRDT extension for Postgres'
-description: "Embedding Yjs and Automerge into Postgres for collaborative applications."
+description: 'Embedding Yjs and Automerge into Postgres for collaborative applications.'
author: paul_copplestone
-image: crdt/crdt-blog.png
-thumb: crdt/crdt-blog.png
+image: launch-week-6/crdt/og-pg-crdt.png
+thumb: launch-week-6/crdt/og-pg-crdt.png
tags:
- launch-week
date: '2022-12-10'
toc_depth: 2
---
-Today we’re open-sourcing an EXPERIMENTAL extension for CRDTs, `pg_crdt`. The GitHub repo is [here](https://github.com/supabase/pg_crdt). There are [instructions](https://github.com/supabase/pg_crdt#installation) for running it locally in the README.
+Today we're open-sourcing an EXPERIMENTAL extension for CRDTs, `pg_crdt`. The GitHub repo is [here](https://github.com/supabase/pg_crdt). There are [instructions](https://github.com/supabase/pg_crdt#installation) for running it locally in the README.
-When we released the new [multiplayer features](/blog/supabase-realtime-multiplayer-general-availability) for our Realtime engine,
-it took 30 minutes for someone to ask if we’d add CRDT support.
+When we released the new [multiplayer features](/blog/supabase-realtime-multiplayer-general-availability) for our Realtime engine,
+it took 30 minutes for someone to ask if we'd add CRDT support.
-> *Anyone from Supabase here, do you have any plans to build in support for CRDT toolkits such as Yjs or AutoMerge for these features? It would make working with them so much easier if there was a plug and play backend.*
+> _Anyone from Supabase here, do you have any plans to build in support for CRDT toolkits such as Yjs or AutoMerge for these features? It would make working with them so much easier if there was a plug and play backend._
-@samwillis on [HackerNews](https://news.ycombinator.com/item?id=32510820)
+
+ @samwillis on [HackerNews](https://news.ycombinator.com/item?id=32510820)
+
-pg_crdt has not been released onto the Supabase platform (and it may never be). We’re considering many options for offline-sync/support and, while CRDTs will undoubtedly factor in, we’re not sure if this is the *right* approach. Hopefully this release generates a healthy discussion about the various ways we can do it at Supabase.
+pg_crdt has not been released onto the Supabase platform (and it may never be). We're considering many options for offline-sync/support and, while CRDTs will undoubtedly factor in, we're not sure if this is the right approach. Hopefully this release generates a healthy discussion about the various ways we can do it at Supabase.
-## What’s a CRDT?
+## What's a CRDT?
A CRDT (Conflict-free Replicated Data Type) is a data structure. More accurately, a family of data structures. They enable collaborative apps like [Figma](https://www.figma.com/blog/how-figmas-multiplayer-technology-works/).
-You already know what a “data structure” is: an Array is a good example. CRDTs are a *special* type of data structure designed to solve a specific problem: they can merge changes in a way that the final state of the data will be the same, no matter the order in which the updates were applied.
+You already know what a “data structure” is: an Array is a good example. CRDTs are a _special_ type of data structure designed to solve a specific problem: they can merge changes in a way that the final state of the data will be the same, no matter the order in which the updates were applied.
In simple terms, a CRDT allows multiple users to make changes to the same data without the need for a central authority to coordinate their actions.
-Let’s use our Array example to demonstrate the problem they solve. Imagine you have an array (which is not a CRDT):
+Let's use our Array example to demonstrate the problem they solve. Imagine you have an array (which is not a CRDT):
```jsx
let fruit = ['Apple', 'Banana', 'Orange']
```
-Now imagine you have 2 developers updating this array on their local computers. They both want to replace the fruit at the start of the array. The first user, let’s call her “Jenny”, does this:
+Now imagine you have 2 developers updating this array on their local computers. They both want to replace the fruit at the start of the array. The first user, let's call her “Jenny”, does this:
```js
fruit[0] = 'Grape' // the array is ['Grape', 'Banana', 'Orange']
```
-The developer sitting next to her, let’s call him “Jonny”, does the same:
+The developer sitting next to her, let's call him “Jonny”, does the same:
```js
fruit[0] = 'Mango' // the array is ['Mango', 'Banana', 'Orange']
@@ -51,36 +53,36 @@ And now, since they are both developing on different machines, they push their c

-Since this is one of those *basic* arrays, the answer is "the fruit array that arrives last”.
+Since this is one of those _basic_ arrays, the answer is "the fruit array that arrives last”.
-1. If Jonny’s fruit array arrives first, it will be saved.
-2. After that, Jenny’s fruit arrived and overwrites Jonny’s changes.
+1. If Jonny's fruit array arrives first, it will be saved.
+2. After that, Jenny's fruit arrived and overwrites Jonny's changes.
-But therein lies the problem: Jonny was the last developer to change his array of fruit, shouldn’t his changes be the ones that are saved?
+But therein lies the problem: Jonny was the last developer to change his array of fruit, shouldn't his changes be the ones that are saved?
-That’s one of the things that CRDTs solve. There is an “array CRDT” which, when merged, will always have the same result. It doesn’t matter if Jonny’s array arrives first, or if Jenny’s arrives first - every time you merge them they would be able to determine that the Jonny’s was the last change the fruit array.
+That's one of the things that CRDTs solve. There is an “array CRDT” which, when merged, will always have the same result. It doesn't matter if Jonny's array arrives first, or if Jenny's arrives first - every time you merge them they would be able to determine that the Jonny's was the last change the fruit array.
How does it do that? Some sort of algorithm, but you can ask ChatGPT to explain that one.
## Offline philosophy
-Collaborative apps are becoming more prolific as legacy software is rebuilt within a browser environment.
+Collaborative apps are becoming more prolific as legacy software is rebuilt within a browser environment.
-Collaboration is largely a data problem - how do we get one user’s changes (data) to merge with another user’s changes (data)? As a database provider it’s natural fit for Supabase to provide the tooling for developers to build collaborative apps.
+Collaboration is largely a data problem - how do we get one user's changes (data) to merge with another user's changes (data)? As a database provider it's natural fit for Supabase to provide the tooling for developers to build collaborative apps.
-Before going too far down the “solution” rabbit hole at Supabase, we try to think about the long-term implications of adopting any technology. We’re pretty boring - we don’t make bets on technologies unless we think they will exist in 20 years.
+Before going too far down the “solution” rabbit hole at Supabase, we try to think about the long-term implications of adopting any technology. We're pretty boring - we don't make bets on technologies unless we think they will exist in 20 years.
-I personally believe CRDTs are the future. For *some things*. If databases were invented today, I’m certain most of the effort would be spent developing CRDT databases or something with “offline algorithms” built-in. But tech is a real-world demonstration of the Lindy effect: the longer something has existed, the longer it’s likely to exist in the future. That’s why we bet on Postgres - with more than 30 years history, it’s here to stay.
+I personally believe CRDTs are the future. For _some things_. If databases were invented today, I'm certain most of the effort would be spent developing CRDT databases or something with “offline algorithms” built-in. But tech is a real-world demonstration of the Lindy effect: the longer something has existed, the longer it's likely to exist in the future. That's why we bet on Postgres - with more than 30 years history, it's here to stay.
-Faced with this reality, we should consider how to solve *offline with Postgres* and where CRDTs might fit into that picture.
+Faced with this reality, we should consider how to solve _offline with Postgres_ and where CRDTs might fit into that picture.
-For a long time I thought there could be a way to shoehorn Postgres row-level data into a CRDT, to give *truly* offline support. This may even still be [possible](https://electric-sql.com/), and it’s one of the ideas we’ll continue to pursue. But Postgres is a rich and evolving ecosystem, and I don’t know whether it will be possible to -
+For a long time I thought there could be a way to shoehorn Postgres row-level data into a CRDT, to give _truly_ offline support. This may even still be [possible](https://electric-sql.com/), and it's one of the ideas we'll continue to pursue. But Postgres is a rich and evolving ecosystem, and I don't know whether it will be possible to -
a) find a merge strategy for an entire row, while simultaneously:
-b) finding a merge strategy for every data type *within* that row (especially with the number of data types available through extensions)
+b) finding a merge strategy for every data type _within_ that row (especially with the number of data types available through extensions)
-It’s possible that developers will need to be selective about their “level” of offline support, at least if they plan to use an “incumbent” databases. For the cases, a simple “last write wins” strategy is probably acceptable (see the excellent [Replicache](https://doc.replicache.dev/examples/repliear) and [Watermelon](https://nozbe.github.io/WatermelonDB/) libraries), but there will be important pieces of their application where it is not.
+It's possible that developers will need to be selective about their “level” of offline support, at least if they plan to use an “incumbent” databases. For the cases, a simple “last write wins” strategy is probably acceptable (see the excellent [Replicache](https://doc.replicache.dev/examples/repliear) and [Watermelon](https://nozbe.github.io/WatermelonDB/) libraries), but there will be important pieces of their application where it is not.
Take this table of blog posts as an example:
@@ -92,9 +94,9 @@ create table posts (
);
```
-Perhaps it’s not that important if the `title` has a “last write wins” strategy, because it’s rarely updated and less likely to have a merge conflict. But it is critical to use a smarter algorithm for the `content` of the blog post, especially in a team where multiple users are editing a blog post at the same time.
+Perhaps it's not that important if the `title` has a “last write wins” strategy, because it's rarely updated and less likely to have a merge conflict. But it is critical to use a smarter algorithm for the `content` of the blog post, especially in a team where multiple users are editing a blog post at the same time.
-That’s a lot of background to get to what you probably want to know about:
+That's a lot of background to get to what you probably want to know about:
## Postgres CRDT extension
@@ -108,7 +110,7 @@ create table posts (
);
```
-The `content` column is now a [Yjs Doc](https://docs.yjs.dev/api/y.doc). Updates to this column are *commutative* and *idempotent*. This means that they can be applied in any order and multiple times, and the result will always be the same. Two people can edit the blog content at the same time, and they won’t have any issues when their changes are saved in the database.
+The `content` column is now a [Yjs Doc](https://docs.yjs.dev/api/y.doc). Updates to this column are _commutative_ and _idempotent_. This means that they can be applied in any order and multiple times, and the result will always be the same. Two people can edit the blog content at the same time, and they won't have any issues when their changes are saved in the database.
### Support for Yjs, Automerge, and beyond
@@ -116,7 +118,7 @@ The Yjs and Automerge teams have done some excellent work to create Rust librari
At this stage it makes sense to give developers as many choices as possible in one extension. The CRDT space is nascent the algorithms are rapidly changing.
-Importantly, both Yjs and Automerge have *JavaScript* and Rust implementations, which means they work natively in both a browser and a Postgres environment. Since collaborative applications are largely a client-side problem, CRDTs are more useful for developers if they have robust JavaScript libraries. In the future, if this extension becomes the approach we take, then Supabase will focus some resources on building Yjs/Automerge libraries for mobile devices too (Swift for iOS, Kotlin for Android).
+Importantly, both Yjs and Automerge have _JavaScript_ and Rust implementations, which means they work natively in both a browser and a Postgres environment. Since collaborative applications are largely a client-side problem, CRDTs are more useful for developers if they have robust JavaScript libraries. In the future, if this extension becomes the approach we take, then Supabase will focus some resources on building Yjs/Automerge libraries for mobile devices too (Swift for iOS, Kotlin for Android).
## Why not build this into Realtime?
@@ -128,18 +130,18 @@ This might still be our best option, but it should not be our first attempt. If

-The Realtime engine seems like a great *compliment* for `pg_crdt`, but before we put it into production we need to solve a few (major) limitations.
+The Realtime engine seems like a great _compliment_ for `pg_crdt`, but before we put it into production we need to solve a few (major) limitations.
## Limitations
-These are a few of the *known* limitations:
+These are a few of the _known_ limitations:
- Realtime broadcasts database changes from the Postgres write ahead log (WAL). The WAL includes a complete copy of the the underlying data so small updates cause the entire document to broadcast to all collaborators
- Frequently updated CRDTs produce a lot of WAL and dead tuples
- Large CRDT types in Postgres generate significant serialization/deserialization overhead on-update.
-We’re likely to discover more (no doubt from a few friendly HN comments).
+We're likely to discover more (no doubt from a few friendly HN comments).
## Next steps
-If you want to help with `pg_crdt` the best way is to get involved in the GitHub repo. We have enabled [Discussions](https://github.com/supabase/pg_crdt/discussions) for any and all ideas. If you have experience with CRDTs and you like this approach, don’t hesitate to contact one of the team.
\ No newline at end of file
+If you want to help with `pg_crdt` the best way is to get involved in the GitHub repo. We have enabled [Discussions](https://github.com/supabase/pg_crdt/discussions) for any and all ideas. If you have experience with CRDTs and you like this approach, don't hesitate to contact one of the team.
diff --git a/apps/www/_blog/2022-12-12-new-supabase-docs-built-with-nextjs.mdx b/apps/www/_blog/2022-12-12-new-supabase-docs-built-with-nextjs.mdx
index dbeca1493f0..41f8ef5ac1e 100644
--- a/apps/www/_blog/2022-12-12-new-supabase-docs-built-with-nextjs.mdx
+++ b/apps/www/_blog/2022-12-12-new-supabase-docs-built-with-nextjs.mdx
@@ -1,6 +1,6 @@
---
title: 'New Supabase Docs, built with Next.js'
-description: We've redesignd our Docs and migrated to Next.js
+description: We've redesigned our Docs and migrated to Next.js
author: jonny
image: lw6-day-1/lw6-day1-docs.jpg
thumb: lw6-day-1/lw6-day1-docs.jpg
diff --git a/apps/www/_blog/2022-12-14-mfa-auth-via-rls.mdx b/apps/www/_blog/2022-12-14-mfa-auth-via-rls.mdx
index 8eeab704ba6..b2b4cbedff0 100644
--- a/apps/www/_blog/2022-12-14-mfa-auth-via-rls.mdx
+++ b/apps/www/_blog/2022-12-14-mfa-auth-via-rls.mdx
@@ -41,7 +41,7 @@ In the event that the user faces difficulties entering a QR code the user can al
An MFA flow can be broken into two key steps: Enrollment and Verification. During the *Enrollment* process Supabase Auth exchanges a randomly generated secret with the user’s authenticator application. During the *Verification* process, the device makes use of the timestamp together with the secret to produce a six digit code that the server can verify.

-**Enrollment**
+*Enrollment*
To generate a QR code, call the `/enroll` endpoint which returns an SVG encoded QR and the secret. Thereafter, create a challenge by calling the `/challenge` endpoint. Once the user has entered the six digit TOTP code generated by their authenticator app, call the`/verify` endpoint with the corresponding factor and challenge details.
diff --git a/apps/www/_blog/2022-12-16-custom-domain-names.mdx b/apps/www/_blog/2022-12-16-custom-domain-names.mdx
new file mode 100644
index 00000000000..014255f71a8
--- /dev/null
+++ b/apps/www/_blog/2022-12-16-custom-domain-names.mdx
@@ -0,0 +1,67 @@
+---
+title: Custom Domain Names
+description: Change your Supabase project's domain name to your own domain.
+author: div_arora
+image: launch-week-6/custom-domains/og-custom-domains.png
+thumb: launch-week-6/custom-domains/og-custom-domains.png
+tags:
+ - launch-week
+date: '2022-12-16'
+toc_depth: 3
+---
+
+After your side-project becomes wildly viral, and you've graduated into a “serious business”, delivering a more branded experience is probably one of the items at the bottom of your checklist.
+
+To that end, we're releasing custom domains, and vanity subdomains, to help you present a more polished product to your users.
+
+# Custom Domains
+
+Custom domains allow you to use your own domain for your Supabase project.
+
+Instead of seeing:
+
+`sqvfdnkeiuztnsinmtau.supabase.co`
+
+your users instead interact with
+
+`api.example.com`:
+
+
+
+Today, we're making Custom Domains generally available, and they're now accessible as a paid add-on through the Supabase dashboard.
+
+Get your custom domain in the [Dashboard](https://app.supabase.com/project/_/settings/general)
+
+# Vanity Subdomains
+
+Vanity Subdomains allow you to choose a subdomain on Supabase's own domain.
+
+Instead of hosting your services on a randomly assigned subdomain:
+
+`abcdefghijklmno.supabase.co`
+
+you can choose one that's relevant to your project, for example:
+
+`my-example-brand.supabase.co`
+
+Vanity Subdomains are offered at no additional cost for all projects on a paid plan, and are being launched in a closed beta.
+
+Instructions for setting up Vanity Subdomains are now available in our [docs](https://supabase.com/docs/guides/platform/custom-domains#vanity-subdomains).
+
+## Limitations
+
+In this release, we still have some limitations that we're working through:
+
+1. Edge Functions don't support custom domains or vanity subdomains yet, so you have to use the current endpoint to access them.
+2. Right now, you can only set up one custom domain or vanity subdomain per project.
+
+We're working hard to fix these limitations, so stay tuned for future updates.
+
+## More Launch Week 6
+
+- [Day 1: New Supabase Docs, built with Next.js](https://supabase.com/blog/new-supabase-docs-built-with-nextjs)
+- [Day 2: Supabase Storage v2: Image resizing and Smart CDN](https://supabase.com/blog/storage-image-resizing-smart-cdn)
+- [Day 3: Multi-factor Authentication via Row Level Security Enforcement](https://supabase.com/blog/mfa-auth-via-rls)
+- [Launch Week 6 Hackathon](https://supabase.com/blog/launch-week-6-hackathon)
+- [Who We Hire at Supabase](https://supabase.com/blog/who-we-hire)
+- [pg_crdt - an experimental CRDT extension for Postgres](https://supabase.com/blog/postgres-crdt)
diff --git a/apps/www/_blog/2022-12-16-launch-week-6-community-day.mdx b/apps/www/_blog/2022-12-16-launch-week-6-community-day.mdx
index 98e9aa112ec..7e84894bfb6 100644
--- a/apps/www/_blog/2022-12-16-launch-week-6-community-day.mdx
+++ b/apps/www/_blog/2022-12-16-launch-week-6-community-day.mdx
@@ -57,7 +57,7 @@ Combining OneSignal with Supabase, you can send cloud messages to your users wit
We have guides on how to get started with [Next.js and OneSignal](https://supabase.com/docs/guides/integrations/onesignal), and [Flutter and OneSignal](https://github.com/OneSignalDevelopers/onesignal-supabase-sample-integration-supabase).
-In the video above, William from OneSignal will show you how you can easily integrate OneAignal with your Supabase app.
+In the video above, William from OneSignal will show you how you can easily integrate OneSignal with your Supabase app.
### NextAuth
@@ -148,13 +148,13 @@ One of the most exciting developments this year is the number of content creator
### Content Storm
-More than 30+ creatores featured in our [Content Storm](https://supabase.com/blog/the-supabase-content-storm). These folks all produced brand new content in the build up to Launch Week and dropped it simultaniously!
+More than 30+ creators featured in our [Content Storm](https://supabase.com/blog/the-supabase-content-storm). These folks all produced brand new content in the build up to Launch Week and dropped it simultaneously!
### Supaship

-Supaship built a whole [Supabase course](https://supaship.io/). It's absolutley jam-packed with advice on how to get the most out of Supabase (and his meme game is absolute fire!).
+Supaship built a whole [Supabase course](https://supaship.io/). It's absolutely jam-packed with advice on how to get the most out of Supabase (and his meme game is absolute fire!).
### Jon Meyers for Egghead
diff --git a/apps/www/_blog/2022-12-16-launch-week-6-wrap-up.mdx b/apps/www/_blog/2022-12-16-launch-week-6-wrap-up.mdx
new file mode 100644
index 00000000000..1e25e3c1534
--- /dev/null
+++ b/apps/www/_blog/2022-12-16-launch-week-6-wrap-up.mdx
@@ -0,0 +1,207 @@
+---
+title: 'Launch Week 6: Wrap Up'
+description: "That's a wrap on Supabase Launch Week Day 6. Here's everything we shipped in one long blog post."
+author: paul_copplestone
+image: launch-week-6/wrap-up/og-wrap-up.png
+thumb: launch-week-6/wrap-up/og-wrap-up.png
+tags:
+ - launch-week
+date: '2022-12-16'
+toc_depth: 3
+---
+
+That's a wrap on Supabase Launch Week Day 6. Here's everything we shipped in one long blog post.
+
+## New Docs, built with Next.js
+
+
+
+Monday
+
+For a developer tool, documentation is more than a resource - it's part of the product. For the past two years at Supabase, this part of our product hasn't been great. Our new docs, built with Next.js, feature a completely new design, better navigation, and the promise of a fully-integrated experience.
+
+- Read the [announcememt](/blog/new-supabase-docs-built-with-nextjs)
+- Watch the [recap on YouTube](https://www.youtube.com/watch?v=Q1Amk6iDlF8)
+- Check out [the new docs](https://supabase.com/docs)
+
+## Storage v2: Image resizing and Smart CDN
+
+
+
+Tuesday
+
+We're introducing three new features for Supabase Storage: Image resizing, webhooks, and a Smart CDN. These features are designed to work together to deliver a next-gen image resizing system.
+
+- Read the [announcement](https://supabase.com/blog/storage-image-resizing-smart-cdn)
+- Watch the [recap on YouTube](https://www.youtube.com/watch?v=NpEl20iuOtg)
+- Browse the docs for [Image Transformations](https://supabase.com/docs/guides/storage/image-transformations)
+- Browse the docs for our [Smart CDN](https://supabase.com/docs/guides/storage/cdn#smart-cdn-caching)
+- Discuss it on [HackerNews](https://news.ycombinator.com/item?id=33969076)
+
+## Auth: Multi-factor Authentication with RLS
+
+
+
+Wednesday
+
+We released Multi Factor Authentication for you to build more secure applications. We built a unique twist so that you can use MFA within your Row Level Security Policies.
+
+- Read the [announcement](/blog/mfa-auth-via-rls)
+- Watch the [recap on YouTube](https://www.youtube.com/watch?v=He7LI2mv9v0)
+- Browse the [docs](/docs/guides/auth/auth-mfa)
+- Discuss it on [HackerNews](https://news.ycombinator.com/item?id=33984104)
+
+## Wrappers, a FDW framework for Postgres
+
+
+
+Thursday
+
+We announced [Supabase Wrappers](https://github.com/supabase/wrappers), a framework for building Postgres Foreign Data Wrappers (FDW) which connects Postgres to external systems. We're releasing Wrappers today in Alpha, with support for Firebase and Stripe. Wrappers for Clickhouse, BigQuery, and Airtable are under development.
+
+- Read the [announcement](/blog/postgres-foreign-data-wrappers-rust)
+- Watch the [recap on YouTube](https://www.youtube.com/watch?v=He7LI2mv9v0)
+- Browse the [docs](https://supabase.github.io)
+- Discuss it on [HackerNews](https://news.ycombinator.com/item?id=34001493)
+
+## Vault: secrets and encryption in Postgres
+
+
+
+Friday
+
+Vault is a new Postgres extension and accompanying Supabase UI that makes it safe and easy to store encrypted secrets and encrypt other stored data in your database. We're releasing it progressively across the platform and you can expect to see it appear in the Supabase Dashboard in the coming weeks.
+
+- Read the [announcement](/blog/vault-now-in-beta)
+- Learn about [Transparent Column Encryption](/blog/transparent-column-encryption-with-postgres)
+
+## pg_graphql v1: GraphQL in Postgres
+
+
+
+One more thing
+
+Today released pg_graphql 1.0 release and its general availability on our platform. pg_graphql is a PostgreSQL extension that allows you to query your database using GraphQL. It is the foundation of GraphQL support in the Supabase stack.
+
+- Read the [announcement](/blog/pg-graphql-v1)
+- Browse the [GitHub repo](https://github.com/supabase/pg_graphql/)
+- View the [docs](/docs/guides/api#graphql-api)
+
+## Postgres Point-in-Time Recovery
+
+
+
+One more thing
+
+Point In Time Recovery (PITR) is now enabled from the dashboard for Pro Projects. With PITR, you can restore your database at any specified time in the past.
+
+- Read the [announcement](/blog/postgres-point-in-time-recovery)
+- Review the [Production Readiness docs](/docs/guides/platform/going-into-prod)
+
+## Custom domains
+
+
+
+One more thing
+
+Custom domains allow you to use your own domain for your Supabase project. We've released custom domains as an upgrade option for all projects, and vanity domains for Pro projects.
+
+- Read the [announcement](/blog/custom-domain-names)
+- Visit the [Custom Domains docs](/docs/guides/platform/custom-domains)
+
+## pg_crdt: a Postgres extension for CRDTs
+
+
+
+One more thing
+
+We open-sourced an experimental extension for CRDTs, pg_crdt. If you're familiar with Yjs or Automerge, then check out the work we're doing here. It's a PostgreSQL extension that allows you to use CRDTs in your database.
+
+- Read the [announcement](/blog/postgres-crdt)
+- Browse the [GitHub repo](https://github.com/supabase/pg_crdt)
+- Discuss it on [HackerNews](https://news.ycombinator.com/item?id=33931971)
+
+## PostgreSQL 15: we support it
+
+
+
+One more thing
+
+All new projects created on the Supabase platform are now on version 15. The PostgreSQL community released version 15 (stable) in October 2022.
+
+- Learn what's [new in PostgreSQL 15](/blog/new-in-postgres-15)
+- View the full PostgreSQL 15 [release notes](https://www.postgresql.org/docs/15/release-15.html)
+
+## PostgREST 11: pre-release
+
+
+
+One more thing
+
+You can now test the PostgREST 11 pre-release locally with the Supabase CLI. Some of the new features include: spreading related tables, related orders and anti-joins.
+
+- Learn more about [PostgREST 11](/blog/postgrest-11-prerelease)
+- Visit the [CLI docs](/docs/guides/resources/supabase-cli)
+
+## Multilingual search in Postgres
+
+
+
+One more thing
+
+We've released a new multilingual Full Text Search extension, PGroonga. It's fast, it's open source, and it's available on our platform today. If you've ever wanted to build a search engine for your app, then check out PGroonga.
+
+- Visit the [PGroonga website](https://pgroonga.github.io)
+- Read the [Extensions Docs](/docs/guides/database/extensions)
+
+## Flutterflow for Flutter App Development
+
+
+
+
+
+Community Spotlight
+
+We partnered with the team at [Flutterflow](https://flutterflow.io/) to bring you a new way to build Flutter apps. Flutterflow is a low-code platform that allows you to build Flutter apps without writing any code. It's a great way to get started with Flutter and Supabase.
+
+- Watch the [tutorial](https://www.youtube.com/watch?v=hw9Q-NjASbU)
+- Get Started with [Flutterflow](https://flutterflow.io/)
+
+## OneSignal for Push Notifications
+
+
+
+
+
+Community Spotlight
+
+We partnered with the team at [OneSignal](https://onesignal.com/) to offer push notifications in Supabase. OneSignal is a messaging platform allowing you to deliver push notifications, in-app messages, SMS, and emails to your users.
+
+- Watch the [tutorial](https://www.youtube.com/watch?v=mw0DLwItue4)
+- Get Started with [OneSignal](https://onesignal.com/)
+
+## Getting Started
+
+Get started today with Supabase. It's free and open source.
+
+- [Like some memes on Twitter](https://twitter.com/supabase)
+- [Star us on GitHub](https://github.com/supabase/supabase)
+- [Join the Discord](https://discord.supabase.com)
+- [Read the docs](https://supabase.com/docs)
+- [Sign up](https://app.supabase.io/)
diff --git a/apps/www/_blog/2022-12-16-new-in-postgres-15.mdx b/apps/www/_blog/2022-12-16-new-in-postgres-15.mdx
index da45e32becf..d1b158b5a47 100644
--- a/apps/www/_blog/2022-12-16-new-in-postgres-15.mdx
+++ b/apps/www/_blog/2022-12-16-new-in-postgres-15.mdx
@@ -17,7 +17,7 @@ The PostgreSQL community [released](https://www.postgresql.org/docs/current/rele
`CREATE` permission is revoked from all users except the database owner. It makes permission assigning more tunable ([details](https://www.postgresql.org/docs/15/ddl-schemas.html#DDL-SCHEMAS-PATTERNS)). And for the migrated database don't forget to revoke `CREATE` permission on the public schema manually to fit the new policy.
-There is a useful option `CREATE VIEW .. WITH security_invoker=on` to create a view that uses permissions of a view caller rather than a view creator to access underlying tables. With this, you should not worry that a user that doesn't have access to a table could see its data through a view.
+There is a useful option `CREATE VIEW .. WITH (security_invoker=on)` to create a view that uses permissions of a view caller rather than a view creator to access underlying tables. With this, you should not worry that a user that doesn't have access to a table could see its data through a view.
## **Performance speed-up**
diff --git a/apps/www/_blog/2022-12-16-pg-graphql-v1.mdx b/apps/www/_blog/2022-12-16-pg-graphql-v1.mdx
new file mode 100644
index 00000000000..30c6c59d777
--- /dev/null
+++ b/apps/www/_blog/2022-12-16-pg-graphql-v1.mdx
@@ -0,0 +1,103 @@
+---
+title: pg_graphql v1.0
+description: Announcing the v1.0 release of pg_graphql
+author: oli_rice
+image: launch-week-6/pggraphql/og-pg-graphql.png
+thumb: launch-week-6/pggraphql/og-pg-graphql.png
+tags:
+ - graphql
+ - postgres
+ - launch-week
+date: '2022-12-16'
+toc_depth: 3
+---
+
+Today we're announcing the 1.0 release of pg_graphql and its general availability on our platform. pg_graphql is a PostgreSQL extension that allows you to query your database using GraphQL. It is the foundation of GraphQL support in the Supabase stack.
+
+Since our first platform release, v0.2.1, the feature set of pg_graphql has steadily grown and stabilized. Despite being a pre-1.0, we've been extremely cautious with each new feature and have yet to introduce a backwards-incompatible change. With the 1.0 release we're formalizing that guarantee, subject to the SemVer spec.
+
+## Background
+
+pg_graphql was created to satisfy an extreme set of constraints. Mainly, [Supabase free tier](https://supabase.com/pricing) projects run on servers with 1 GB of memory. On those servers, we squeeze tuned versions of [PostgreSQL](https://github.com/supabase/postgres), [PostgREST](https://postgrest.org/en/stable/), and [GoTrue](https://github.com/supabase/gotrue). Every megabyte consumed by something that isn't PostgreSQL is another chance for an index to fall out of memory, or a large query to fail.
+
+Our philosophy when adding to the stack is to use existing open source tools wherever possible. We surveyed the available GraphQL → SQL options and found some excellent candidates in [Hasura](https://hasura.io/) and [Graphile](https://www.graphile.org/). Both support the set of features we're interested in, but consume significantly more memory than we could sacrifice on the free tier. Realizing that, we searched for an architecture that could meet our runtime constraints and performance requirements.
+
+## Architecture
+
+Our first prototype of pg_graphql PostgreSQL extension had a parser written in C (libgraphqlparser) with all business logic of transpiling GraphQL to SQL **written** in SQL. We exposed the extensions sole SQL function `graphql.resolve(...)` over HTTP using PostgREST's [RPC functionality](https://postgrest.org/en/stable/api.html#s-procs). With this approach, the memory footprint was too small to measure when accessed over HTTP. While memory-use sent us down this path, we discovered that leaning into Postgres primitives lead to some incredible synergies. To name a few:
+
+### Security
+
+Since data are accessed through a standard, unprivileged, SQL function, Postgres role permissions and Row Level Security (RLS) policies work exactly like they do in Postgres. Define your security model once, and it applies everywhere: SQL, REST, Realtime, and GraphQL
+
+### Always up-to-date
+
+No separate process means no roundtrip time. Inspecting the database's schema does not require any caching and is always in-sync. Knowing that the GraphQL and SQL schemas are aligned give us the confidence to compile GraphQL requests of any complexity into exactly one SQL query, [solving the N+1 query problem](https://medium.com/the-marcy-lab-school/what-is-the-n-1-problem-in-graphql-dd4921cb3c1a) and producing high throughput.
+
+### Scaling
+
+As an extension, pg_graphql's performance scales directly with the size of the database. When a user's performance needs grow, upgrading the database instance also scales up GraphQL throughput with no external processes to manage.
+
+### ACID - Atomicity, Consistency, Isolation, and Durability
+
+Databases have strong ACID guarantees. Being embedded in the database lets us claim those guarantees through the GraphQL API. For example, if any part of a multi-mutation GraphQL request fails, the entire request can roll back to leave the database in a consistent state.
+
+## From SQL to Rust
+
+Our pure [SQL implementation of the pg_graphql transpiler](https://github.com/supabase/pg_graphql/blob/bd0283718abaf329d98c69808f862594e9df5edc/pg_graphql--0.4.0.sql) carried us from v0.0.1 to v0.4.0. Ultimately, we started to feel some pain, although probably not in the way you'd expect.
+
+Opinions about business logic in SQL are notoriously split. In my view, there are some foot guns, but:
+
+- SQL has types
+- SQL has functions
+- Functions are composable
+
+Ergo, keep your functions pure and you've got a strongly typed functional programming paradigm. Taking that approach, the developer experience for pg_graphql was surprisingly excellent. The feedback cycle with [pg_regress](https://www.postgresql.org/docs/9.1/regress.html) is fast, and occasionally the type system even caught a bug or two. What more could you ask for?
+
+Somewhere around the 4,000 line count, things started to bog down. The rough shape of the codebase was coming into view, which made it clear where we could further extract common patterns into functions. At this point I learned two things:
+
+- SQL functions are “pass by value” (copy) so passing state around can get expensive
+- The query planner tends to stop inlining functions when calls are deeply nested
+
+Combine those two facts with our GraphQL AST being a big ball of JSONB, and the GitHub issues about slow schema introspection on free tier started to trickle in.
+
+Enter [pgx](https://github.com/tcdi/pgx)…
+
+pgx is a rust framework for building Postgres extensions. It has a very polished onboarding experience and (as you would expect) full SQL interop. That made it straightforward to initially sprinkle some rust on pg_graphql's hotspots. When that went well, we ultimately rewrote pg_graphql from the ground up as a pure Rust project for the v0.5.0 release.
+
+One of rust's main selling points is zero cost abstractions. That means high-level concepts like generics incur no runtime penalty. Transitioning from SQL's expensive abstractions to rust's zero cost abstractions has been hugely satisfying as it enabled refactoring the codebase into a more maintainable state. Development velocity is up. Code quality is up. Performance is WAY up.
+
+As of 1.0, overhead introduced by pg_graphql is sub 300 *micro*seconds per request on free-tier hardware. When executed from SQL we see ~1060 queries per second per connection (no parallelism). If we include the entire Auth + HTTP stack, free tier can handle ~645 requests per second. On larger instance the stack handles upwards of 10k requests / second.
+
+```text
+This is ApacheBench, Version 2.3 <$Revision: 1843412 $>
+Server Software: postgrest/10.1.1
+Document Path: /graphql/v1
+Concurrency Level: 10
+Time taken for tests: 3.099 seconds
+Complete requests: 2000
+Requests per second: 645.40 [#/sec] (mean)
+Time per request: 15.494 [ms] (mean)
+Time per request: 1.549 [ms] (mean, across all concurrent requests)
+```
+
+## Roadmap
+
+While v1.0 is an important milestone for stability, there's plenty of room to expand the feature set. For example, some commonly requested features on the immediate roadmap are:
+
+- Extended filtering options
+ - `startsWith` for the `String` type
+ - nestable `and`/ `or` blocks
+- Support for user-defined functions
+- Support for views
+
+Longer term we look forward to experimenting with more ambitions features like an API for migrations, integrations with 3rd-party services through [supabase/wrappers](https://github.com/supabase/wrappers), and a scalable solution for subscriptions.
+
+## More Launch Week 6
+
+- [Day 1: New Supabase Docs, built with Next.js](https://supabase.com/blog/new-supabase-docs-built-with-nextjs)
+- [Day 2: Supabase Storage v2: Image resizing and Smart CDN](https://supabase.com/blog/storage-image-resizing-smart-cdn)
+- [Day 3: Multi-factor Authentication via Row Level Security Enforcement](https://supabase.com/blog/mfa-auth-via-rls)
+- [Launch Week 6 Hackathon](https://supabase.com/blog/launch-week-6-hackathon)
+- [Who We Hire at Supabase](https://supabase.com/blog/who-we-hire)
+- [pg_crdt - an experimental CRDT extension for Postgres](https://supabase.com/blog/postgres-crdt)
diff --git a/apps/www/_blog/2022-12-16-postgres-point-in-time-recovery.mdx b/apps/www/_blog/2022-12-16-postgres-point-in-time-recovery.mdx
new file mode 100644
index 00000000000..243adfdb0e1
--- /dev/null
+++ b/apps/www/_blog/2022-12-16-postgres-point-in-time-recovery.mdx
@@ -0,0 +1,50 @@
+---
+title: 'Point in Time Recovery is now available for Pro projects'
+description: "We're making PITR available for more projects, with a new Dashboard UI that makes it simple to use."
+author: angelico_de_los_reyes
+image: launch-week-6/pitr/og-pitr.png
+thumb: launch-week-6/pitr/og-pitr.png
+tags:
+ - launch-week
+ - postgres
+ - backups
+date: '2022-12-16'
+toc_depth: 3
+---
+
+When we announced Point-in-Time a few months ago, it was only available for Enterprise customers. Today, we're making PITR available for more projects, with a new Dashboard UI that makes it simple to use.
+
+Pro-tier projects created from August 2022 onwards (excluding Northeast Asia / Seoul region), can now enable Point In Time Recovery (PITR) from the dashboard. Projects must have the "Small" compute add-on to ensure that PITR operates smoothly behind the scenes.
+
+For older projects, don't worry - we're working on making it available for everybody. In the meantime, if you would like to have PITR enabled for your ineligible project, reach out directly [here](https://app.supabase.com/support/new), or stay tuned for further updates.
+
+## What is Point in Time Recovery?
+
+
+
+Point in Time Recovery provides the ability for a database to be restored at any specified point in time. This is useful when averting disasters, for all those times that a, _cough_, natural calamity strikes (like accidentally dropping a table). With PITR, the database can be restored to a state it was in mere seconds before trouble.
+
+All of this is made possible by a combination of physical backups and archives from the [Write Ahead Log (WAL)](https://www.postgresql.org/docs/current/wal-intro.html). Physical backups provide a snapshot of the underlying directory of the database, while WAL files contain records of every change made in the database.
+
+Under the hood, we use [WAL-G](https://github.com/wal-g/wal-g), an open source archival and restoration tool, to handle all aspects of PITR. On a daily basis, WAL-G takes a snapshot of the database and sends it to our storage servers. Throughout the day, as database transactions occur, WAL files are generated and uploaded to archived.
+
+## Should I enable PITR?
+
+
+
+Consider your Recovery Point Objective (RPO) when deciding whether to enable Point in Time Recovery. RPO is the threshold for how much data, measured in time, a business could lose when disaster strikes. This is dependent on a business and its underlying requirements. The agreed upon RPO would be a deciding factor in choosing which solution best fits a project.
+
+While all Pro-tier projects and above are backed up on a daily basis, this means that at the worst case, a project could lose up to 24 hours worth of data if disaster hits at the most inopportune time. With Point in Time Recovery however, backups are made at much shorter intervals, shortening the RPO. WAL files are backed up at two minute intervals. This could be faster if it hits a certain file threshold before the the two minute mark.
+
+## Getting started
+
+Enabling Point in Time Recovery could be done [in the Dashboard](https://app.supabase.com/project/_/settings/billing/update/pro). Retention for backups used by PITR is set to up to 7 days by default but could be increased to up to 28 days via self-serve.
+
+## More Launch Week 6
+
+- [Day 1: New Supabase Docs, built with Next.js](https://supabase.com/blog/new-supabase-docs-built-with-nextjs)
+- [Day 2: Supabase Storage v2: Image resizing and Smart CDN](https://supabase.com/blog/storage-image-resizing-smart-cdn)
+- [Day 3: Multi-factor Authentication via Row Level Security Enforcement](https://supabase.com/blog/mfa-auth-via-rls)
+- [Launch Week 6 Hackathon](https://supabase.com/blog/launch-week-6-hackathon)
+- [Who We Hire at Supabase](https://supabase.com/blog/who-we-hire)
+- [pg_crdt - an experimental CRDT extension for Postgres](https://supabase.com/blog/postgres-crdt)
diff --git a/apps/www/_blog/2022-12-16-vault-now-in-beta.mdx b/apps/www/_blog/2022-12-16-vault-now-in-beta.mdx
new file mode 100644
index 00000000000..3d1418be10d
--- /dev/null
+++ b/apps/www/_blog/2022-12-16-vault-now-in-beta.mdx
@@ -0,0 +1,96 @@
+---
+title: 'Supabase Vault is now in Beta'
+description: 'A Postgres extension to store encrypted secrets and encrypt data.'
+author: michel
+image: launch-week-6/vault/og-vault.png
+thumb: launch-week-6/vault/og-vault.png
+tags:
+ - launch-week
+ - postgres
+ - encryption
+date: '2022-12-16'
+toc_depth: 3
+---
+
+During our last Launch Week we [announced](/blog/supabase-vault) Supabase Vault as our “one more thing”. Today we're releasing it progressively across the platform.
+
+Vault is a new Postgres extension and accompanying Supabase UI that makes it safe and easy to store encrypted secrets and encrypt other stored data in your database. This foundation opens up a lot of possibilities for Postgres that go beyond what is available in a stock distribution. From a product perspective we're grouping various features under the “Vault banner”. Let's explore a few of these features.
+
+## Secrets Management
+
+Practically speaking, the Vault is a table of Secrets and Encryption Keys that are stored using [Authenticated Encryption](https://en.wikipedia.org/wiki/Authenticated_encryption) on disk, but available in decrypted form through a Postgres view so that the secrets can be used by applications from SQL. Because the secrets are stored encrypted and authenticated, any backups or replication streams also preserve this encryption in a way that can't be forged.
+
+We've created a dashboard UI for the Vault that makes storing secrets easy. Click a button and type in your secret, optionally create a new key that is referenced by id (or use the existing default), and submit. Your secret is now stored on disk encrypted using the specified key id.
+
+
+
+There are two main parts to the Vault UI, Secrets and Encryption Keys:
+
+- **Secrets:** Use the Vault to store Secrets - everything from Environment Variables to API Keys. You can use these Secrets anywhere in your database: Postgres [Functions](/docs/guides/database/functions), Triggers, and [Webhooks](/docs/guides/database/webhooks). From a SQL perspective, accessing secrets is as easy as querying a table (or in this case, a view). The underlying secrets tables will be stored in encrypted form.
+- **Encryption Keys:** encryption keys are used to encrypt data inside your database. Fun fact: the Secrets you store in the Vault are encrypted with an Encryption Key which we set up by default and is not accessible to SQL or stored in your database alongside the same data it is used to encrypt. You can create different Encryption Keys for different purposes, for example: one for encrypting user-data, and another for application-data.
+
+## Transparent Column Encryption (TCE)
+
+Our recent [blog post](/blog/transparent-column-encryption-with-postgres) describes TCE in-depth. TCE is one of the safest ways to encrypt your data so that it doesn't leak into logs and backups, as well as providing your users with row-level authenticated encryption. TCE is the foundational feature of the Vault, but you can use it on your own tables if you choose to if the Vault isn't sufficient for your needs, for example if you have multiple tables that you wish to have encrypted columns. Any Postgres value that can be cast to `text` or `bytea` can use TCE to encrypt the data that is stored to disk.
+
+### Encrypting columns
+
+In the “New Column” flow on the Dashboard, you can select that a `text` or `bytea` column is encrypted, and select an existing key id or create a new one. This is functionally identical to the Vault above, but you can apply it to any of your existing tables. In a sense the Vault is a pre-created table and UI for you to get started quickly storing secrets, and to be a centralized point for “global” secrets management, but your not stuck with just that, you can encrypt multiple columns in multiple tables, how you want to store your secret data can be entirely up to you.
+
+
+
+Once you've setup an encrypted column, just insert data into the table like you would any other table. If you put in an email address for example, you will see that what is stored is not an email at all, but an encrypted value.
+
+
+
+Decrypted data can be accessed by a special view that is automatically created whenever you create an encrypted column on a table. This view decrypts the data row-by-row as you access it. By default this view is called `decrypted_`, so in the example provided, the decryption view for the `profiles` table is `decrypted_profiles`. In addition to the existing `emails` column, there is a new column in the view called `decrypted_emails` that contains the decrypted email value. It's that simple!
+
+
+
+## Deep Dive on How The Vault works
+
+
+
+As we mentioned, the Vault uses pgsodium's Transparent Column Encryption (TCE) to store secrets in an authenticated encrypted form. There are some details around that you may be curious about, what does authenticated mean, and where are encryption keys store? This section explains those details.
+
+The first important feature of TCE is that it uses an [Authenticated Encryption with Associated Data]() encryption algorithm based on libsodium. “Authenticated Encryption” means that in addition to the data being encrypted, it is also “signed” so that it cannot be forged, the decryption function verifies that the signature is valid **before decrypting the value**. “Associated Data” means that in addition to signing the secret, you can include any other columns in your row in the signature computation, “associating” those columns with the secret. This doesn't encrypt those other columns, but it does ensure that **they are authentic** and cannot be forged because they are included in the secret's signature. So you know when you restore your database dumps, not only are the secrets safe, but also the “associated” columns are also authentic and unforged.
+
+Another important feature of pgsodium is that the encryption keys are never stored in the database alongside the encrypted data, instead, only a **Key ID** is stored, which refers to a key that is only accessible outside of SQL. Even if an attacker can capture a dump of your entire database, they will see only encrypted data and key ids, **never the raw key itself**. This is an important safety precaution, there would be no point in storing the encryption key in the database alongside the encrypted data, this would be like locking your front door but leaving the key in the lock! Storing the key outside the database fixes this issue.
+
+You might be wondering, ok then where are the keys stored? Supabase creates and manages the root keys from which all key ids are derived in our internal customer backend systems. We keep this key safe and separate from your data, and provide an alternate dashboard endpoint for accessing the key if you want to decrypt your data outside of Supabase.
+
+## Future possibilities
+
+Privacy is becoming one of the most important features in a modern product. Supabase's embrace of the pgsodium extension aims to make this simple. Some of the possibilities we are looking into are:
+
+- **End-to-end encryption**: give your users the ability to encrypt their personal data so even you, the developer cannot access it, using the libsodium [encrypted streams](https://doc.libsodium.org/secret-key_cryptography/secretstream) API that is exposed by pgsodium. After exchanging keys, parties can stream unlimited amounts of data from peer to peer without being intercepted by any party in between, including Supabase.
+- **Group encryption**: have you ever joined a group on Whatsapp and been frustrated that you can't read the previous messages? That's because group encryption is hard. We hope to make that easier using new algorithms like [signcryption](https://github.com/jedisct1/libsodium-signcryption) to support multi-party encrypted messages that can be easily encoded into a token format and use to support streaming encryption keys.
+- **Public Key Management:** Public Key Encryption can be hard, but pgsodium makes it easier by exposing all of the public key encryption functions that are supported by libsodium. Making and distributing key pairs is now easy, no need to run arcane GPG scripts or mess with SSL libraries. libsodium contains state of the art public key encryption, and by extension so does pgsodium. These features are available now on the Supabase platform and offer a lot of possibilities to unshackle developers from other confusing and inadequate solutions available today.
+
+### Using the Vault
+
+You'll see the Vault appear in the Dashboard over the next month. If you want to use Vault today, email growth@supabase.com and we'll enable it on your account. Vault is available for all customers (including the Free-tier).
+
+## More Launch Week 6
+
+- [Day 1: New Supabase Docs, built with Next.js](https://supabase.com/blog/new-supabase-docs-built-with-nextjs)
+- [Day 2: Supabase Storage v2: Image resizing and Smart CDN](https://supabase.com/blog/storage-image-resizing-smart-cdn)
+- [Day 3: Multi-factor Authentication via Row Level Security Enforcement](https://supabase.com/blog/mfa-auth-via-rls)
+- [Launch Week 6 Hackathon](https://supabase.com/blog/launch-week-6-hackathon)
+- [Who We Hire at Supabase](https://supabase.com/blog/who-we-hire)
+- [pg_crdt - an experimental CRDT extension for Postgres](https://supabase.com/blog/postgres-crdt)
diff --git a/apps/www/components/LaunchWeek/lw6_days.json b/apps/www/components/LaunchWeek/lw6_days.json
index 69f32b1d5e1..e961beefa62 100644
--- a/apps/www/components/LaunchWeek/lw6_days.json
+++ b/apps/www/components/LaunchWeek/lw6_days.json
@@ -87,8 +87,8 @@
]
},
{
- "title": "Day 5",
- "shipped": false,
+ "title": "Supabase Vault Release",
+ "shipped": true,
"date": "16 Dec 2022",
"description": "Vault Release",
"d": 5,
@@ -96,6 +96,19 @@
"youtube_id": "6bGQotxisoY",
"blogpost": "https://supabase.com/blog",
"docs": "https://supabase.com/docs",
- "steps": []
+ "steps": [
+ {
+ "title": "Vault Release",
+ "blog": "/blog/vault-now-in-beta",
+ "isNew": true,
+ "description": ""
+ },
+ {
+ "title": "Transparent Column Encryption",
+ "description": "Faster asset delivery, now even faster.",
+ "blog": "/blog/transparent-column-encryption-with-postgres",
+ "isNew": true
+ }
+ ]
}
]
diff --git a/apps/www/lib/authors.json b/apps/www/lib/authors.json
index cc37016e61d..1b2c394d052 100644
--- a/apps/www/lib/authors.json
+++ b/apps/www/lib/authors.json
@@ -2,7 +2,7 @@
{
"author_id": "angelico_de_los_reyes",
"author": "Angelico de los Reyes",
- "position": "",
+ "position": "Engineering",
"author_url": "https://github.com/dragarcia",
"author_image_url": "https://github.com/dragarcia.png"
},
diff --git a/apps/www/lib/mdx/mdxComponents.tsx b/apps/www/lib/mdx/mdxComponents.tsx
index e8b1e6dacf5..a54bee5c0ad 100644
--- a/apps/www/lib/mdx/mdxComponents.tsx
+++ b/apps/www/lib/mdx/mdxComponents.tsx
@@ -5,6 +5,7 @@ import ImageGrid from '~/components/ImageGrid'
import Quote from '~/components/Quote'
import Chart from '~/components/Charts/PGCharts'
import InlineCodeTag from '~/components/InlineCode'
+import { Badge } from 'ui'
// import all components used in blog articles here
// to do: move this into a helper/utils, it is used elsewhere
@@ -14,6 +15,7 @@ const ignoreClass = 'ignore-on-export'
export default function mdxComponents(type?: 'blog' | 'lp' | undefined) {
const components = {
CodeBlock,
+ Badge,
Quote,
Avatar,
PGChart: (props: any) => {
diff --git a/apps/www/lib/redirects.js b/apps/www/lib/redirects.js
index b0d03d05b66..fd7ee2335d9 100644
--- a/apps/www/lib/redirects.js
+++ b/apps/www/lib/redirects.js
@@ -1619,88 +1619,93 @@ module.exports = [
},
{
permanent: true,
- source: '/docs/guides/auth-twilio',
+ source: '/docs/guides/auth/auth-twilio',
destination: '/docs/guides/auth/phone-login/twilio',
},
{
permanent: true,
- source: '/docs/guides/auth/with-google',
- destination: '/docs/guides/auth/social-login/with-google',
+ source: '/docs/guides/auth/auth-vonage',
+ destination: '/docs/guides/auth/phone-login/vonage',
},
{
permanent: true,
- source: '/docs/guides/auth/with-facebook',
- destination: '/docs/guides/auth/social-login/with-facebook',
+ source: '/docs/guides/auth/auth-google',
+ destination: '/docs/guides/auth/social-login/auth-google',
},
{
permanent: true,
- source: '/docs/guides/auth/with-apple',
- destination: '/docs/guides/auth/social-login/with-apple',
+ source: '/docs/guides/auth/auth-facebook',
+ destination: '/docs/guides/auth/social-login/auth-facebook',
},
{
permanent: true,
- source: '/docs/guides/auth/with-azure',
- destination: '/docs/guides/auth/social-login/with-azure',
+ source: '/docs/guides/auth/auth-apple',
+ destination: '/docs/guides/auth/social-login/auth-apple',
},
{
permanent: true,
- source: '/docs/guides/auth/with-twitter',
- destination: '/docs/guides/auth/social-login/with-twitter',
+ source: '/docs/guides/auth/auth-azure',
+ destination: '/docs/guides/auth/social-login/auth-azure',
},
{
permanent: true,
- source: '/docs/guides/auth/with-github',
- destination: '/docs/guides/auth/social-login/with-github',
+ source: '/docs/guides/auth/auth-twitter',
+ destination: '/docs/guides/auth/social-login/auth-twitter',
},
{
permanent: true,
- source: '/docs/guides/auth/with-gitlab',
- destination: '/docs/guides/auth/social-login/with-gitlab',
+ source: '/docs/guides/auth/auth-github',
+ destination: '/docs/guides/auth/social-login/auth-github',
},
{
permanent: true,
- source: '/docs/guides/auth/with-bitbucket',
- destination: '/docs/guides/auth/social-login/with-bitbucket',
+ source: '/docs/guides/auth/auth-gitlab',
+ destination: '/docs/guides/auth/social-login/auth-gitlab',
},
{
permanent: true,
- source: '/docs/guides/auth/with-discord',
- destination: '/docs/guides/auth/social-login/with-discord',
+ source: '/docs/guides/auth/auth-bitbucket',
+ destination: '/docs/guides/auth/social-login/auth-bitbucket',
},
{
permanent: true,
- source: '/docs/guides/auth/with-keycloak',
- destination: '/docs/guides/auth/social-login/with-keycloak',
+ source: '/docs/guides/auth/auth-discord',
+ destination: '/docs/guides/auth/social-login/auth-discord',
},
{
permanent: true,
- source: '/docs/guides/auth/with-linkedin',
- destination: '/docs/guides/auth/social-login/with-linkedin',
+ source: '/docs/guides/auth/auth-keycloak',
+ destination: '/docs/guides/auth/social-login/auth-keycloak',
},
{
permanent: true,
- source: '/docs/guides/auth/with-notion',
- destination: '/docs/guides/auth/social-login/with-notion',
+ source: '/docs/guides/auth/auth-linkedin',
+ destination: '/docs/guides/auth/social-login/auth-linkedin',
},
{
permanent: true,
- source: '/docs/guides/auth/with-slack',
- destination: '/docs/guides/auth/social-login/with-slack',
+ source: '/docs/guides/auth/auth-notion',
+ destination: '/docs/guides/auth/social-login/auth-notion',
},
{
permanent: true,
- source: '/docs/guides/auth/with-spotify',
- destination: '/docs/guides/auth/social-login/with-spotify',
+ source: '/docs/guides/auth/auth-slack',
+ destination: '/docs/guides/auth/social-login/auth-slack',
},
{
permanent: true,
- source: '/docs/guides/auth/with-twitch',
- destination: '/docs/guides/auth/social-login/with-twitch',
+ source: '/docs/guides/auth/auth-spotify',
+ destination: '/docs/guides/auth/social-login/auth-spotify',
},
{
permanent: true,
- source: '/docs/guides/auth/with-workos',
- destination: '/docs/guides/auth/social-login/with-workos',
+ source: '/docs/guides/auth/auth-twitch',
+ destination: '/docs/guides/auth/social-login/auth-twitch',
+ },
+ {
+ permanent: true,
+ source: '/docs/guides/auth/auth-workos',
+ destination: '/docs/guides/auth/social-login/auth-workos',
},
{
permanent: true,
diff --git a/apps/www/pages/edge-functions/edge-functions.tsx b/apps/www/pages/edge-functions/edge-functions.tsx
index a1d9cd65678..c572c51526d 100644
--- a/apps/www/pages/edge-functions/edge-functions.tsx
+++ b/apps/www/pages/edge-functions/edge-functions.tsx
@@ -223,20 +223,17 @@ import { Customer } from 'types'
serve(async (req) => {
try {
- // create a supabase client
+ // create a supabase client with Auth context of the user that called the function
const supabaseClient = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
- Deno.env.get('SUPABASE_ANON_KEY') ?? ''
+ Deno.env.get('SUPABASE_ANON_KEY') ?? '',
+ { global: { headers: { Authorization: req.headers.get('Authorization')! } } }
)
// create a stripe client
const stripe = Stripe(Deno.env.get('STRIPE_SECRET_KEY'))
- // Get the authorization header from the request.
- const authHeader = req.headers.get('Authorization').replace("Bearer ","")
- // Client now respects auth policies for this user
- supabaseClient.auth.setAuth(authHeader)
- // set the user profile
- const user = supabase.auth.user()
+ // get the current logged in user
+ const {data: { user },} = supabase.auth.getUser()
// Retrieve user metadata that only the user is allowed to select
const { data, error } = await supabaseClient
diff --git a/apps/www/pages/launch-week/index.tsx b/apps/www/pages/launch-week/index.tsx
index f702c333773..225de69fcb0 100644
--- a/apps/www/pages/launch-week/index.tsx
+++ b/apps/www/pages/launch-week/index.tsx
@@ -38,7 +38,7 @@ export default function launchweek() {
const { isDarkMode } = useTheme()
const title = 'Launch Week 6'
const description = 'Supabase Launch Week 6 | 12-18 Dec 2022'
- const liveDay = 'Thursday'
+ const liveDay = 'Friday'
const [supabase] = useState(() =>
createClient(process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!)
@@ -130,14 +130,16 @@ export default function launchweek() {
diff --git a/apps/www/public/images/blog/launch-week-6/crdt/og-pg-crdt.png b/apps/www/public/images/blog/launch-week-6/crdt/og-pg-crdt.png
new file mode 100644
index 00000000000..b8f6b998f71
Binary files /dev/null and b/apps/www/public/images/blog/launch-week-6/crdt/og-pg-crdt.png differ
diff --git a/apps/www/public/images/blog/launch-week-6/custom-domains/custom-subdomain.png b/apps/www/public/images/blog/launch-week-6/custom-domains/custom-subdomain.png
new file mode 100644
index 00000000000..53e830a9730
Binary files /dev/null and b/apps/www/public/images/blog/launch-week-6/custom-domains/custom-subdomain.png differ
diff --git a/apps/www/public/images/blog/launch-week-6/custom-domains/og-custom-domains.png b/apps/www/public/images/blog/launch-week-6/custom-domains/og-custom-domains.png
new file mode 100644
index 00000000000..63b14d9b0fd
Binary files /dev/null and b/apps/www/public/images/blog/launch-week-6/custom-domains/og-custom-domains.png differ
diff --git a/apps/www/public/images/blog/launch-week-6/pggraphql/og-pg-graphql.png b/apps/www/public/images/blog/launch-week-6/pggraphql/og-pg-graphql.png
new file mode 100644
index 00000000000..5fbb76ce70d
Binary files /dev/null and b/apps/www/public/images/blog/launch-week-6/pggraphql/og-pg-graphql.png differ
diff --git a/apps/www/public/images/blog/launch-week-6/pitr/og-pitr.png b/apps/www/public/images/blog/launch-week-6/pitr/og-pitr.png
new file mode 100644
index 00000000000..82280012323
Binary files /dev/null and b/apps/www/public/images/blog/launch-week-6/pitr/og-pitr.png differ
diff --git a/apps/www/public/images/blog/launch-week-6/pitr/pitr-date-selection.png b/apps/www/public/images/blog/launch-week-6/pitr/pitr-date-selection.png
new file mode 100644
index 00000000000..6ce491d380f
Binary files /dev/null and b/apps/www/public/images/blog/launch-week-6/pitr/pitr-date-selection.png differ
diff --git a/apps/www/public/images/blog/launch-week-6/pitr/pitr-overview.png b/apps/www/public/images/blog/launch-week-6/pitr/pitr-overview.png
new file mode 100644
index 00000000000..be1ec28f7e4
Binary files /dev/null and b/apps/www/public/images/blog/launch-week-6/pitr/pitr-overview.png differ
diff --git a/apps/www/public/images/blog/launch-week-6/vault/og-vault.png b/apps/www/public/images/blog/launch-week-6/vault/og-vault.png
new file mode 100644
index 00000000000..71ff756fef8
Binary files /dev/null and b/apps/www/public/images/blog/launch-week-6/vault/og-vault.png differ
diff --git a/apps/www/public/images/blog/launch-week-6/vault/vault-decrypted-data.png b/apps/www/public/images/blog/launch-week-6/vault/vault-decrypted-data.png
new file mode 100644
index 00000000000..e802f9d1ef3
Binary files /dev/null and b/apps/www/public/images/blog/launch-week-6/vault/vault-decrypted-data.png differ
diff --git a/apps/www/public/images/blog/launch-week-6/vault/vault-encrypted-data.png b/apps/www/public/images/blog/launch-week-6/vault/vault-encrypted-data.png
new file mode 100644
index 00000000000..631536c56fa
Binary files /dev/null and b/apps/www/public/images/blog/launch-week-6/vault/vault-encrypted-data.png differ
diff --git a/apps/www/public/images/blog/launch-week-6/vault/vault-encrypting-columns.png b/apps/www/public/images/blog/launch-week-6/vault/vault-encrypting-columns.png
new file mode 100644
index 00000000000..2a2c487eaa7
Binary files /dev/null and b/apps/www/public/images/blog/launch-week-6/vault/vault-encrypting-columns.png differ
diff --git a/apps/www/public/images/blog/launch-week-6/vault/vault-hello-compressed.mp4 b/apps/www/public/images/blog/launch-week-6/vault/vault-hello-compressed.mp4
new file mode 100644
index 00000000000..48395586435
Binary files /dev/null and b/apps/www/public/images/blog/launch-week-6/vault/vault-hello-compressed.mp4 differ
diff --git a/apps/www/public/images/blog/launch-week-6/wrap-up/og-wrap-up.png b/apps/www/public/images/blog/launch-week-6/wrap-up/og-wrap-up.png
new file mode 100644
index 00000000000..0137d0d395e
Binary files /dev/null and b/apps/www/public/images/blog/launch-week-6/wrap-up/og-wrap-up.png differ
diff --git a/apps/www/public/images/launchweek/PITR-visual-hover-light.svg b/apps/www/public/images/launchweek/PITR-visual-hover-light.svg
new file mode 100644
index 00000000000..f556d075421
--- /dev/null
+++ b/apps/www/public/images/launchweek/PITR-visual-hover-light.svg
@@ -0,0 +1,93 @@
+
diff --git a/apps/www/public/images/launchweek/PITR-visual-hover.svg b/apps/www/public/images/launchweek/PITR-visual-hover.svg
new file mode 100644
index 00000000000..150bab53ec9
--- /dev/null
+++ b/apps/www/public/images/launchweek/PITR-visual-hover.svg
@@ -0,0 +1,93 @@
+
diff --git a/apps/www/public/images/launchweek/PITR-visual-light.svg b/apps/www/public/images/launchweek/PITR-visual-light.svg
new file mode 100644
index 00000000000..57a2ae898d8
--- /dev/null
+++ b/apps/www/public/images/launchweek/PITR-visual-light.svg
@@ -0,0 +1,93 @@
+
diff --git a/apps/www/public/images/launchweek/PITR-visual.svg b/apps/www/public/images/launchweek/PITR-visual.svg
new file mode 100644
index 00000000000..940aa100e38
--- /dev/null
+++ b/apps/www/public/images/launchweek/PITR-visual.svg
@@ -0,0 +1,93 @@
+
diff --git a/apps/www/public/images/launchweek/PgGraphql-visual-hover-light.svg b/apps/www/public/images/launchweek/PgGraphql-visual-hover-light.svg
new file mode 100644
index 00000000000..9623ead49c7
--- /dev/null
+++ b/apps/www/public/images/launchweek/PgGraphql-visual-hover-light.svg
@@ -0,0 +1,198 @@
+
diff --git a/apps/www/public/images/launchweek/PgGraphql-visual-hover.svg b/apps/www/public/images/launchweek/PgGraphql-visual-hover.svg
new file mode 100644
index 00000000000..cce40efe137
--- /dev/null
+++ b/apps/www/public/images/launchweek/PgGraphql-visual-hover.svg
@@ -0,0 +1,198 @@
+
diff --git a/apps/www/public/images/launchweek/PgGraphql-visual-light.svg b/apps/www/public/images/launchweek/PgGraphql-visual-light.svg
new file mode 100644
index 00000000000..41380ed6f42
--- /dev/null
+++ b/apps/www/public/images/launchweek/PgGraphql-visual-light.svg
@@ -0,0 +1,192 @@
+
diff --git a/apps/www/public/images/launchweek/PgGraphql-visual.svg b/apps/www/public/images/launchweek/PgGraphql-visual.svg
new file mode 100644
index 00000000000..19fde8c1d2a
--- /dev/null
+++ b/apps/www/public/images/launchweek/PgGraphql-visual.svg
@@ -0,0 +1,192 @@
+
diff --git a/apps/www/public/images/launchweek/PostgREST11-visual-hover-light.svg b/apps/www/public/images/launchweek/PostgREST11-visual-hover-light.svg
new file mode 100644
index 00000000000..b47c55bd292
--- /dev/null
+++ b/apps/www/public/images/launchweek/PostgREST11-visual-hover-light.svg
@@ -0,0 +1,129 @@
+
diff --git a/apps/www/public/images/launchweek/PostgREST11-visual-hover.svg b/apps/www/public/images/launchweek/PostgREST11-visual-hover.svg
new file mode 100644
index 00000000000..e3ee608cab1
--- /dev/null
+++ b/apps/www/public/images/launchweek/PostgREST11-visual-hover.svg
@@ -0,0 +1,130 @@
+
diff --git a/apps/www/public/images/launchweek/PostgREST11-visual-light.svg b/apps/www/public/images/launchweek/PostgREST11-visual-light.svg
new file mode 100644
index 00000000000..bb3e0a3ab6e
--- /dev/null
+++ b/apps/www/public/images/launchweek/PostgREST11-visual-light.svg
@@ -0,0 +1,116 @@
+
diff --git a/apps/www/public/images/launchweek/PostgREST11-visual.svg b/apps/www/public/images/launchweek/PostgREST11-visual.svg
new file mode 100644
index 00000000000..09c7207853e
--- /dev/null
+++ b/apps/www/public/images/launchweek/PostgREST11-visual.svg
@@ -0,0 +1,116 @@
+
diff --git a/apps/www/public/images/launchweek/custom-domains-visual-hover-light.svg b/apps/www/public/images/launchweek/custom-domains-visual-hover-light.svg
new file mode 100644
index 00000000000..0abf9dba341
--- /dev/null
+++ b/apps/www/public/images/launchweek/custom-domains-visual-hover-light.svg
@@ -0,0 +1,153 @@
+
diff --git a/apps/www/public/images/launchweek/custom-domains-visual-hover.svg b/apps/www/public/images/launchweek/custom-domains-visual-hover.svg
new file mode 100644
index 00000000000..723eadef22e
--- /dev/null
+++ b/apps/www/public/images/launchweek/custom-domains-visual-hover.svg
@@ -0,0 +1,161 @@
+
diff --git a/apps/www/public/images/launchweek/custom-domains-visual-light.svg b/apps/www/public/images/launchweek/custom-domains-visual-light.svg
new file mode 100644
index 00000000000..25909761937
--- /dev/null
+++ b/apps/www/public/images/launchweek/custom-domains-visual-light.svg
@@ -0,0 +1,153 @@
+
diff --git a/apps/www/public/images/launchweek/custom-domains-visual.svg b/apps/www/public/images/launchweek/custom-domains-visual.svg
new file mode 100644
index 00000000000..2786fa9792d
--- /dev/null
+++ b/apps/www/public/images/launchweek/custom-domains-visual.svg
@@ -0,0 +1,161 @@
+
diff --git a/apps/www/public/images/launchweek/outro-light.svg b/apps/www/public/images/launchweek/outro-light.svg
new file mode 100644
index 00000000000..3067fbbc5c2
--- /dev/null
+++ b/apps/www/public/images/launchweek/outro-light.svg
@@ -0,0 +1,9 @@
+
diff --git a/apps/www/public/images/launchweek/outro.svg b/apps/www/public/images/launchweek/outro.svg
new file mode 100644
index 00000000000..4a5f21eef42
--- /dev/null
+++ b/apps/www/public/images/launchweek/outro.svg
@@ -0,0 +1,9 @@
+
diff --git a/apps/www/public/images/launchweek/pg_crdt-visual-hover-light.svg b/apps/www/public/images/launchweek/pg_crdt-visual-hover-light.svg
new file mode 100644
index 00000000000..5223b45be17
--- /dev/null
+++ b/apps/www/public/images/launchweek/pg_crdt-visual-hover-light.svg
@@ -0,0 +1,182 @@
+
diff --git a/apps/www/public/images/launchweek/pg_crdt-visual-hover.svg b/apps/www/public/images/launchweek/pg_crdt-visual-hover.svg
new file mode 100644
index 00000000000..ae75a367b58
--- /dev/null
+++ b/apps/www/public/images/launchweek/pg_crdt-visual-hover.svg
@@ -0,0 +1,182 @@
+
diff --git a/apps/www/public/images/launchweek/pg_crdt-visual-light.svg b/apps/www/public/images/launchweek/pg_crdt-visual-light.svg
new file mode 100644
index 00000000000..05fa238e4bd
--- /dev/null
+++ b/apps/www/public/images/launchweek/pg_crdt-visual-light.svg
@@ -0,0 +1,182 @@
+
diff --git a/apps/www/public/images/launchweek/pg_crdt-visual.svg b/apps/www/public/images/launchweek/pg_crdt-visual.svg
new file mode 100644
index 00000000000..80c6ffe9542
--- /dev/null
+++ b/apps/www/public/images/launchweek/pg_crdt-visual.svg
@@ -0,0 +1,182 @@
+
diff --git a/apps/www/public/images/launchweek/postgres-visual-hover-light.svg b/apps/www/public/images/launchweek/postgres-visual-hover-light.svg
new file mode 100644
index 00000000000..95f4b7bd656
--- /dev/null
+++ b/apps/www/public/images/launchweek/postgres-visual-hover-light.svg
@@ -0,0 +1,84 @@
+
diff --git a/apps/www/public/images/launchweek/postgres-visual-hover.svg b/apps/www/public/images/launchweek/postgres-visual-hover.svg
new file mode 100644
index 00000000000..9f004fd8c84
--- /dev/null
+++ b/apps/www/public/images/launchweek/postgres-visual-hover.svg
@@ -0,0 +1,84 @@
+
diff --git a/apps/www/public/images/launchweek/postgres-visual-light.svg b/apps/www/public/images/launchweek/postgres-visual-light.svg
new file mode 100644
index 00000000000..fd683f199eb
--- /dev/null
+++ b/apps/www/public/images/launchweek/postgres-visual-light.svg
@@ -0,0 +1,84 @@
+
diff --git a/apps/www/public/images/launchweek/postgres-visual.svg b/apps/www/public/images/launchweek/postgres-visual.svg
new file mode 100644
index 00000000000..a5f4550269e
--- /dev/null
+++ b/apps/www/public/images/launchweek/postgres-visual.svg
@@ -0,0 +1,84 @@
+
diff --git a/apps/www/public/rss.xml b/apps/www/public/rss.xml
index 8d937a7f7fb..215ba2e41d8 100644
--- a/apps/www/public/rss.xml
+++ b/apps/www/public/rss.xml
@@ -42,18 +42,25 @@
MFA Auth with enforcement via RLSTue, 13 Dec 2022 16:04:00 +0000
+
+ https://supabase.com/blog/mfa-auth-via-rls
+ Multi-factor Authentication via Row Level Security Enforcement
+ https://supabase.com/blog/mfa-auth-via-rls
+ MFA Auth with enforcement via RLS
+ Tue, 13 Dec 2022 23:11:00 +0000
+https://supabase.com/blog/storage-image-resizing-smart-cdnSupabase Storage v2: Image resizing and Smart CDN
https://supabase.com/blog/storage-image-resizing-smart-cdn
We're introducing new features for Supabase Storage: Image resizing and a Smart CDN.
- Mon, 12 Dec 2022 16:04:00 +0000
+ Mon, 12 Dec 2022 05:05:00 +0000https://supabase.com/blog/new-supabase-docs-built-with-nextjsNew Supabase Docs, built with Next.js
https://supabase.com/blog/new-supabase-docs-built-with-nextjs
- We've redesignd our Docs and migrated to Next.js
+ We've redesigned our Docs and migrated to Next.jsSun, 11 Dec 2022 16:04:00 +0000
@@ -61,973 +68,973 @@
pg_crdt - an experimental CRDT extension for Postgres
https://supabase.com/blog/postgres-crdt
Embedding Yjs and Automerge into Postgres for collaborative applications.
- Fri, 09 Dec 2022 16:04:00 +0000
+ Fri, 09 Dec 2022 05:05:00 +0000https://supabase.com/blog/who-we-hireWho We Hire at Supabase
https://supabase.com/blog/who-we-hire
Traits we look for to maintain a culture of shipping fast and often
- Thu, 08 Dec 2022 16:04:00 +0000
+ Thu, 08 Dec 2022 05:05:00 +0000https://supabase.com/blog/launch-week-6-hackathonLaunch Week 6 Hackathon
https://supabase.com/blog/launch-week-6-hackathon
Build an Open Source Project, Win $1500 and the Supabase Darkmode Keyboard
- Thu, 08 Dec 2022 16:04:00 +0000
+ Thu, 08 Dec 2022 05:05:00 +0000https://supabase.com/blog/supabase-beta-november-2022Supabase Beta November 2022
https://supabase.com/blog/supabase-beta-november-2022
We are preparing everything for Launch Week 6, but we still had time to ship some goodies this month!
- Tue, 06 Dec 2022 16:04:00 +0000
+ Tue, 06 Dec 2022 05:05:00 +0000https://supabase.com/blog/the-supabase-content-stormThe Supabase Content Storm
https://supabase.com/blog/the-supabase-content-storm
We worked with +30 content creators to drop a mountain of content simultaneously.
- Mon, 05 Dec 2022 16:04:00 +0000
+ Mon, 05 Dec 2022 05:05:00 +0000https://supabase.com/blog/transparent-column-encryption-with-postgresTransparent Column Encryption with Postgres
https://supabase.com/blog/transparent-column-encryption-with-postgres
Using pgsodium's Transparent Column Encryption to encrypt data and provide your users with row-level encryption.
- Wed, 30 Nov 2022 16:04:00 +0000
+ Wed, 30 Nov 2022 05:05:00 +0000https://supabase.com/blog/sql-or-nosql-both-with-postgresqlSQL or NoSQL? Why not use both (with PostgreSQL)?
https://supabase.com/blog/sql-or-nosql-both-with-postgresql
How to turn Postgres into an easy-to-use NoSQL database that retains all the power of SQL
- Wed, 23 Nov 2022 16:04:00 +0000
+ Wed, 23 Nov 2022 05:05:00 +0000https://supabase.com/blog/flutter-authentication-and-authorization-with-rlsFlutter Authentication and Authorization with RLS
https://supabase.com/blog/flutter-authentication-and-authorization-with-rls
Learn how you can secure your Flutter app using Supabase Row Level Security.
- Mon, 21 Nov 2022 16:04:00 +0000
+ Mon, 21 Nov 2022 05:05:00 +0000https://supabase.com/blog/fetching-and-caching-supabase-data-in-next-js-server-componentsFetching and caching Supabase data in Next.js 13 Server Components
https://supabase.com/blog/fetching-and-caching-supabase-data-in-next-js-server-components
Next.js 13 introduces new data fetching and caching methods to enable React Server Components and Suspense.
- Wed, 16 Nov 2022 16:04:00 +0000
+ Wed, 16 Nov 2022 05:05:00 +0000https://supabase.com/blog/authentication-in-ionic-angularAuthentication in Ionic Angular with Supabase
https://supabase.com/blog/authentication-in-ionic-angular
Learn how to build an Ionic Angular app with authentication, Row Level Security, and Magic Link auth.
- Mon, 07 Nov 2022 16:04:00 +0000
+ Mon, 07 Nov 2022 05:05:00 +0000https://supabase.com/blog/supabase-beta-update-october-2022Supabase Beta October 2022
https://supabase.com/blog/supabase-beta-update-october-2022
New SDKs, quickstarts, Functions tricks, and more. But, more importantly, Launch Week 6️ has a date!
- Tue, 01 Nov 2022 16:04:00 +0000
+ Tue, 01 Nov 2022 04:04:00 +0000https://supabase.com/blog/postgresql-commitfestWhat is PostgreSQL commitfest and how to contribute
https://supabase.com/blog/postgresql-commitfest
A time-tested method for contributing to the core Postgres code
- Wed, 26 Oct 2022 16:04:00 +0000
+ Wed, 26 Oct 2022 04:04:00 +0000https://supabase.com/blog/supabase-flutter-sdk-v1-releasedsupabase-flutter v1 Released
https://supabase.com/blog/supabase-flutter-sdk-v1-released
We've released supabase-flutter v1. More intuitive way of accessing Supabase from your Flutter application.
- Thu, 20 Oct 2022 16:04:00 +0000
+ Thu, 20 Oct 2022 04:04:00 +0000https://supabase.com/blog/supabase-js-v2-releasedsupabase-js v2 Released
https://supabase.com/blog/supabase-js-v2-released
We've released supabase-js v2. Updated examples, quickstarts, and an improved experience.
- Wed, 19 Oct 2022 16:04:00 +0000
+ Wed, 19 Oct 2022 04:04:00 +0000https://supabase.com/blog/postgres-full-text-search-vs-the-restPostgres Full Text Search vs the rest
https://supabase.com/blog/postgres-full-text-search-vs-the-rest
Comparing one of the most popular Postgres features against alternatives
- Thu, 13 Oct 2022 16:04:00 +0000
+ Thu, 13 Oct 2022 04:04:00 +0000https://supabase.com/blog/supabase-beta-update-september-2022Supabase Beta September 2022
https://supabase.com/blog/supabase-beta-update-september-2022
We were too focused on clearing out the backlog so we didn't ship anything new last month... or did we?!
- Tue, 04 Oct 2022 16:04:00 +0000
+ Tue, 04 Oct 2022 04:04:00 +0000https://supabase.com/blog/postgres-wasmPostgres WASM by Snaplet and Supabase
https://supabase.com/blog/postgres-wasm
We're open sourcing postgres-wasm, a PostgresQL server that runs inside a browser, with our friends at Snaplet.
- Sun, 02 Oct 2022 16:04:00 +0000
+ Sun, 02 Oct 2022 04:04:00 +0000https://supabase.com/blog/choosing-a-postgres-primary-keyChoosing a Postgres Primary Key
https://supabase.com/blog/choosing-a-postgres-primary-key
Turns out the question of which identifier to use as a Primary Key is complicated -- we're going to dive into some of the complexity and inherent trade-offs, and figure things out
- Wed, 07 Sep 2022 16:04:00 +0000
+ Wed, 07 Sep 2022 04:04:00 +0000https://supabase.com/blog/supabase-beta-update-august-2022Supabase Beta August 2022
https://supabase.com/blog/supabase-beta-update-august-2022
Launch Week Special. See everything we shipped, plus winners of the Hackathon and the extended Community Highlights
- Tue, 06 Sep 2022 16:04:00 +0000
+ Tue, 06 Sep 2022 04:04:00 +0000https://supabase.com/blog/launch-week-5-hackathon-winnersLaunch Week 5 Hackathon Winners
https://supabase.com/blog/launch-week-5-hackathon-winners
Announcing the winners of the Launch Week 5 Hackathon!
- Wed, 24 Aug 2022 16:04:00 +0000
+ Wed, 24 Aug 2022 04:04:00 +0000https://supabase.com/blog/building-a-realtime-trello-board-with-supabase-and-angularBuilding a Realtime Trello Board with Supabase and Angular
https://supabase.com/blog/building-a-realtime-trello-board-with-supabase-and-angular
Go beyond the hello world example with this real world project.
- Tue, 23 Aug 2022 16:04:00 +0000
+ Tue, 23 Aug 2022 04:04:00 +0000https://supabase.com/blog/supabase-vaultSupabase Vault
https://supabase.com/blog/supabase-vault
Today we're announcing Vault, a Postgres extension for managing secrets and encryption inside your database.
- Thu, 18 Aug 2022 16:04:00 +0000
+ Thu, 18 Aug 2022 04:04:00 +0000https://supabase.com/blog/postgrest-v10PostgREST v10: EXPLAIN and Improved Relationship Detection
https://supabase.com/blog/postgrest-v10
Today, PostgREST 10 was released. Let's take a look at some of the new features that go hand in hand with supabase-js v2.
- Thu, 18 Aug 2022 16:04:00 +0000
+ Thu, 18 Aug 2022 04:04:00 +0000https://supabase.com/blog/pg-jsonschema-a-postgres-extension-for-json-validationpg_jsonschema: JSON Schema support for Postgres
https://supabase.com/blog/pg-jsonschema-a-postgres-extension-for-json-validation
Today we're releasing pg_jsonschema, a Postgres extension for JSON validation.
- Thu, 18 Aug 2022 16:04:00 +0000
+ Thu, 18 Aug 2022 04:04:00 +0000https://supabase.com/blog/launch-week-5-one-more-thingOne more thing
https://supabase.com/blog/launch-week-5-one-more-thing
Let's be honest, it's never just one more thing.
- Thu, 18 Aug 2022 16:04:00 +0000
+ Thu, 18 Aug 2022 04:04:00 +0000https://supabase.com/blog/launch-week-5-community-dayCommunity Day
https://supabase.com/blog/launch-week-5-community-day
Wrapping up Launch Week 5 with contributors, partners, and friends.
- Thu, 18 Aug 2022 16:04:00 +0000
+ Thu, 18 Aug 2022 04:04:00 +0000https://supabase.com/blog/supabase-realtime-multiplayer-general-availabilityRealtime: Multiplayer Edition
https://supabase.com/blog/supabase-realtime-multiplayer-general-availability
Announcing the general availability of Realtime's Broadcast and Presence.
- Wed, 17 Aug 2022 16:04:00 +0000
+ Wed, 17 Aug 2022 04:04:00 +0000https://supabase.com/blog/supabase-soc2Supabase is SOC2 compliant
https://supabase.com/blog/supabase-soc2
Supabase is now SOC2 compliant. Learn how we got here and what it means for our customers.
- Tue, 16 Aug 2022 16:04:00 +0000
+ Tue, 16 Aug 2022 04:04:00 +0000https://supabase.com/blog/supabase-js-v2supabase-js v2
https://supabase.com/blog/supabase-js-v2
A look at supabase-js v2, which brings type support and focuses on quality-of-life improvements for developers.
- Mon, 15 Aug 2022 16:04:00 +0000
+ Mon, 15 Aug 2022 04:04:00 +0000https://supabase.com/blog/supabase-cli-v1-and-admin-api-betaSupabase CLI v1 and Management API Beta
https://supabase.com/blog/supabase-cli-v1-and-admin-api-beta
We are moving Supabase CLI v1 out of beta, and releasing Management API beta.
- Sun, 14 Aug 2022 16:04:00 +0000
+ Sun, 14 Aug 2022 04:04:00 +0000https://supabase.com/blog/supabase-series-bSupabase Series B
https://supabase.com/blog/supabase-series-b
Supabase raised $80M in May, bringing our total funding to $116M.
- Thu, 11 Aug 2022 16:04:00 +0000
+ Thu, 11 Aug 2022 04:04:00 +0000https://supabase.com/blog/launch-week-5-hackathonLaunch Week 5 Hackathon
https://supabase.com/blog/launch-week-5-hackathon
Build to win $1500 - Friday 12th to Monday 21st August 2022
- Tue, 09 Aug 2022 16:04:00 +0000
+ Tue, 09 Aug 2022 04:04:00 +0000https://supabase.com/blog/slack-consolidate-slackbot-to-consolidate-messagesSlack Consolidate: a slackbot built with Python and Supabase
https://supabase.com/blog/slack-consolidate-slackbot-to-consolidate-messages
A slackbot to consolidate messages from different channels using Supabase, Slack SDK and Python
- Mon, 08 Aug 2022 16:04:00 +0000
+ Mon, 08 Aug 2022 04:04:00 +0000https://supabase.com/blog/supabase-beta-update-july-2022Supabase Beta July 2022
https://supabase.com/blog/supabase-beta-update-july-2022
Launch Week Golden Tickets, Flutter SDK 1.0 Developer Preview and more...
- Tue, 02 Aug 2022 16:04:00 +0000
+ Tue, 02 Aug 2022 04:04:00 +0000https://supabase.com/blog/supabase-flutter-sdk-1-developer-previewSupabase Flutter SDK 1.0 Developer Preview
https://supabase.com/blog/supabase-flutter-sdk-1-developer-preview
Supabase Flutter SDK is getting a major update and we need your help making it better.
- Mon, 01 Aug 2022 16:04:00 +0000
+ Mon, 01 Aug 2022 04:04:00 +0000https://supabase.com/blog/seen-by-in-postgresqlImplementing "seen by" functionality with Postgres
https://supabase.com/blog/seen-by-in-postgresql
Different approaches for tracking visitor counts with PostgreSQL.
- Sun, 17 Jul 2022 16:04:00 +0000
+ Sun, 17 Jul 2022 04:04:00 +0000https://supabase.com/blog/supabase-auth-helpers-with-sveltekit-supportRevamped Auth Helpers for Supabase (with SvelteKit support)
https://supabase.com/blog/supabase-auth-helpers-with-sveltekit-support
Supabase Auth Helpers now have improved developer experience, Sveltekit support, and more.
- Tue, 12 Jul 2022 16:04:00 +0000
+ Tue, 12 Jul 2022 04:04:00 +0000https://supabase.com/blog/beta-update-june-2022Supabase Beta June 2022
https://supabase.com/blog/beta-update-june-2022
Auth Helpers, Unlimited Free Projects, CLI and more...
- Tue, 05 Jul 2022 16:04:00 +0000
+ Tue, 05 Jul 2022 04:04:00 +0000https://supabase.com/blog/flutter-tutorial-building-a-chat-appFlutter Tutorial: building a Flutter chat app
https://supabase.com/blog/flutter-tutorial-building-a-chat-app
Learn how to build a Flutter chat app with open source and scalable backend (inc. auth, realtime, database, and more).
- Wed, 29 Jun 2022 16:04:00 +0000
+ Wed, 29 Jun 2022 04:04:00 +0000https://supabase.com/blog/visualizing-supabase-data-using-metabaseVisualizing Supabase Data using Metabase
https://supabase.com/blog/visualizing-supabase-data-using-metabase
How to create different kinds of charts out of data stored in Supabase using Metabase.
- Tue, 28 Jun 2022 16:04:00 +0000
+ Tue, 28 Jun 2022 04:04:00 +0000https://supabase.com/blog/partial-postgresql-data-dumps-with-rlsPartial data dumps using Postgres Row Level Security
https://supabase.com/blog/partial-postgresql-data-dumps-with-rls
Using RLS to create seed files for local PostgreSQL testing.
- Mon, 27 Jun 2022 16:04:00 +0000
+ Mon, 27 Jun 2022 04:04:00 +0000https://supabase.com/blog/loading-data-supabase-pythonPython data loading with Supabase
https://supabase.com/blog/loading-data-supabase-python
An example of how to load data into Supabase using supabase-py
- Thu, 16 Jun 2022 16:04:00 +0000
+ Thu, 16 Jun 2022 04:04:00 +0000https://supabase.com/blog/beta-update-may-2022Supabase Beta May 2022
https://supabase.com/blog/beta-update-may-2022
Product and community updates including wildcard auth redirects, edge functions with webhooks, and Prometheus endpoints for everybody.
- Tue, 31 May 2022 16:04:00 +0000
+ Tue, 31 May 2022 04:04:00 +0000https://supabase.com/blog/how-supabase-accelerates-development-of-all-pull-togetherHow Mike Lyndon is using Supabase to accelerate development of AllPullTogether
https://supabase.com/blog/how-supabase-accelerates-development-of-all-pull-together
Mike Lyndon is learning web development as he builds AllPullTogether, and Supabase is helping him accelerate what he can accomplish.
- Wed, 25 May 2022 16:04:00 +0000
+ Wed, 25 May 2022 04:04:00 +0000https://supabase.com/blog/partner-gallery-works-with-supabaseWorks With Supabase - announcing our Partner Gallery
https://supabase.com/blog/partner-gallery-works-with-supabase
Introducing our Partner Gallery - open source and made with Supabase.
- Tue, 19 Apr 2022 16:04:00 +0000
+ Tue, 19 Apr 2022 04:04:00 +0000https://supabase.com/blog/bring-the-func-hackathon-winnersBring the Func Hackathon Winners 2022
https://supabase.com/blog/bring-the-func-hackathon-winners
Celebrating many amazing OSS Hackathon projects using GraphQL and Edge Functions.
- Sun, 17 Apr 2022 16:04:00 +0000
+ Sun, 17 Apr 2022 04:04:00 +0000https://supabase.com/blog/beta-update-march-2022Supabase Beta March 2022
https://supabase.com/blog/beta-update-march-2022
Functions, GraphQL, and much more.
- Thu, 14 Apr 2022 16:04:00 +0000
+ Thu, 14 Apr 2022 04:04:00 +0000https://supabase.com/blog/supabrewSupabrew - Never Code Thirsty
https://supabase.com/blog/supabrew
A light and refreshing non-alcoholic beer for devs.
- Thu, 31 Mar 2022 16:04:00 +0000
+ Fri, 01 Apr 2022 04:04:00 +0000https://supabase.com/blog/supabase-realtime-with-multiplayer-featuresSupabase Realtime, with Multiplayer Features
https://supabase.com/blog/supabase-realtime-with-multiplayer-features
Today we're announced Realtime, with multiplayer features. Realtime enables broadcast, presence, and listening to database changes delivered over WebSockets.
- Thu, 31 Mar 2022 16:04:00 +0000
+ Fri, 01 Apr 2022 04:04:00 +0000https://supabase.com/blog/hackathon-bring-the-funcHackathon: Bring the Func(🕺)
https://supabase.com/blog/hackathon-bring-the-func
Build open-source projects with our latest features, win limited edition swag and plant a tree!
- Thu, 31 Mar 2022 16:04:00 +0000
+ Fri, 01 Apr 2022 04:04:00 +0000https://supabase.com/blog/supabase-edge-functionsEdge Functions are now available in Supabase
https://supabase.com/blog/supabase-edge-functions
Today we're launching Edge Functions. Edge Functions let you execute Typescript code close to your users, no matter where they're located.
- Wed, 30 Mar 2022 16:04:00 +0000
+ Wed, 30 Mar 2022 04:04:00 +0000https://supabase.com/blog/supabase-enterpriseIntroducing Supabase Enterprise
https://supabase.com/blog/supabase-enterprise
Today we are releasing Supabase Enterprise, a suite of features to scale your project.
- Tue, 29 Mar 2022 16:04:00 +0000
+ Tue, 29 Mar 2022 04:04:00 +0000https://supabase.com/blog/graphql-now-availableGraphQL is now available in Supabase
https://supabase.com/blog/graphql-now-available
GraphQL support is now in general availability on the Supabase platform via our open source PostgreSQL extension, pg_graphql (beta).
- Mon, 28 Mar 2022 16:04:00 +0000
+ Mon, 28 Mar 2022 04:04:00 +0000https://supabase.com/blog/community-day-lw4Community Day
https://supabase.com/blog/community-day-lw4
Kicking off Launch Week 4 with contributors, partners, and friends.
- Sun, 27 Mar 2022 16:04:00 +0000
+ Sun, 27 Mar 2022 04:04:00 +0000https://supabase.com/blog/supabase-launch-week-fourSupabase Launch Week 4
https://supabase.com/blog/supabase-launch-week-four
Launch Week 4: One new feature every day for an entire week. Starting Monday 28th March.
- Thu, 24 Mar 2022 16:04:00 +0000
+ Thu, 24 Mar 2022 04:04:00 +0000https://supabase.com/blog/should-i-open-source-my-companyShould I Open Source my Company?
https://supabase.com/blog/should-i-open-source-my-company
The unexpected upsides of building in public
- Thu, 24 Mar 2022 16:04:00 +0000
+ Thu, 24 Mar 2022 04:04:00 +0000https://supabase.com/blog/auditPostgres Auditing in 150 lines of SQL
https://supabase.com/blog/audit
PostgreSQL has a robust set of features which we can leverage to create a generic auditing solution in 150 lines of SQL.
- Mon, 07 Mar 2022 16:04:00 +0000
+ Mon, 07 Mar 2022 05:05:00 +0000https://supabase.com/blog/supabase-beta-january-2022Supabase Beta January 2022
https://supabase.com/blog/supabase-beta-january-2022
New auth providers, SMS providers, and new videos.
- Mon, 21 Feb 2022 16:04:00 +0000
+ Mon, 21 Feb 2022 05:05:00 +0000https://supabase.com/blog/supabase-beta-december-2021Supabase Beta December 2021
https://supabase.com/blog/supabase-beta-december-2021
New crypto extension, Postgres videos, and a bunch of cool integrations.
- Wed, 19 Jan 2022 16:04:00 +0000
+ Wed, 19 Jan 2022 05:05:00 +0000https://supabase.com/blog/product-hunt-golden-kitty-awards-2021Golden Kitty Awards Ceremony Watch Party with Supabase
https://supabase.com/blog/product-hunt-golden-kitty-awards-2021
Hang out with us while watching the Product Hunt Golden Kitty Awards Ceremony
- Wed, 19 Jan 2022 16:04:00 +0000
+ Wed, 19 Jan 2022 05:05:00 +0000https://supabase.com/blog/holiday-hackdays-winners-2021Holiday Hackdays Winners 2021
https://supabase.com/blog/holiday-hackdays-winners-2021
Celebrating many amazing projects submitted to our Holiday Hackdays Hackathon.
- Thu, 16 Dec 2021 16:04:00 +0000
+ Thu, 16 Dec 2021 05:05:00 +0000https://supabase.com/blog/beta-november-2021-launch-week-recapSupabase Beta November 2021: Launch Week Recap
https://supabase.com/blog/beta-november-2021-launch-week-recap
We wrapped up November with Supabase's third Launch Week. Here's all the awesome stuff that got shipped ...
- Tue, 14 Dec 2021 16:04:00 +0000
+ Tue, 14 Dec 2021 05:05:00 +0000https://supabase.com/blog/supabase-holiday-hackdays-hackathonKicking off the Holiday Hackdays
https://supabase.com/blog/supabase-holiday-hackdays-hackathon
Build cool stuff and celebrate open-source software with us during the Holiday Hackdays!
- Thu, 02 Dec 2021 16:04:00 +0000
+ Thu, 02 Dec 2021 05:05:00 +0000https://supabase.com/blog/pg-graphqlpg_graphql: A GraphQL extension for PostgreSQL
https://supabase.com/blog/pg-graphql
GraphQL support is in development for PostgreSQL + Supabase.
- Thu, 02 Dec 2021 16:04:00 +0000
+ Thu, 02 Dec 2021 05:05:00 +0000https://supabase.com/blog/launch-week-three-friday-five-more-thingsFive more things
https://supabase.com/blog/launch-week-three-friday-five-more-things
It's never just one more thing!
- Thu, 02 Dec 2021 16:04:00 +0000
+ Thu, 02 Dec 2021 05:05:00 +0000https://supabase.com/blog/supabase-acquires-logflareSupabase acquires Logflare
https://supabase.com/blog/supabase-acquires-logflare
Today, we're ecstatic to announce that Logflare is joining Supabase.
- Wed, 01 Dec 2021 16:04:00 +0000
+ Wed, 01 Dec 2021 05:05:00 +0000https://supabase.com/blog/realtime-row-level-security-in-postgresqlRealtime Postgres RLS now available on Supabase
https://supabase.com/blog/realtime-row-level-security-in-postgresql
Realtime database changes are now broadcast to authenticated users, respecting the same PostgreSQL policies that you use for Row Level Security.
- Tue, 30 Nov 2021 16:04:00 +0000
+ Tue, 30 Nov 2021 05:05:00 +0000https://supabase.com/blog/supabase-studioSupabase Studio
https://supabase.com/blog/supabase-studio
The same Dashboard that you're using on our Platform is now available for local development and Self-Hosting.
- Mon, 29 Nov 2021 16:04:00 +0000
+ Mon, 29 Nov 2021 05:05:00 +0000https://supabase.com/blog/community-day-lw3Community Day
https://supabase.com/blog/community-day-lw3
Kicking off launch week by highlighting the communities around Supabase.
- Sun, 28 Nov 2021 16:04:00 +0000
+ Sun, 28 Nov 2021 05:05:00 +0000https://supabase.com/blog/whats-new-in-postgres-14New in PostgreSQL 14: What every developer should know
https://supabase.com/blog/whats-new-in-postgres-14
A quick look at some new features and functionality in PostgreSQL 14.
- Sat, 27 Nov 2021 16:04:00 +0000
+ Sat, 27 Nov 2021 05:05:00 +0000https://supabase.com/blog/postgrest-9PostgREST 9
https://supabase.com/blog/postgrest-9
New features and updates in PostgREST version 9.
- Fri, 26 Nov 2021 16:04:00 +0000
+ Fri, 26 Nov 2021 05:05:00 +0000https://supabase.com/blog/supabase-launch-week-the-trilogySupabase Launch Week III: Holiday Special
https://supabase.com/blog/supabase-launch-week-the-trilogy
Tis the season to be shipping.
- Thu, 25 Nov 2021 16:04:00 +0000
+ Thu, 25 Nov 2021 05:05:00 +0000https://supabase.com/blog/supabase-how-we-launchHow we launch at Supabase
https://supabase.com/blog/supabase-how-we-launch
The history and methodology of Supabase Launch Week.
- Thu, 25 Nov 2021 16:04:00 +0000
+ Thu, 25 Nov 2021 05:05:00 +0000https://supabase.com/blog/supabase-beta-october-2021Supabase Beta October 2021
https://supabase.com/blog/supabase-beta-october-2021
Three new Auth providers, multi-schema support, and we're gearing up for another Launch Week.
- Sat, 06 Nov 2021 16:04:00 +0000
+ Sat, 06 Nov 2021 04:04:00 +0000https://supabase.com/blog/supabase-series-aSupabase $30m Series A
https://supabase.com/blog/supabase-series-a
Supabase just raised $30M, bringing our total funding to $36M.
- Wed, 27 Oct 2021 16:04:00 +0000
+ Wed, 27 Oct 2021 04:04:00 +0000https://supabase.com/blog/replenysh-time-to-value-in-less-than-24-hoursReplenysh uses Supabase to implement OTP in less than 24-hours
https://supabase.com/blog/replenysh-time-to-value-in-less-than-24-hours
Learn how Replenysh uses Supabase to power the circular economy, redefining how brands interact with their customers and products.
- Mon, 18 Oct 2021 16:04:00 +0000
+ Mon, 18 Oct 2021 04:04:00 +0000https://supabase.com/blog/hacktoberfest-hackathon-winners-2021Hacktoberfest Hackathon Winners 2021
https://supabase.com/blog/hacktoberfest-hackathon-winners-2021
Celebrating many amazing projects submitted to our Hacktoberfest Hackathon.
- Wed, 13 Oct 2021 16:04:00 +0000
+ Wed, 13 Oct 2021 04:04:00 +0000https://supabase.com/blog/supabase-beta-sept-2021Supabase Beta Sept 2021
https://supabase.com/blog/supabase-beta-sept-2021
Hackathon, Aborting request, UI updates, and now Hiring.
- Sun, 03 Oct 2021 16:04:00 +0000
+ Sun, 03 Oct 2021 04:04:00 +0000https://supabase.com/blog/supabase-hacktoberfest-hackathon-2021Supabase Hacktoberfest Hackathon 2021
https://supabase.com/blog/supabase-hacktoberfest-hackathon-2021
We're running another Supabase Hackathon during Hacktoberfest!
- Mon, 27 Sep 2021 16:04:00 +0000
+ Mon, 27 Sep 2021 04:04:00 +0000https://supabase.com/blog/supabase-beta-august-2021Supabase Beta August 2021
https://supabase.com/blog/supabase-beta-august-2021
Fundraising, Realtime Security, custom SMS templates, and deployments in South Korea.
- Thu, 09 Sep 2021 16:04:00 +0000
+ Thu, 09 Sep 2021 04:04:00 +0000https://supabase.com/blog/supabase-beta-july-2021Supabase Beta July 2021
https://supabase.com/blog/supabase-beta-july-2021
Discord Logins, Vercel Integration, Full text search, and OAuth guides.
- Wed, 11 Aug 2021 16:04:00 +0000
+ Wed, 11 Aug 2021 04:04:00 +0000https://supabase.com/blog/hackathon-winnersOpen Source Hackathon Winners
https://supabase.com/blog/hackathon-winners
Let the medal ceremony begin for the best projects submitted during the Supabase Hackathon.
- Sun, 08 Aug 2021 16:04:00 +0000
+ Sun, 08 Aug 2021 04:04:00 +0000https://supabase.com/blog/supabase-swag-storeSupabase Swag Store
https://supabase.com/blog/supabase-swag-store
Today we are officially launching the Supabase Swag Store.
- Thu, 29 Jul 2021 16:04:00 +0000
+ Thu, 29 Jul 2021 04:04:00 +0000https://supabase.com/blog/supabase-functions-updatesUpdates for Supabase Functions
https://supabase.com/blog/supabase-functions-updates
The question on everyone's mind - are we launching Supabase Functions? Well, it's complicated.
- Thu, 29 Jul 2021 16:04:00 +0000
+ Thu, 29 Jul 2021 04:04:00 +0000https://supabase.com/blog/1-the-supabase-hackathonThe Supabase Hackathon
https://supabase.com/blog/1-the-supabase-hackathon
A whole week of Hacking for Fun and Prizes.
- Thu, 29 Jul 2021 16:04:00 +0000
+ Thu, 29 Jul 2021 04:04:00 +0000https://supabase.com/blog/supabase-reports-and-metricsSupabase Reports and Metrics
https://supabase.com/blog/supabase-reports-and-metrics
We're exposing a full set of metrics in your projects, so that you can build better (and faster) products for your users.
- Wed, 28 Jul 2021 16:04:00 +0000
+ Wed, 28 Jul 2021 04:04:00 +0000https://supabase.com/blog/supabase-auth-passwordless-sms-loginSupabase Auth v2: Phone Auth now available
https://supabase.com/blog/supabase-auth-passwordless-sms-login
Phone Auth is available today on all new and existing Supabase projects.
- Tue, 27 Jul 2021 16:04:00 +0000
+ Tue, 27 Jul 2021 04:04:00 +0000https://supabase.com/blog/mobbin-supabase-200000-usersMobbin uses Supabase to authenticate 200,000 users
https://supabase.com/blog/mobbin-supabase-200000-users
Learn how Mobbin migrated 200,000 users from Firebase for a better authentication experience.
- Tue, 27 Jul 2021 16:04:00 +0000
+ Tue, 27 Jul 2021 04:04:00 +0000https://supabase.com/blog/storage-betaSupabase Storage now in Beta
https://supabase.com/blog/storage-beta
Supabase Storage moves into Beta.
- Mon, 26 Jul 2021 16:04:00 +0000
+ Mon, 26 Jul 2021 04:04:00 +0000https://supabase.com/blog/spot-flutter-with-postgresSpot: a video sharing app built with Flutter
https://supabase.com/blog/spot-flutter-with-postgres
Spot is a geolocation-based video-sharing app with some social networking features.
- Mon, 26 Jul 2021 16:04:00 +0000
+ Mon, 26 Jul 2021 04:04:00 +0000https://supabase.com/blog/supabase-postgres-13Supabase is now on Postgres 13.3
https://supabase.com/blog/supabase-postgres-13
From today, new Supabase projects will be on a version of Supabase Postgres that runs on Postgres 13.3.
- Sun, 25 Jul 2021 16:04:00 +0000
+ Sun, 25 Jul 2021 04:04:00 +0000https://supabase.com/blog/supabase-community-daySupabase Community Day
https://supabase.com/blog/supabase-community-day
Community Day
- Sun, 25 Jul 2021 16:04:00 +0000
+ Sun, 25 Jul 2021 04:04:00 +0000https://supabase.com/blog/epsilon3-self-hostingEpsilon3 Self-Host Supabase To Revolutionize Space Operations
https://supabase.com/blog/epsilon3-self-hosting
Learn how the team at Epsilon3 use Supabase to help teams execute secure and reliable operations in an industry that project spend runs into the billions.
- Sun, 25 Jul 2021 16:04:00 +0000
+ Sun, 25 Jul 2021 04:04:00 +0000https://supabase.com/blog/supabase-launch-week-sqlSupabase Launch Week II: The SQL
https://supabase.com/blog/supabase-launch-week-sql
Five days of Supabase. Again.
- Wed, 21 Jul 2021 16:04:00 +0000
+ Wed, 21 Jul 2021 04:04:00 +0000https://supabase.com/blog/roles-postgres-hooksProtecting reserved roles with PostgreSQL Hooks
https://supabase.com/blog/roles-postgres-hooks
Using Postgres Hooks to protect functionality in your Postgres database.
- Thu, 01 Jul 2021 16:04:00 +0000
+ Thu, 01 Jul 2021 04:04:00 +0000https://supabase.com/blog/supabase-beta-june-2021Supabase Beta June 2021
https://supabase.com/blog/supabase-beta-june-2021
Discord Logins, Vercel Integration, Full text search, and OAuth guides.
- Tue, 01 Jun 2021 16:04:00 +0000
+ Tue, 01 Jun 2021 04:04:00 +0000https://supabase.com/blog/supabase-beta-may-2021Supabase Beta May 2021
https://supabase.com/blog/supabase-beta-may-2021
Apple & Twitter Logins, Supabase Grid, Go & Swift Libraries.
- Tue, 01 Jun 2021 16:04:00 +0000
+ Tue, 01 Jun 2021 04:04:00 +0000https://supabase.com/blog/supabase-beta-april-2021Supabase Beta April 2021
https://supabase.com/blog/supabase-beta-april-2021
Supabase "gardening" - stability, security, and community support.
- Tue, 04 May 2021 16:04:00 +0000
+ Tue, 04 May 2021 04:04:00 +0000https://supabase.com/blog/supabase-beta-march-2021Supabase Beta March 2021
https://supabase.com/blog/supabase-beta-march-2021
Launch week, Storage, Supabase CLI, Connection Pooling, Supabase UI, and Pricing.
- Mon, 05 Apr 2021 16:04:00 +0000
+ Mon, 05 Apr 2021 04:04:00 +0000https://supabase.com/blog/supabase-workflowsWorkflows are coming to Supabase
https://supabase.com/blog/supabase-workflows
Functions are great, but you know what's better?
- Thu, 01 Apr 2021 16:04:00 +0000
+ Thu, 01 Apr 2021 04:04:00 +0000https://supabase.com/blog/supabase-pgbouncerPgBouncer is now available in Supabase
https://supabase.com/blog/supabase-pgbouncer
Better support for Serverless and Postgres.
- Thu, 01 Apr 2021 16:04:00 +0000
+ Thu, 01 Apr 2021 04:04:00 +0000https://supabase.com/blog/supabase-dot-comSupabase Dot Com
https://supabase.com/blog/supabase-dot-com
The Supabase Domain name is changing.
- Thu, 01 Apr 2021 16:04:00 +0000
+ Thu, 01 Apr 2021 04:04:00 +0000https://supabase.com/blog/supabase-nft-marketplaceSupabase Launches NFT Marketplace
https://supabase.com/blog/supabase-nft-marketplace
A fully encrypted NFT platform to protect and transact your digital assets
- Wed, 31 Mar 2021 16:04:00 +0000
+ Thu, 01 Apr 2021 04:04:00 +0000https://supabase.com/blog/supabase-cliSupabase CLI
https://supabase.com/blog/supabase-cli
Local development, database migrations, and self-hosting.
- Tue, 30 Mar 2021 16:04:00 +0000
+ Wed, 31 Mar 2021 04:04:00 +0000https://supabase.com/blog/supabase-storageStorage is now available in Supabase
https://supabase.com/blog/supabase-storage
Launching Supabase Storage and how you can use it in your apps
- Mon, 29 Mar 2021 16:04:00 +0000
+ Tue, 30 Mar 2021 04:04:00 +0000https://supabase.com/blog/pricingSupabase Beta Pricing
https://supabase.com/blog/pricing
Supabase launches Beta pricing structure
- Sun, 28 Mar 2021 16:04:00 +0000
+ Mon, 29 Mar 2021 04:04:00 +0000https://supabase.com/blog/launch-weekLaunch week
https://supabase.com/blog/launch-week
Five days of Supabase.
- Wed, 24 Mar 2021 16:04:00 +0000
+ Wed, 24 Mar 2021 04:04:00 +0000https://supabase.com/blog/angels-of-supabaseAngels of Supabase
https://supabase.com/blog/angels-of-supabase
Meet the investors of Supabase.
- Wed, 24 Mar 2021 16:04:00 +0000
+ Wed, 24 Mar 2021 04:04:00 +0000https://supabase.com/blog/In-The-LoopDevelopers stay up to date with intheloop.dev
https://supabase.com/blog/In-The-Loop
Learn why Kevin is building intheloop.dev with Supabase
- Sun, 21 Mar 2021 16:04:00 +0000
+ Mon, 22 Mar 2021 04:04:00 +0000https://supabase.com/blog/using-supabase-replitUsing Supabase in Replit
https://supabase.com/blog/using-supabase-replit
Free hosted relational database from within your node.js repl
- Wed, 10 Mar 2021 16:04:00 +0000
+ Thu, 11 Mar 2021 05:05:00 +0000https://supabase.com/blog/toad-a-link-shortener-with-simple-apis-for-low-codersToad, a link shortener with simple APIs for low-coders
https://supabase.com/blog/toad-a-link-shortener-with-simple-apis-for-low-coders
An easy-to-use link shortening tool with simple APIs
- Sun, 07 Mar 2021 16:04:00 +0000
+ Mon, 08 Mar 2021 05:05:00 +0000https://supabase.com/blog/postgres-as-a-cron-serverPostgres as a CRON Server
https://supabase.com/blog/postgres-as-a-cron-server
Running repetitive tasks with your Postgres database.
- Thu, 04 Mar 2021 16:04:00 +0000
+ Fri, 05 Mar 2021 05:05:00 +0000https://supabase.com/blog/supabase-beta-february-2021Supabase Beta February 2021
https://supabase.com/blog/supabase-beta-february-2021
One year of building.
- Mon, 01 Mar 2021 16:04:00 +0000
+ Tue, 02 Mar 2021 05:05:00 +0000https://supabase.com/blog/cracking-postgres-interviewCracking PostgreSQL Interview Questions
https://supabase.com/blog/cracking-postgres-interview
Understand the top PostgreSQL Interview Questions
- Fri, 26 Feb 2021 16:04:00 +0000
+ Sat, 27 Feb 2021 05:05:00 +0000https://supabase.com/blog/case-study-roboflowRoboflow.com choose Supabase to power Paint.wtf leaderboard
https://supabase.com/blog/case-study-roboflow
Learn how Roboflow.com used Supabase to build their Paint.wtf leaderboard
- Mon, 08 Feb 2021 16:04:00 +0000
+ Tue, 09 Feb 2021 05:05:00 +0000https://supabase.com/blog/supabase-beta-january-2021Supabase Beta January 2021
https://supabase.com/blog/supabase-beta-january-2021
Eleven months of building.
- Mon, 01 Feb 2021 16:04:00 +0000
+ Tue, 02 Feb 2021 05:05:00 +0000https://supabase.com/blog/supabase-beta-december-2020Supabase Beta December 2020
https://supabase.com/blog/supabase-beta-december-2020
Ten months of building.
- Fri, 01 Jan 2021 16:04:00 +0000
+ Sat, 02 Jan 2021 05:05:00 +0000https://supabase.com/blog/supabase-dashboard-performanceMaking the Supabase Dashboard Supa-fast
https://supabase.com/blog/supabase-dashboard-performance
Improving the performance of the Supabase dashboard
- Sat, 12 Dec 2020 16:04:00 +0000
+ Sun, 13 Dec 2020 05:05:00 +0000https://supabase.com/blog/supabase-striveschoolSupabase Partners With Strive School To Help Teach Open Source
https://supabase.com/blog/supabase-striveschool
Supabase Partners With Strive School To Help Teach Open Source To The Next Generation Of Developers
- Tue, 01 Dec 2020 16:04:00 +0000
+ Wed, 02 Dec 2020 05:05:00 +0000https://supabase.com/blog/case-study-xenditXendit Built a Counter-Fraud Watchlist for the Fintech Industry
https://supabase.com/blog/case-study-xendit
See how Xendit use Supabase to build a full-text search engine.
- Tue, 01 Dec 2020 16:04:00 +0000
+ Wed, 02 Dec 2020 05:05:00 +0000https://supabase.com/blog/case-study-tayfaTAYFA Built a No-Code Website Builder in Seven Days
https://supabase.com/blog/case-study-tayfa
See how Tayfa went from idea to paying customer in less than 30 days.
- Tue, 01 Dec 2020 16:04:00 +0000
+ Wed, 02 Dec 2020 05:05:00 +0000https://supabase.com/blog/case-study-monitoroMonitoro Built a Web Crawler Handling Millions of API Requests
https://supabase.com/blog/case-study-monitoro
See how Monitoro built an automated scraping platform using Supabase.
- Tue, 01 Dec 2020 16:04:00 +0000
+ Wed, 02 Dec 2020 05:05:00 +0000https://supabase.com/blog/supabase-alpha-november-2020Supabase Alpha November 2020
https://supabase.com/blog/supabase-alpha-november-2020
Nine months of building.
- Mon, 30 Nov 2020 16:04:00 +0000
+ Tue, 01 Dec 2020 05:05:00 +0000https://supabase.com/blog/postgresql-viewsPostgres Views
https://supabase.com/blog/postgresql-views
Creating and using a view in PostgreSQL.
- Tue, 17 Nov 2020 16:04:00 +0000
+ Wed, 18 Nov 2020 05:05:00 +0000https://supabase.com/blog/supabase-alpha-october-2020Supabase Alpha October 2020
https://supabase.com/blog/supabase-alpha-october-2020
Eight months of building.
- Sun, 01 Nov 2020 16:04:00 +0000
+ Mon, 02 Nov 2020 05:05:00 +0000https://supabase.com/blog/improved-dxSupabase.js 1.0
https://supabase.com/blog/improved-dx
We're releasing a new version of our Supabase client with some awesome new improvements.
- Thu, 29 Oct 2020 16:04:00 +0000
+ Fri, 30 Oct 2020 04:04:00 +0000https://supabase.com/blog/supabase-alpha-september-2020Supabase Alpha September 2020
https://supabase.com/blog/supabase-alpha-september-2020
Seven months of building.
- Fri, 02 Oct 2020 16:04:00 +0000
+ Sat, 03 Oct 2020 04:04:00 +0000https://supabase.com/blog/supabase-hacktoberfest-2020Supabase Hacktoberfest 2020
https://supabase.com/blog/supabase-hacktoberfest-2020
Join us for a celebration of open source software and learn how to contribute to Supabase.
- Thu, 10 Sep 2020 16:04:00 +0000
+ Fri, 11 Sep 2020 04:04:00 +0000https://supabase.com/blog/supabase-alpha-august-2020Supabase Alpha August 2020
https://supabase.com/blog/supabase-alpha-august-2020
Six months of building
- Wed, 02 Sep 2020 16:04:00 +0000
+ Thu, 03 Sep 2020 04:04:00 +0000https://supabase.com/blog/supabase-authSupabase Auth
https://supabase.com/blog/supabase-auth
Authenticate and authorize your users with Supabase Auth
- Tue, 04 Aug 2020 16:04:00 +0000
+ Wed, 05 Aug 2020 04:04:00 +0000https://supabase.com/blog/supabase-alpha-july-2020Supabase Alpha July 2020
https://supabase.com/blog/supabase-alpha-july-2020
Five months of building
- Sat, 01 Aug 2020 16:04:00 +0000
+ Sun, 02 Aug 2020 04:04:00 +0000https://supabase.com/blog/continuous-postgresql-backup-walgContinuous PostgreSQL Backups using WAL-G
https://supabase.com/blog/continuous-postgresql-backup-walg
Have you ever wanted to restore your database's state to a particular moment in time? This post explains how, using WAL-G.
- Sat, 01 Aug 2020 16:04:00 +0000
+ Sun, 02 Aug 2020 04:04:00 +0000https://supabase.com/blog/alpha-launch-postmortemAlpha Launch Postmortem
https://supabase.com/blog/alpha-launch-postmortem
Everything that went wrong with Supabase's launch
- Thu, 09 Jul 2020 16:04:00 +0000
+ Fri, 10 Jul 2020 04:04:00 +0000https://supabase.com/blog/postgresql-templatesWhat are PostgreSQL Templates?
https://supabase.com/blog/postgresql-templates
What are PostgreSQL templates and what are they used for?
- Wed, 08 Jul 2020 16:04:00 +0000
+ Thu, 09 Jul 2020 04:04:00 +0000https://supabase.com/blog/postgresql-physical-logical-backupsPhysical vs Logical Backups in PostgreSQL
https://supabase.com/blog/postgresql-physical-logical-backups
What are physical and logical backups in Postgres?
- Mon, 06 Jul 2020 16:04:00 +0000
+ Tue, 07 Jul 2020 04:04:00 +0000https://supabase.com/blog/supabase-alpha-june-2020Supabase Alpha June 2020
https://supabase.com/blog/supabase-alpha-june-2020
Four months of building
- Tue, 30 Jun 2020 16:04:00 +0000
+ Wed, 01 Jul 2020 04:04:00 +0000https://supabase.com/blog/supabase-steve-chavezSteve Chavez has joined Supabase
https://supabase.com/blog/supabase-steve-chavez
Steve joins Supabase to help build Auth.
- Sun, 14 Jun 2020 16:04:00 +0000
+ Mon, 15 Jun 2020 04:04:00 +0000https://supabase.com/blog/supabase-alpha-may-2020Supabase Alpha May 2020
https://supabase.com/blog/supabase-alpha-may-2020
Three months of building
- Sun, 31 May 2020 16:04:00 +0000
+ Mon, 01 Jun 2020 04:04:00 +0000https://supabase.com/blog/supabase-alpha-april-2020Supabase Alpha April 2020
https://supabase.com/blog/supabase-alpha-april-2020
Two months of building
- Sun, 31 May 2020 16:04:00 +0000
+ Mon, 01 Jun 2020 04:04:00 +0000
diff --git a/i18n/README.bn.md b/i18n/README.bn.md
index b9455141903..ef6c1836891 100644
--- a/i18n/README.bn.md
+++ b/i18n/README.bn.md
@@ -11,7 +11,7 @@
- [x] হোস্ট করা পোস্টগ্রেস ডাটাবেস. [ডক্স](https://supabase.com/docs/guides/database)
- [x] অথেনটিকেশন এবং অথরাইজড . [ডক্স](https://supabase.com/docs/guides/auth)
-- [x] স্বয়ংক্রিয়ভাবে তৈরি APIs.
+- [x] স্বয়ংক্রিয়ভাবে তৈরি এপিআই.
- [x] রেস্ট. [ডক্স](https://supabase.com/docs/guides/api#rest-api)
- [x] রিয়েলটাইম সাবস্ক্রিপশন. [ডক্স](https://supabase.com/docs/guides/api#realtime-api)
- [x] গ্রাফকিউএল (বেটা). [ডক্স](https://supabase.com/docs/guides/api#graphql-api)
@@ -31,10 +31,10 @@
## কমিউনিটি ও সাপোর্ট
-- [কমিউনিটি ফোরাম](https://github.com/supabase/supabase/discussions). এর জন্য সর্বোত্তম: তৈরিতে সহায়তা, ডাটাবেস সেরা অনুশীলন সম্পর্কে আলোচনা।
-- [গিঠাব ইস্যু](https://github.com/supabase/supabase/issues). এর জন্য সেরা: সুপাবেস ব্যবহার করে আপনি যে বাগ এবং ত্রুটির সম্মুখীন হন।
-- [ইমেইল সাপোর্ট](https://supabase.com/docs/support#business-support). এর জন্য সেরা: আপনার ডাটাবেস বা অবকাঠামো নিয়ে সমস্যা।
-- [ডিসকোর্ড](https://discord.supabase.com). এর জন্য সর্বোত্তম: আপনার অ্যাপ্লিকেশনগুলি ভাগ করা এবং সম্প্রদায়ের সাথে হ্যাঙ্গআউট করা৷
+- [কমিউনিটি ফোরাম](https://github.com/supabase/supabase/discussions)। সর্বোত্তম: তৈরি করতে সহায়তা, ডাটাবেস সেরা অনুশীলন সম্পর্কে আলোচনা।
+- [গিটহাব ইস্যু](https://github.com/supabase/supabase/issues)। সর্বোত্তম: সুপাবেস ব্যবহার করতে আপনি যে বাগ এবং ত্রুটির সম্মুখীন হন।
+- [ইমেইল সাপোর্ট](https://supabase.com/docs/support#business-support)। সর্বোত্তম: আপনার ডাটাবেস বা অবকাঠামো নিয়ে সমস্যা।
+- [ডিসকোর্ড](https://discord.supabase.com)। সর্বোত্তম: আপনার অ্যাপ্লিকেশনগুলি শেয়ার করা এবং কমিউনিটির সাথে দেখা সাক্ষাৎ করা৷
## স্ট্যাটাস
@@ -43,30 +43,30 @@
- [x] পাবলিক বেটা: বেশিরভাগ নন-এন্টারপ্রাইজ ব্যবহারের ক্ষেত্রে যথেষ্ট স্থিতিশীল
- [ ] পাবলিক: প্রোডাকশন রেডি
-আমরা বর্তমানে পাবলিক বেটাতে আছি। বড় আপডেটের বিজ্ঞপ্তি পেতে এই রেপোর "রিলিজ" দেখুন।
+আমরা বর্তমানে পাবলিক বেটাতে আছি। বড় আপডেটের বিজ্ঞপ্তি পেতে এই রিপুর "রিলিজ" দেখুন।
-
+
---
## কিভাবে এটা কাজ করে
-Supabase হল ওপেন সোর্স টুলের সংমিশ্রণ। আমরা এন্টারপ্রাইজ-গ্রেড, ওপেন সোর্স পণ্য ব্যবহার করে Firebase-এর বৈশিষ্ট্য তৈরি করছি। যদি MIT, Apache 2, বা সমতুল্য ওপেন লাইসেন্স সহ টুল এবং সম্প্রদায়গুলি বিদ্যমান থাকে, আমরা সেই টুলটি ব্যবহার করব এবং সমর্থন করব। যদি টুলটি বিদ্যমান না থাকে, তাহলে আমরা নিজেরাই এটি তৈরি এবং ওপেন সোর্স করি। Supabase Firebase-এর 1-থেকে-1 ম্যাপিং নয়। ওপেন সোর্স টুল ব্যবহার করে ডেভেলপারদের ফায়ারবেসের মতো ডেভেলপার অভিজ্ঞতা দেওয়াই আমাদের লক্ষ্য।
+Supabase হল ওপেন সোর্স টুলের সংমিশ্রণ। আমরা এন্টারপ্রাইজ-গ্রেড, ওপেন সোর্স পণ্য ব্যবহার করে Firebase-এর ফিচারসমুহ তৈরি করছি। যদি MIT, Apache 2, বা সমতুল্য ওপেন লাইসেন্স সহ টুল এবং সম্প্রদায়গুলি বিদ্যমান থাকে, আমরা সেই টুলটি ব্যবহার করব এবং সমর্থন করব। যদি টুলটি বিদ্যমান না থাকে, তাহলে আমরা নিজেরাই এটি তৈরি এবং ওপেন সোর্স করি। Supabase Firebase-এর 1-থেকে-1 ম্যাপিং নয়। ওপেন সোর্স টুল ব্যবহার করে ডেভেলপারদের ফায়ারবেসের মতো ডেভেলপার অভিজ্ঞতা দেওয়াই আমাদের লক্ষ্য।
**স্থাপত্য**
-সুপাবেস হল একটি [হোস্ট করা প্ল্যাটফর্ম](https://app.supabase.com)। আপনি সাইন আপ করতে পারেন এবং কিছু ইনস্টল না করে সুপাবেস ব্যবহার শুরু করতে পারেন।
+সুপাবেস হল একটি [হোস্ট করা প্ল্যাটফর্ম](https://app.supabase.com)। আপনি সাইন আপ করে এবং কিছু ইনস্টল না করে সুপাবেস ব্যবহার শুরু করতে পারেন।
এছাড়াও আপনি [স্ব-হোস্ট](https://supabase.com/docs/guides/hosting/overview) এবং [ডেভেলপ লোকালি](https://supabase.com/docs/guides/local-development) করতে পারেন।

- [PostgreSQL](https://www.postgresql.org/) হল একটি অবজেক্ট-রিলেশনাল ডাটাবেস সিস্টেম যার 30 বছরের বেশি সক্রিয় বিকাশ রয়েছে যা এটিকে নির্ভরযোগ্যতা, বৈশিষ্ট্যের দৃঢ়তা এবং কর্মক্ষমতার জন্য একটি শক্তিশালী খ্যাতি অর্জন করেছে।
- [রিয়েলটাইম](https://github.com/supabase/realtime) হল একটি Elixir সার্ভার যা আপনাকে ওয়েবসকেট ব্যবহার করে PostgreSQL সন্নিবেশ, আপডেট এবং মুছে ফেলা শুনতে দেয়। ডাটাবেস পরিবর্তনের জন্য রিয়েলটাইম পোল পোস্টগ্রেসের অন্তর্নির্মিত প্রতিলিপি কার্যকারিতা, পরিবর্তনগুলিকে JSON-এ রূপান্তরিত করে, তারপর অনুমোদিত ক্লায়েন্টদের কাছে ওয়েবসকেটের মাধ্যমে JSON সম্প্রচার করে।
-- [PostgREST](http://postgrest.org/) একটি ওয়েব সার্ভার যা আপনার PostgreSQL ডাটাবেসকে সরাসরি একটি RESTful API-তে পরিণত করে
-- [স্টোরেজ](https://github.com/supabase/storage-api) অনুমতিগুলি পরিচালনা করতে Postgres ব্যবহার করে S3-এ সঞ্চিত ফাইলগুলি পরিচালনা করার জন্য একটি RESTful ইন্টারফেস প্রদান করে।
-- [postgres-meta](https://github.com/supabase/postgres-meta) হল আপনার পোস্টগ্রেস পরিচালনা করার জন্য একটি RESTful API, যা আপনাকে টেবিল আনতে, ভূমিকা যোগ করতে এবং কোয়েরি চালানোর অনুমতি দেয়।
-- [GoTrue](https://github.com/netlify/gotrue) ব্যবহারকারীদের পরিচালনা এবং SWT টোকেন ইস্যু করার জন্য একটি SWT ভিত্তিক API।
-- [কং](https://github.com/Kong/kong) হল একটি ক্লাউড-নেটিভ API গেটওয়ে।
+- [PostgREST](http://postgrest.org/) একটি ওয়েব সার্ভার যা আপনার PostgreSQL ডাটাবেসকে সরাসরি একটি রেস্টফুল এপিআইতে পরিণত করে।
+- [স্টোরেজ](https://github.com/supabase/storage-api) অনুমতিগুলি পরিচালনা করতে পোস্টগ্রেস ব্যবহার করে S3-এ সঞ্চিত ফাইলগুলি পরিচালনা করার জন্য একটি রেস্টফুল ইন্টারফেস প্রদান করে।
+- [পোস্টগ্রেস-মেটা](https://github.com/supabase/postgres-meta) হল আপনার পোস্টগ্রেস পরিচালনা করার জন্য একটি রেস্টফুল এপিআই, যা আপনাকে টেবিল আনতে, ভূমিকা যোগ করতে এবং কোয়েরি চালানোর অনুমতি দেয়।
+- [গোট্রু](https://github.com/netlify/gotrue) ব্যবহারকারীদের পরিচালনা এবং SWT টোকেন ইস্যু করার জন্য একটি SWT ভিত্তিক এপিআই
+- [কং](https://github.com/Kong/kong) হল একটি ক্লাউড-নেটিভ এপিআই গেটওয়ে।
#### ক্লায়েন্ট লাইব্রেরি
@@ -82,7 +82,7 @@ Supabase হল ওপেন সোর্স টুলের সংমিশ্