diff --git a/.github/workflows/publish_image.yml b/.github/workflows/publish_image.yml index 8ed1db87295..84c8b8a88c2 100644 --- a/.github/workflows/publish_image.yml +++ b/.github/workflows/publish_image.yml @@ -2,6 +2,8 @@ name: Publish to Image Registry on: push: + branches: + - 'studio' tags: - '*' workflow_dispatch: @@ -25,6 +27,7 @@ jobs: latest=false tags: | type=ref,event=tag + type=sha,prefix={{date 'YYYYMMDD'}},enable=${{ github.ref_type == 'branch' }} type=raw,value=${{ inputs.version }},enable=${{ github.event_name != 'push' }} - uses: docker/setup-qemu-action@v2 diff --git a/apps/reference/docs/guides/auth/auth-helpers/nextjs.mdx b/apps/reference/docs/guides/auth/auth-helpers/nextjs.mdx index 4e8ffdd87dc..b509792f914 100644 --- a/apps/reference/docs/guides/auth/auth-helpers/nextjs.mdx +++ b/apps/reference/docs/guides/auth/auth-helpers/nextjs.mdx @@ -70,6 +70,7 @@ NEXT_PUBLIC_SUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY ## Basic Setup +```jsx title="app/root.jsx" +export const loader = async ({ request }) => { + // Environment variables may be stored somewhere other than `process.env` in runtimes other than node. + // We need to pipe these Supabase environment variables to the browser. + const { SUPABASE_URL, SUPABASE_ANON_KEY } = process.env + + // We can retrieve the session on the server and hand it to the client. + // This is used to make sure the session is available immediately upon rendering. + const response = new Response() + const supabase = createServerClient( + process.env.SUPABASE_URL!, + process.env.SUPABASE_ANON_KEY!, + { request, response } + ) + const { + data: { session: initialSession }, + } = await supabase.auth.getSession() + + // In order for the set-cookie header to be set, headers must be returned as part of the loader response. + return json( + { + initialSession, + env: { + SUPABASE_URL, + SUPABASE_ANON_KEY, + }, + }, + { + headers: response.headers, + } + ) +} +``` + + + + +```tsx title="app/root.tsx" +export const loader: LoaderFunction = async ({ request }) => { + // Environment variables may be stored somewhere other than `process.env` in runtimes other than node. + // We need to pipe these Supabase environment variables to the browser. + const { SUPABASE_URL, SUPABASE_ANON_KEY } = process.env + + // We can retrieve the session on the server and hand it to the client. + // This is used to make sure the session is available immediately upon rendering. + const response = new Response() + const supabase = createServerClient( + process.env.SUPABASE_URL!, + process.env.SUPABASE_ANON_KEY!, + { request, response } + ) + const { + data: { session: initialSession }, + } = await supabase.auth.getSession() + + // In order for the set-cookie header to be set, headers must be returned as part of the loader response. + return json( + { + initialSession, + env: { + SUPABASE_URL, + SUPABASE_ANON_KEY, + }, + }, + { + headers: response.headers, + } + ) +} +``` + + + + +Next, upon the initial client-side rendering of your application, set up a browser client and listen to session changes and expose both throughout your routes via the outlet context: + + + + +```jsx title="app/root.jsx" +import { useEffect, useState } from 'react' +import { json } from '@remix-run/node' +import { Outlet, useLoaderData } from '@remix-run/react' +import { + createServerClient, + createBrowserClient, +} from '@supabase/auth-helpers-remix' + +export const loader: LoaderFunction = async ({ request }) => { + // ... see loader function above. +} + +export default function App() { + const { env, initialSession } = useLoaderData() + const [supabase, setSupabase] = useState(null) + const [session, setSession] = useState(initialSession) + + const context = { supabase, session } + + useEffect(() => { + if (!supabase) { + const supabase = createBrowserClient( + env.SUPABASE_URL, + env.SUPABASE_ANON_KEY + ) + setSupabase(supabase) + const { + data: { subscription }, + } = supabase.auth.onAuthStateChange((_, session) => setSession(session)) + return () => { + subscription.unsubscribe() + } + } + }, []) + + return ( + + + + + + ) +} +``` + + + + +```tsx title="app/root.tsx" +import { useEffect, useState } from 'react' +import { json, LoaderFunction } from '@remix-run/node' +import { Outlet, useLoaderData } from '@remix-run/react' +import { + createServerClient, + createBrowserClient, + supabase, + Session, +} from '@supabase/auth-helpers-remix' +import { Database } from '../db_types' + +export type ContextType = { + supabase: supabase | null + session: Session | null +} + +type LoaderData = { + env: { SUPABASE_URL: string; SUPABASE_ANON_KEY: string } + initialSession: Session | null +} + +export const loader: LoaderFunction = async ({ request }) => { + // ... see loader function above. +} + +export default function App() { + const { env, initialSession } = useLoaderData() + const [supabase, setSupabase] = useState(null) + const [session, setSession] = useState(initialSession) + + const context: ContextType = { supabase, session } + + useEffect(() => { + if (!supabase) { + const supabase = createBrowserClient( + env.SUPABASE_URL, + env.SUPABASE_ANON_KEY + ) + setSupabase(supabase) + const { + data: { subscription }, + } = supabase.auth.onAuthStateChange((_, session) => setSession(session)) + return () => { + subscription.unsubscribe() + } + } + }, []) + + return ( + + + + + + ) +} +``` + + + + +Now the supabase client and session are available throughout the application via the `useOutletContext`: + + + + +```jsx title="app/routes/index.jsx" +import { useOutletContext } from '@remix-run/react' + +export default function Index() { + const { supabase, session } = useOutletContext() + + return
{JSON.stringify({ session }, null, 2)}
+} +``` + +
+ + +```tsx title="app/routes/index.tsx" +import { useOutletContext } from '@remix-run/react' +import type { ContextType } from '../root' + +export default function Index() { + const { supabase, session } = useOutletContext() + + return
{JSON.stringify({ session }, null, 2)}
+} +``` + +
+
+ +You can find a full working example in the [source code on GitHub](https://github.com/supabase/auth-helpers/tree/main/examples/remix). + +## Usage with TypeScript + +You can pass types that were [generated with the Supabase CLI](/docs/reference/javascript/typescript-support#generating-types) to the `createServerClient` or `createBrowserClient` functions to get enhanced type safety and auto completion: + +### Server-side + +```tsx +import { createServerClient } from '@supabase/auth-helpers-remix' +import { Database } from '../../db_types' + +export const loader = async ({ request }) => { + const response = new Response() + + const supabase = createServerClient( + process.env.SUPABASE_URL, + process.env.SUPABASE_ANON_KEY, + { request, response } + ) +} +``` + +### Client-side + +```tsx +import { createBrowserClient } from '@supabase/auth-helpers-remix' +import { Database } from '../../db_types' + +const supabase = createBrowserClient(SUPABASE_URL, SUPABASE_ANON_KEY) +``` + +## Loader + Loader functions run on the server immediately before the component is rendered. They respond to all GET requests on a route. You can create an authenticated Supabase client by calling the `createServerClient` function and passing it your `SUPABASE_URL`, `SUPABASE_ANON_KEY`, and a `Request` and `Response`. + + + ```jsx import { json } from '@remix-run/node' // change this import to whatever runtime you are using import { createServerClient } from '@supabase/auth-helpers-remix' @@ -74,13 +354,13 @@ export const loader = async ({ request }) => { // an empty response is required for the auth helpers // to set cookies to manage auth - const supabaseClient = createServerClient( + const supabase = createServerClient( process.env.SUPABASE_URL, process.env.SUPABASE_ANON_KEY, { request, response } ) - const { data } = await supabaseClient.from('test').select('*') + const { data } = await supabase.from('test').select('*') // in order for the set-cookie header to be set, // headers must be returned as part of the loader response @@ -93,30 +373,22 @@ export const loader = async ({ request }) => { } ``` -> Supabase will set cookie headers to manage the user's auth session, therefore, the `response.headers` must be returned from the `Loader` function. - -Loader functions run on the server immediately before the component is rendered. You can create an authenticated Supabase client by calling the `createServerClient` function and passing it your `SUPABASE_URL`, `SUPABASE_ANON_KEY`, and a `Request` and `Response`. - -```jsx +```tsx import { LoaderFunction, json } from '@remix-run/node' // change this import to whatever runtime you are using import { createServerClient } from '@supabase/auth-helpers-remix' -export const loader: LoaderFunction = async ({ - request, -}: { - request: Request, -}) => { +export const loader: LoaderFunction = async ({ request }) => { const response = new Response() - const supabaseClient = createServerClient( + const supabase = createServerClient( process.env.SUPABASE_URL, process.env.SUPABASE_ANON_KEY, { request, response } ) - const { data } = await supabaseClient.from('test').select('*') + const { data } = await supabase.from('test').select('*') return json( { data }, @@ -127,14 +399,17 @@ export const loader: LoaderFunction = async ({ } ``` -> Supabase will set cookie headers to manage the user's auth session, therefore, the `response.headers` must be returned from the `Loader` function. - +> Supabase will set cookie headers to manage the user's auth session, therefore, the `response.headers` must be returned from the `Loader` function. + ## Action +Action functions run on the server and respond to HTTP requests to a route, other than GET - POST, PUT, PATCH, DELETE etc. You can create an authenticated Supabase client by calling the `createServerClient` function and passing it your `SUPABASE_URL`, `SUPABASE_ANON_KEY`, and a `Request` and `Response`. + -Action functions run on the server and respond to HTTP requests to a route, other than GET - POST, PUT, PATCH, DELETE etc. You can create an authenticated Supabase client by calling the `createServerClient` function and passing it your `SUPABASE_URL`, `SUPABASE_ANON_KEY`, and a `Request` and `Response`. - ```jsx import { json } from '@remix-run/node' // change this import to whatever runtime you are using import { createServerClient } from '@supabase/auth-helpers-remix' @@ -151,13 +424,13 @@ import { createServerClient } from '@supabase/auth-helpers-remix' export const action = async ({ request }) => { const response = new Response() - const supabaseClient = createServerClient( + const supabase = createServerClient( process.env.SUPABASE_URL, process.env.SUPABASE_ANON_KEY, { request, response } ) - const { data } = await supabaseClient.from('test').select('*') + const { data } = await supabase.from('test').select('*') return json( { data }, @@ -168,31 +441,23 @@ export const action = async ({ request }) => { } ``` -> Supabase will set cookie headers to manage the user's auth session, therefore, the `response.headers` must be returned from the `Action` function. - -Action functions run on the server and respond to HTTP requests to a route, other than GET - POST, PUT, PATCH, DELETE etc. You can create an authenticated Supabase client by calling the `createServerClient` function and passing it your `SUPABASE_URL`, `SUPABASE_ANON_KEY`, and a `Request` and `Response`. - -```jsx +```tsx import { ActionFunction, json } from '@remix-run/node' // change this import to whatever runtime you are using import { createServerClient } from '@supabase/auth-helpers-remix' -export const action: ActionFunction = async ({ - request, -}: { - request: Request, -}) => { +export const action: ActionFunction = async ({ request }) => { const response = new Response() - const supabaseClient = createServerClient( + const supabase = createServerClient( process.env.SUPABASE_URL, process.env.SUPABASE_ANON_KEY, { request, response } ) - const { data } = await supabaseClient.from('test').select('*') + const { data } = await supabase.from('test').select('*') return json( { data }, @@ -203,11 +468,11 @@ export const action: ActionFunction = async ({ } ``` -> Supabase will set cookie headers to manage the user's auth session, therefore, the `response.headers` must be returned from the `Action` function. - +> Supabase will set cookie headers to manage the user's auth session, therefore, the `response.headers` must be returned from the `Action` function. + ## Session and User You can determine if a user is authenticated by checking their session using the `getSession` function. @@ -215,7 +480,7 @@ You can determine if a user is authenticated by checking their session using the ```jsx const { data: { session }, -} = await supabaseClient.auth.getSession() +} = await supabase.auth.getSession() ``` The session contains a user property. @@ -224,681 +489,418 @@ The session contains a user property. const user = session?.user ``` -> This is the recommended way for accessing the logged in user. There is also a `getUser()` function but this does not refresh the session if it has expired. +## Authentication UI -## Client-side +### Pre-built Auth UI + +We recommend using our [pre-built Auth UI](/docs/guides/auth/auth-helpers/auth-ui) for authenticating users. It supports custom themes and extensible styles to match your brand and aesthetic. + +### Custom Auth UI + +Should you prefer to build your own Auth UI, you can use our [JavaScript Library](/docs/reference/javascript/) to interact with Supabase Auth from the client-side. + ]}> -In order to use the Supabase client in the browser - fetching data in `useEffect` or subscribing to realtime events - we need to do a little more plumbing. Remix does not include a way to make environment variables available to the browser, so we need to pipe them through from a `loader` function in our `root.jsx` route and attach them to the `window`. +```jsx title="app/routes/signin.jsx" +import { useOutletContext } from '@remix-run/react' -```jsx title="app/root.jsx" -export const loader = () => { - const { SUPABASE_URL, SUPABASE_ANON_KEY } = process.env - return json({ - env: { - SUPABASE_URL, - SUPABASE_ANON_KEY, - }, - }) -} -``` +export default function Auth() { + const { supabase, session } = useOutletContext() -> These may not be stored in `process.env` for environments other than Node. + const handleSubmit = async (event) => { + event.preventDefault() + if (!supabase) return + const formData = new FormData(event.currentTarget) + const email = formData.get('loginEmail') + const password = formData.get('loginPassword') + // Sign in + const { error } = await supabase.auth.signInWithPassword({ + email, + password, + }) + if (error) alert(error.message) + } -Next, we call the `useLoaderData` hook in our component to get the `env` object. - -```jsx title="app/root.jsx" -const { env } = useLoaderData() -``` - -And then, add a ` -
+ diff --git a/apps/reference/nav/supabase_dart_sidebars.js b/apps/reference/nav/supabase_dart_sidebars.js index 106bf0ca333..a3da7c80ebf 100644 --- a/apps/reference/nav/supabase_dart_sidebars.js +++ b/apps/reference/nav/supabase_dart_sidebars.js @@ -43,18 +43,6 @@ const sidebars = { 'generated/upsert', 'generated/delete', 'generated/rpc', - { - type: 'category', - label: 'Modifiers', - items: [ - 'generated/using-modifiers', - 'generated/limit', - 'generated/order', - 'generated/range', - 'generated/single', - ], - collapsed: true, - }, { type: 'category', label: 'Filters', @@ -86,6 +74,18 @@ const sidebars = { ], collapsed: true, }, + { + type: 'category', + label: 'Modifiers', + items: [ + 'generated/using-modifiers', + 'generated/limit', + 'generated/order', + 'generated/range', + 'generated/single', + ], + collapsed: true, + }, ], collapsed: true, }, diff --git a/apps/temp-docs/components/CustomHTMLElements/CustomHTMLElements.utils.ts b/apps/temp-docs/components/CustomHTMLElements/CustomHTMLElements.utils.ts index f768c93215d..af959573bee 100644 --- a/apps/temp-docs/components/CustomHTMLElements/CustomHTMLElements.utils.ts +++ b/apps/temp-docs/components/CustomHTMLElements/CustomHTMLElements.utils.ts @@ -2,8 +2,10 @@ export const getAnchor = (text: any): string | undefined => { if (typeof text !== 'string') { return undefined } else { - const [anchor] = text.match(/{#[a-z-]*}/g) || [] - return anchor !== undefined ? anchor.slice(2, anchor.length - 1) : undefined + return text + .toLowerCase() + .replace(/[^a-z0-9 ]/g, '') + .replace(/[ ]/g, '-') } } @@ -15,3 +17,19 @@ export const removeAnchor = (text: any) => { else return text } } + +export const highlightSelectedTocItem = (id: string) => { + const tocMenuItems = document.querySelectorAll('.toc-menu a') + + // find any currently active items and remove them + const currentActiveItem = document.querySelector('.toc-menu .toc__menu-item--active') + currentActiveItem?.classList.remove('toc__menu-item--active') + + // Add active class to the current item + tocMenuItems.forEach((item) => { + // @ts-ignore + if (item.href.split('#')[1] === id) { + item.classList.add('toc__menu-item--active') + } + }) +} diff --git a/apps/temp-docs/components/CustomHTMLElements/H3.tsx b/apps/temp-docs/components/CustomHTMLElements/H3.tsx deleted file mode 100644 index b952513d94a..00000000000 --- a/apps/temp-docs/components/CustomHTMLElements/H3.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { getAnchor, removeAnchor } from './CustomHTMLElements.utils' - -const H3 = ({ children }) => { - const anchor = getAnchor(children) - const link = `#${anchor}` - return ( -

- {removeAnchor(children)} - {anchor && ( - - # - - )} -

- ) -} -export default H3 diff --git a/apps/temp-docs/components/CustomHTMLElements/H4.tsx b/apps/temp-docs/components/CustomHTMLElements/H4.tsx deleted file mode 100644 index d178551cde5..00000000000 --- a/apps/temp-docs/components/CustomHTMLElements/H4.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { getAnchor, removeAnchor } from './CustomHTMLElements.utils' - -const H4 = ({ children }) => { - const anchor = getAnchor(children) - const link = `#${anchor}` - return ( -

- {removeAnchor(children)} - {anchor && ( - - # - - )} -

- ) -} -export default H4 diff --git a/apps/temp-docs/components/CustomHTMLElements/Heading.tsx b/apps/temp-docs/components/CustomHTMLElements/Heading.tsx new file mode 100644 index 00000000000..bf81989b26c --- /dev/null +++ b/apps/temp-docs/components/CustomHTMLElements/Heading.tsx @@ -0,0 +1,29 @@ +import { getAnchor, removeAnchor, highlightSelectedTocItem } from './CustomHTMLElements.utils' +import { useInView } from 'react-intersection-observer' + +const Heading = ({ tag, children }) => { + const HeadingTag = `${tag}` as any + + const anchor = getAnchor(children) + const link = `#${anchor}` + + // check if current heading is in view, update TOC active item accordingly + const { ref, inView, entry } = useInView({ + threshold: 1, + onChange: (inView, entry) => { + if (inView) highlightSelectedTocItem(entry.target.id) + }, + }) + + return ( + + {removeAnchor(children)} + {anchor && ( + + # + + )} + + ) +} +export default Heading diff --git a/apps/temp-docs/components/CustomHTMLElements/index.tsx b/apps/temp-docs/components/CustomHTMLElements/index.tsx index 5a537049aa3..56ded7aefd1 100644 --- a/apps/temp-docs/components/CustomHTMLElements/index.tsx +++ b/apps/temp-docs/components/CustomHTMLElements/index.tsx @@ -1,4 +1,3 @@ -import H3 from './H3' -import H4 from './H4' +import Heading from './Heading' -export { H3, H4 } +export { Heading } diff --git a/apps/temp-docs/components/index.tsx b/apps/temp-docs/components/index.tsx index 747e03536d3..08c783a4651 100644 --- a/apps/temp-docs/components/index.tsx +++ b/apps/temp-docs/components/index.tsx @@ -5,8 +5,8 @@ import ButtonCard from './ButtonCard' import CodeBlock from './CodeBlock/CodeBlock' import Frameworks from './Frameworks' import AuthProviders from './AuthProviders' -import { H3, H4 } from './CustomHTMLElements' +import { Heading } from './CustomHTMLElements' import QuickstartIntro from './MDX/quickstart_intro.mdx' import ProjectSetup from './MDX/project_setup.mdx' @@ -20,12 +20,29 @@ const components = { QuickstartIntro, ProjectSetup, - Alert, + Alert: (props: any) => ( + + {props.children} + + ), Tabs, TabPanel: (props: any) => {props.children}, - h3: H3, - h4: H4, + h2: (props: any) => ( + + {props.children} + + ), + h3: (props: any) => ( + + {props.children} + + ), + h4: (props: any) => ( + + {props.children} + + ), code: (props: any) => , mono: (props: any) => {props.children}, } diff --git a/apps/temp-docs/docs/guides/cli/local-development.mdx b/apps/temp-docs/docs/guides/cli/local-development.mdx index 269c288e823..0fed6af0583 100644 --- a/apps/temp-docs/docs/guides/cli/local-development.mdx +++ b/apps/temp-docs/docs/guides/cli/local-development.mdx @@ -228,3 +228,7 @@ The local development environment is not as feature-complete as the Supabase Pla - The Functions interface is coming soon. - Logs are not supported through the interface (however you can access them through the Docker containers). - You cannot update your project settings in the Dashboard—this must be done using the CLI. + +``` + +``` diff --git a/apps/temp-docs/docs/guides/database/testing.mdx b/apps/temp-docs/docs/guides/database/testing.mdx index a1e2267df44..0fcda6c6c12 100644 --- a/apps/temp-docs/docs/guides/database/testing.mdx +++ b/apps/temp-docs/docs/guides/database/testing.mdx @@ -7,7 +7,7 @@ description: Test your database schema, tables, functions, and policies. import Tabs from '@theme/Tabs' import TabItem from '@theme/TabItem' -You can use the Supabase CLI to test your database. To get started: +You can use the Supabase CLI to test your database. The minimum required version of the CLI is [v1.11.4](https://github.com/supabase/cli/releases). To get started: - [Install the Supabase CLI](/docs/guides/cli) on your local machine diff --git a/apps/temp-docs/layouts/Default.tsx b/apps/temp-docs/layouts/Default.tsx index eb0dc7ca4f3..6060552d33d 100644 --- a/apps/temp-docs/layouts/Default.tsx +++ b/apps/temp-docs/layouts/Default.tsx @@ -57,13 +57,17 @@ const Layout: FC = ({ meta, children, toc, menuItems, currentPage }) => { {toc && !meta?.hide_table_of_contents && ( -
-
On this page
-
    +
    +
      {toc.json.map((item: any, i: number) => { return ( -
    • - {item.content} +
    • + + {item.content} +
    • ) })} diff --git a/apps/temp-docs/package.json b/apps/temp-docs/package.json index 4cce04b4d61..fe6ed028283 100644 --- a/apps/temp-docs/package.json +++ b/apps/temp-docs/package.json @@ -57,6 +57,7 @@ "react": "17.0.2", "react-copy-to-clipboard": "^5.0.2", "react-dom": "17.0.2", + "react-intersection-observer": "^9.4.0", "react-markdown": "^8.0.3", "react-syntax-highlighter": "^15.3.1", "remark": "^14.0.2", diff --git a/apps/temp-docs/styles/main.scss b/apps/temp-docs/styles/main.scss index 97358f02757..971a2e96b18 100644 --- a/apps/temp-docs/styles/main.scss +++ b/apps/temp-docs/styles/main.scss @@ -158,6 +158,11 @@ pre[class*='language-'] { } } +// ToC styles +.toc__menu-item--active { + color: var(--colors-brand9) !important; +} + .video-container { position: relative; width: 100%; @@ -175,4 +180,4 @@ pre[class*='language-'] { .admonition-content > p { @apply m-0; -} \ No newline at end of file +} diff --git a/apps/www/_blog/2022-11-02-supabase-beta-update-october-2022.mdx b/apps/www/_blog/2022-11-02-supabase-beta-update-october-2022.mdx new file mode 100644 index 00000000000..3b575fcab3d --- /dev/null +++ b/apps/www/_blog/2022-11-02-supabase-beta-update-october-2022.mdx @@ -0,0 +1,122 @@ +--- +title: Supabase Beta October 2022 +description: New SDKs, quickstarts, Functions tricks, and more. But, more importantly, Launch Week 6️ has a date! +author: ant_wilson +image: 2022-october/monthly-update-october-2022.jpg +thumb: 2022-october/monthly-update-october-2022.jpg +tags: + - release-notes +date: '2022-11-02' +toc_depth: 3 +--- + +During October, we shipped something for everybody: new SDKs, quickstarts, Functions tricks, and more. All are listed here just for you. But, more importantly, Launch Week 6️⃣ has a date! + +## supabase-js v2 and supabase-flutter v1 released + +![supabase-js v2 and supabase-flutter v1 released](/images/blog/2022-october/supabase-js-v2-supabase-flutter-v1-header.jpg) + +The new versions of our two most popular SDKs have been fully released. It couldn’t have happened without our amazing community, thanks to everyone involved. Now, it’s time to build 🛠 + +[Try supabase-js V2](https://supabase.com/docs/reference/javascript/)
      +[Try flutter-supabase V1](https://supabase.com/docs/reference/dart) + +## New Next.js quickstart & Next.js 13 example + +![New Next.js quickstart & Next.js 13 example](/images/blog/2022-october/next-header.jpg) + +Next.js is all the rage right now 🔥  + +Next.js Conf raised the bar for dev conferences. We had the honor of being a Gold Sponsor, so we revamped our [Next.js Quickstart guide](https://supabase.com/docs/guides/with-nextjs) to include our pre-built Auth UI and [Auth Helpers.](https://supabase.com/docs/guides/auth/auth-helpers/nextjs) + +And Next.js 13 was announced! Making it extremely easy to fetch and cache data from our [Serverless API](https://supabase.com/docs/guides/api). So we put together an [example to try it out](https://github.com/supabase/supabase/tree/master/examples/caching/with-nextjs-13). + +## Supabase Auth and Server-Side Rendering + +![Supabase Auth and Server-Side Rendering](/images/blog/2022-october/authentication-server-side-docs.jpg) + +The Auth team published an in-depth doc explaining how Supabase Auth supports server-side rendering. Includes an explanation of the authentication flow and answers to some of the more common questions. + +[Read the docs](https://supabase.com/docs/guides/auth/server-side-rendering). + +## Database Testing with pgTAP + +![Database Testing with pgTAP](/images/blog/2022-october/database-testing-postgres-pgtap.jpg) + +Do you have 100% code coverage? Probably not, because that’s usually the last thing you think of, but *definitely* not if you don’t have database tests. We just shipped a framework for Database Tests which makes it incredibly easy to test your database using pgTAP an pg_prove. + +[Read the docs](https://supabase.com/docs/guides/database/testing). + +## Edge Functions Update + +![Edge Functions Update](/images/blog/2022-october/functions-new-methods.jpg) + +Functions now support GET requests! Other HTTP verbs such as PUT, PATCH, and DELETE are supported too. + +[Check this example](https://github.com/supabase/supabase/blob/master/examples/edge-functions/supabase/functions/restful-tasks/index.ts) + +## Quick Product Updates + +- supabase-py 🐍 now has functions support! [PR](https://github.com/supabase-community/supabase-py/pull/179) +- You can now detect users’ location from Edge Functions easily by using `X-Forwarded-For header`. [Example](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/location) +- Return `provider_refresh_token` along with `provider_access_token`. [PR](https://github.com/supabase/gotrue/pull/641) +- Added a `refreshSession` method to allow users to forcefully refresh a session instead of waiting for it to autorefresh upon expiry. Thanks to [@j4w8n](https://github.com/j4w8n) for the [PR](https://github.com/supabase/gotrue-js/pull/505) 🙇🏻‍♂️ +- Logging: realtime, storage, postgrest, and pgbouncer released. +- Trigger a file download by adding the download query parameter to your storage objects. storage-api. [PR](https://github.com/supabase/storage-api/issues/122) + +## Made with Supabase + +![Made with Supabase](/images/blog/2022-october/twitter-card-header.jpg) + +There were so many amazing apps Made with Supabase this month that we couldn’t choose just one… so here are three: + +🚰 [Remote Water Feeder](https://twitter.com/SomangshuG/status/1581888060643774465) by Somangshu Goswami
      +📊 [Decile App](https://github.com/decileapp/decile) by [Krishna](https://twitter.com/ntkris)
      +📑 [Explainpaper](https://www.explainpaper.com/) by [Aman Jha](https://twitter.com/amanjha__) and [Jade](https://twitter.com/functionofjade) + +If you want to see +100 other apps, check [the replies](https://twitter.com/supabase/status/1585226233742229504). + +## Extended Community Highlights + +![Community](/images/blog/2022-june/community.jpg) + +- Mark Buggraf sat down to chat about postgres-wasm with LogRocket. [Podcast](https://podrocket.logrocket.com/opensourcing-postgres-wasm) +- A collection of awesome Supabase resources. [awesome-supabase](https://github.com/lyqht/awesome-supabase) +- All the Happy Hour Hacktoberfest episodes. [Episode 1](https://www.youtube.com/watch?v=qRSYenBLHHQ) | [Episode 2](https://www.youtube.com/watch?v=-RlivqzNIso) | [Episode 3](https://www.youtube.com/watch?v=LzDIptBGtUw) +- Hacking the PostgREST Headers: Oh, the Things You Can Do! [Article](https://dev.to/burggraf/hacking-the-postgrest-headers-oh-the-things-you-can-do-ck2) +- Why we’re moving away from Firebase. [Blog post](https://koptional.com/article/why-we%E2%80%99re-moving-away-from-firebase) +- Basejump SaaS starter for Supabase. [Repo](https://github.com/usebasejump/basejump) +- SvelteKit + Supabase CRUD with RLS: Row-Level Security! [Video](https://www.youtube.com/watch?v=iKzjfHARXpc) +- Building a startup (build log 2#): Authenticating students with Supabase. [Blog Post](https://dev.to/paul_emechebe/building-a-startup-build-log-2-authenticating-users-with-supabase-1p1b) +- CRUD with Supabase in Flutter. [Tutorial](https://sadabwasim.medium.com/crud-with-supabase-in-flutter-dbe97fa0c15) +- Phone Auth with self-hosted Supabase. [Video](https://www.youtube.com/watch?v=z3sE-ix2uok) +- My Future with Elixir: set-theoretic types. [Blog Post](https://elixir-lang.org/blog/2022/10/05/my-future-with-elixir-set-theoretic-types/) +- Upload media to Supabase from remote URL with nodejs. [Blog Post](https://www.antoinemesnil.com/posts/upload-media-supabase) +- Say goodbye to backend development. [Video](https://www.youtube.com/watch?v=9CuTxeioKF4) + +## Launch Week 6 date announced + +We are ending 2022 on a high note ✊. Mark your calendars: Launch Week 6 is happenning on **December 12-16**. + +In the meantime, [revisit LW5](https://supabase.com/launch-week). + +## We’re hiring + +Come join one of the fastest-growing open source projects ever 🤗 + +- [Sales Engineer](https://boards.greenhouse.io/supabase/jobs/4711141004) +- [Lead Billing and API Engineer](https://boards.greenhouse.io/supabase/jobs/4652333004) +- [View all our openings](https://boards.greenhouse.io/supabase) + +## Meme Zone + +If you made it this far in the blog post you deserve a treat. [Follow us on Twitter](https://twitter.com/supabase) for more. + +![Supabase meme October 2022](/images/blog/2022-october/beta-update-october-meme.jpeg) + +## Get started + +- Start using Supabase today: **[app.supabase.com](https://app.supabase.com/)** +- Make sure to **[star us on GitHub](https://github.com/supabase/supabase)** +- Follow us **[on Twitter](https://twitter.com/supabase)** +- Subscribe to our **[YouTube channel](https://www.youtube.com/c/supabase)** diff --git a/apps/www/components/CTABanner/index.tsx b/apps/www/components/CTABanner/index.tsx index 8665b6de062..d1313ad6e12 100644 --- a/apps/www/components/CTABanner/index.tsx +++ b/apps/www/components/CTABanner/index.tsx @@ -5,7 +5,7 @@ const CTABanner = (props: any) => { return (
      diff --git a/apps/www/components/Features/index.tsx b/apps/www/components/Features/index.tsx index ee5838d693b..b5c8dc3f68f 100644 --- a/apps/www/components/Features/index.tsx +++ b/apps/www/components/Features/index.tsx @@ -9,6 +9,7 @@ import TextLink from '../TextLink' const Features = () => { const IconSections = Object.values(Solutions).map((solution: any) => { const { name, description, icon, label, url } = solution + if (solution.name === 'Realtime') return null return (
      diff --git a/apps/www/components/PricingAddOnTable.tsx b/apps/www/components/PricingAddOnTable.tsx index 74bb578c15d..dbd7ccf7562 100644 --- a/apps/www/components/PricingAddOnTable.tsx +++ b/apps/www/components/PricingAddOnTable.tsx @@ -41,7 +41,7 @@ const PricingAddOnTable = ({ icon, pricing }: PricingAddOnTableProps) => { type="button" >
      -
      +
      {icon} diff --git a/apps/www/data/Pricing.json b/apps/www/data/Pricing.json index 41e8ff932c3..33a37a692bd 100644 --- a/apps/www/data/Pricing.json +++ b/apps/www/data/Pricing.json @@ -20,14 +20,6 @@ "enterprise": true } }, - { - "title": "Realtime functionality", - "tiers": { - "free": true, - "pro": true, - "enterprise": true - } - }, { "title": "Database space", "tiers": { @@ -41,8 +33,8 @@ "tooltip": "Backups are entire copies of your database that can be restored in the future.", "tiers": { "free": false, - "pro": "7 days of backup", - "enterprise": "30 days Point in Time backup" + "pro": "7 days of backup* (* if > 1TB, contact enterprise)", + "enterprise": "Custom" } }, { @@ -92,7 +84,7 @@ "tiers": { "free": "Up to 50,000 MAUs", "pro": "100,000 included, then $0.00325 per MAU", - "enterprise": "1,000,000 included, then $0.00325 per MAU" + "enterprise": "Unlimited" } }, { @@ -151,6 +143,14 @@ "pro": "100 / hour", "enterprise": "Contact Us" } + }, + { + "title": "Advanced security features", + "tiers": { + "free": false, + "pro": false, + "enterprise": "Contact Us" + } } ] }, @@ -198,19 +198,11 @@ "title": "Edge Functions", "icon": "M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4", "features": [ - { - "title": "Runtime hours", - "tiers": { - "free": "100 hours per month", - "pro": "1,000 hours per month", - "enterprise": "Unlimited" - } - }, { "title": "Invocations", "tiers": { "free": "500K per month", - "pro": "2 Million per month", + "pro": "2 Million per month, then $2 per 1 million invocations", "enterprise": "Unlimited" } }, @@ -226,12 +218,50 @@ "title": "Number of functions", "tiers": { "free": "10", - "pro": "100", + "pro": "100, then $10 per additional 100 functions", "enterprise": "Unlimited" } } ] }, + "realtime": { + "title": "Realtime", + "icon": "M15.042 21.672L13.684 16.6m0 0l-2.51 2.225.569-9.47 5.227 7.917-3.286-.672zM12 2.25V4.5m5.834.166l-1.591 1.591M20.25 10.5H18M7.757 14.743l-1.59 1.59M6 10.5H3.75m4.007-4.243l-1.59-1.59", + "features": [ + { + "title": "Change Data Capture (CDC)", + "tiers": { + "free": true, + "pro": true, + "enterprise": true + } + }, + { + "title": "Concurrent Peak Connections", + "tiers": { + "free": "Up to 200", + "pro": "Up to 500, then $10 per 1000", + "enterprise": "Unlimited concurrent connections and volume discount" + } + }, + { + "title": "Max Messages Per Month", + "tiers": { + "free": "2 Million (including database)", + "pro": "5 Million", + "enterprise": "Volume discounts on messages" + } + }, + { + "title": "Max Message Size", + "tiers": { + "free": "250 Kb", + "pro": "3 Mb", + "enterprise": "Custom" + } + } + ] + }, "dashboard": { "title": "Dashboard", "icon": "M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 110-4m0 4v2m0-6V4", @@ -262,42 +292,10 @@ } ] }, - "support": { - "title": "Support and Compliance", - "icon": "M18.364 5.636l-3.536 3.536m0 5.656l3.536 3.536M9.172 9.172L5.636 5.636m3.536 9.192l-3.536 3.536M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-5 0a4 4 0 11-8 0 4 4 0 018 0z", + "security": { + "title": "Platform Security and Compliance", + "icon": "M9 12.75L11.25 15 15 9.75m-3-7.036A11.959 11.959 0 013.598 6 11.99 11.99 0 003 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285z", "features": [ - { - "title": "Community support", - "tiers": { - "free": true, - "pro": true, - "enterprise": true - } - }, - { - "title": "Email support", - "tiers": { - "free": false, - "pro": true, - "enterprise": true - } - }, - { - "title": "Email support SLA", - "tiers": { - "free": false, - "pro": false, - "enterprise": true - } - }, - { - "title": "Designated support", - "tiers": { - "free": false, - "pro": false, - "enterprise": true - } - }, { "title": "On Premises / BYO cloud", "tiers": { @@ -335,7 +333,7 @@ "tiers": { "free": false, "pro": false, - "enterprise": "Coming soon" + "enterprise": true } }, { @@ -354,6 +352,69 @@ "enterprise": true } }, + { + "title": "Access Roles", + "tiers": { + "free": "Owner, Developer", + "pro": "Owner, Developer", + "enterprise": "Additional owner(s), admin, read-only, billing admin, custom" + } + }, + { + "title": "Vanity URLs", + "tiers": { + "free": false, + "pro": true, + "enterprise": true + } + }, + { + "title": "Custom Domains", + "tooltip": "Contact us to access this feature", + "tiers": { + "free": false, + "pro": "$10 per domain per month per project add on", + "enterprise": "1 included, additional custom domains $10 per custom domain per month. Volume discounts available." + } + } + ] + }, + "support": { + "title": "Support", + "icon": "M18.364 5.636l-3.536 3.536m0 5.656l3.536 3.536M9.172 9.172L5.636 5.636m3.536 9.192l-3.536 3.536M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-5 0a4 4 0 11-8 0 4 4 0 018 0z", + "features": [ + { + "title": "Community support", + "tiers": { + "free": true, + "pro": true, + "enterprise": true + } + }, + { + "title": "Email support", + "tiers": { + "free": false, + "pro": true, + "enterprise": true + } + }, + { + "title": "Email support SLA", + "tiers": { + "free": false, + "pro": false, + "enterprise": true + } + }, + { + "title": "Designated support", + "tiers": { + "free": false, + "pro": false, + "enterprise": true + } + }, { "title": "On Boarding Support", "tiers": { diff --git a/apps/www/data/PricingAddOn.json b/apps/www/data/PricingAddOn.json index 3de96ea0e20..2d597446001 100644 --- a/apps/www/data/PricingAddOn.json +++ b/apps/www/data/PricingAddOn.json @@ -1,11 +1,11 @@ { "database": { - "title": "Database", + "title": "Optimized Compute", "features": [ - "Fully Managed PostgreSQL", - "Dedicated Postgres Database", - "Optimized Database Instances", - "Realtime Functionality" + "For projects that need dedicated compute", + "For scaling number of connections", + "Additional CPU & RAM options", + "Additional Disk IO Bandwidth" ], "rows": [ { diff --git a/apps/www/data/Solutions.json b/apps/www/data/Solutions.json index 7e9131da046..ae3f1919fba 100644 --- a/apps/www/data/Solutions.json +++ b/apps/www/data/Solutions.json @@ -23,6 +23,14 @@ "label": "", "url": "/storage" }, + "realtime": { + "name": "Realtime", + "icon": "M15.042 21.672L13.684 16.6m0 0l-2.51 2.225.569-9.47 5.227 7.917-3.286-.672zM12 2.25V4.5m5.834.166l-1.591 1.591M20.25 10.5H18M7.757 14.743l-1.59 1.59M6 10.5H3.75m4.007-4.243l-1.59-1.59", + "description": "Store, organize, and serve large files. Any media, including videos and images.", + "description_short": "", + "label": "", + "url": "/storage" + }, "edge-functions": { "name": "Edge Functions", "icon": "M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4", @@ -30,5 +38,13 @@ "description_short": "", "label": "", "url": "/edge-functions" + }, + "realtime": { + "name": "Realtime", + "icon": "M13 10V3L4 14h7v7l9-11h-7z", + "description": "Create multiplayer experiences by sharing, broadcasting, and listenning to changes from other clients or the Database.", + "description_short": "", + "label": "", + "url": "/realtime" } } diff --git a/apps/www/data/products/realtime/api-examples.js b/apps/www/data/products/realtime/api-examples.js new file mode 100644 index 00000000000..862e4cd4152 --- /dev/null +++ b/apps/www/data/products/realtime/api-examples.js @@ -0,0 +1,87 @@ +export default [ + { + lang: 'js', + title: 'Database changes', + description: '', + code: ` + import { createClient } from '@supabase/supabase-js' + + const supabaseClient = createClient('URL', 'ANON') + const channel = supabaseClient + .channel('postgresChangesChannel') + .on('postgres_changes', { + event: 'INSERT', + schema: 'public', + table: 'messages' + }, payload => console.log(payload)) + .subscribe() + + + + + + + + + + + `, + }, + { + lang: 'js', + title: 'Presence', + description: '', + code: ` + import { createClient } from '@supabase/supabase-js' + + const supabaseClient = createClient('URL', 'ANON') + const channel = supabaseClient.channel('presenceChannel', { configs: { presence: 'id123' } }) + + channel + .on('presence', { event: 'sync' }, () => console.log(channel.presenceState())) + .on('presence', { event: 'join' }, ({ key, currentPresences, newPresences }) => console.log(key, currentPresences, newPresences)) + .on('presence', { event: 'leave' }, ({ key, currentPresences, leftPresences }) => console.log(key, currentPresences, leftPresences)) + .subscribe((status) => { + if (status === 'SUBSCRIBED') { + channel.track({ user_name: 'user123' }) + channel.track({ user_name: 'user345' }) + } + }) + + + + + + `, + }, + { + lang: 'js', + title: 'Broadcast', + description: '', + code: ` + import { createClient } from '@supabase/supabase-js' + + const supabaseClient = createClient('URL', 'ANON') + const channel = supabaseClient.channel('broadcastChannel', { configs: { broadcast: { self: true, ack: true } } }) + + channel + .on('broadcast', { event: 'pos' }, payload => console.log(payload)) + .subscribe((status) => { + if (status === 'SUBSCRIBED') { + channel + .send({ type: 'broadcast', event: 'pos', payload: { x: 0, y: 0 }}) + .then(status => { + if (status === 'ok') console.log('ok') + + // if ack is false then channel.send will always return 'ok' + if (status === 'timed out') console.log('timed out') + }) + } + }) + + + + + `, + }, +] diff --git a/apps/www/data/products/realtime/app-examples.js b/apps/www/data/products/realtime/app-examples.js new file mode 100644 index 00000000000..d323bae395e --- /dev/null +++ b/apps/www/data/products/realtime/app-examples.js @@ -0,0 +1,62 @@ +export default [ + { + img: 'toast-messages.svg', + title: 'Toast messages', + description: 'Listen to changes in the database and show users a toast message.', + }, + { + img: 'live-avatars.svg', + title: 'Live avatars', + description: 'Share the status of users across multiple clients.', + }, + { + img: 'live-cursors.svg', + title: 'Live cursors', + description: 'Share the position and status of multiple cursors across multiple clients.', + }, + { + img: 'leaderboard.svg', + title: 'Leaderboards', + description: + 'Listen to changes in your database regarding the scores of your users and display them live.', + }, + { + img: 'stock-market.svg', + title: 'Live charts', + description: + 'Keep charts updated in Realtime by listening to changes in the database rather than polling at intervals.', + }, + { + img: 'in-app-chat.svg', + title: 'In app chat', + description: 'Listen to changes in the database to display up-to-date text messages.', + }, + { + img: 'code-editor.svg', + title: 'Shared text editor', + description: 'Users can collaborate with text documents or even code editors.', + }, + + { + img: 'whiteboard.svg', + title: 'Shared whiteboard', + description: + 'Allow users to collaorate on a shared whiteboard, sharing positions and states of any kind of object in Realtime.', + }, + { + img: 'location.svg', + title: 'Location', + description: 'Listen to changes in the database regarding the position of a moving coordinate.', + }, + { + img: 'multiplayer-game.svg', + title: 'Multiplayer games', + description: + "Keep track of how long a player has been playing, who's turn it is and even share to other clients what the pllayer is doing.", + }, + { + img: 'form-presence.svg', + title: 'Form presence', + description: 'Display the active selection of different users throughout an interactive form.', + }, +] diff --git a/apps/www/internals/generate-sitemap.mjs b/apps/www/internals/generate-sitemap.mjs index abcd15bbe6c..03c922d6811 100644 --- a/apps/www/internals/generate-sitemap.mjs +++ b/apps/www/internals/generate-sitemap.mjs @@ -41,6 +41,9 @@ async function generate() { .replace('/auth/Auth', '/auth') .replace('/database/Database', '/database') .replace('/storage/Storage', '/storage') + .replace('/realtime/Realtime', '/realtime') + .replace('/edge-functions/edge-functions', '/edge-functions') + .replace('/nextjs/Nextjs', '/nextjs') let route = path === '/index' ? '' : path diff --git a/apps/www/pages/pricing/CHANGELOG.txt b/apps/www/pages/pricing/CHANGELOG.txt index e3f3c76d83d..bec552c3e06 100644 --- a/apps/www/pages/pricing/CHANGELOG.txt +++ b/apps/www/pages/pricing/CHANGELOG.txt @@ -1,5 +1,34 @@ Pricing Changelog +### 02 Nov 2022 +---- + +Database +- guidance on backups > 1TB in size +- Removed "Realtime functionality" as it is redundant with new realtime section +Auth +- added “advanced security features” +- MAUs changed to unlimited for Enterprise +Realtime +— Added new realtime section +- Concurrent Peak Connections +- Max Messages Per Month +- Max Message Size +Edge Functions +- Runtime hours removed +- Number of functions, usage pricing added after limit on Pro +- Invocations, usage pricing added after limit on Pro +Support +- Security features moved to own section +Platform Security and Compliance +- New section made +- added Access roles +- added Custom Domains +- added Vanity URLs added +Database Compute Add ons +- New label “Optimized Compute” + + ### 16 June 2022 ---- diff --git a/apps/www/pages/pricing/index.tsx b/apps/www/pages/pricing/index.tsx index 3958abe182c..a51809c5dec 100644 --- a/apps/www/pages/pricing/index.tsx +++ b/apps/www/pages/pricing/index.tsx @@ -343,6 +343,11 @@ export default function IndexPage() { tier={'free'} icon={Solutions['storage'].icon} /> + + + + + + + + diff --git a/apps/www/pages/realtime/Realtime.module.css b/apps/www/pages/realtime/Realtime.module.css new file mode 100644 index 00000000000..a58d8edb4ea --- /dev/null +++ b/apps/www/pages/realtime/Realtime.module.css @@ -0,0 +1,250 @@ +.shape { + transform-origin: top left; + animation: shape 20s infinite; +} + +@keyframes shape { + 0%, + 5% { + opacity: 1; + transform: scale(0, 0); + border-radius: 0; + border-color: hsla(153, 60%, 28%, 1); + box-shadow: none; + border-width: 3px; + } + 10%, + 37.3% { + opacity: 1; + transform: scale(1, 1); + border-radius: 0; + border-color: hsla(153, 60%, 28%, 1); + box-shadow: none; + border-width: 3px; + } + 38%, + 42% { + opacity: 1; + transform: scale(1, 1); + border-radius: 0px; + border-color: #ffffff; + box-shadow: none; + border-width: 3px; + } + 45%, + 48.2% { + opacity: 1; + transform: scale(1, 1); + border-radius: 10px; + border-color: #ffffff; + box-shadow: none; + border-width: 3px; + } + 49%, + 71.2% { + opacity: 1; + transform: scale(1, 1); + border-radius: 10px; + border-color: hsla(153, 60%, 28%, 1); + box-shadow: none; + border-width: 3px; + } + 72%, + 74% { + opacity: 1; + transform: scale(1, 1); + border-radius: 10px; + border-color: #ffffff; + box-shadow: none; + border-width: 3px; + } + 76%, + 92% { + opacity: 1; + transform: scale(1, 1); + border-radius: 10px; + border-color: #ffffff; + box-shadow: 0px 7px 20px 0px rgba(0, 0, 0, 0.2); + border-width: 1.5px; + } + 94%, + 100% { + opacity: 1; + transform: scale(1, 1); + border-radius: 10px; + border-color: hsla(153, 60%, 28%, 1); + box-shadow: 0px 7px 20px 0px rgba(0, 0, 0, 0.2); + border-width: 1.5px; + } +} + +.button-text { + animation: button-text 20s infinite; +} + +@keyframes button-text { + 0%, + 78.5% { + opacity: 0; + font-family: 'Arial'; + background-color: transparent; + } + 79%, + 84% { + opacity: 1; + font-family: 'Arial'; + background-color: transparent; + } + 84.5%, + 88% { + opacity: 1; + font-family: 'Arial'; + background-color: rgba(0, 0, 0, 0.4); + } + 88.1%, + 100% { + opacity: 1; + font-family: 'custom-font'; + background-color: transparent; + } +} + +.cursor-one { + animation: cursor-one 20s infinite; +} + +@keyframes cursor-one { + 0% { + transform: translate(0px, 0px); + } + 2%, + 5% { + transform: translate(-202px, -63px); + } + 10%, + 11% { + transform: translate(-16px, -15px); + } + 13%, + 100% { + transform: translate(0, 0); + } +} + +.cursor-two { + animation: cursor-two 20s infinite; +} + +@keyframes cursor-two { + 0%, + 17% { + transform: scale(1) translate(-200px, 300px); + } + 20%, + 32% { + transform: scale(1) translate(-85px, 89px); + } + 34%, + 37.1% { + transform: scale(1) translate(0px, 0px); + } + 37.4%, + 37.7% { + transform: scale(0.95) translate(0px, 0px); + } + 38%, + 46% { + transform: scale(1) translate(0px, 0px); + } + 49%, + 100% { + transform: scale(1) translate(-50px, 100px); + } +} + +.cursor-two-comment { + animation: cursor-two-comment 20s infinite; +} + +@keyframes cursor-two-comment { + 0%, + 22% { + opacity: 0; + transform: scale(0.95) translate(0px, 5px); + } + 24%, + 30% { + opacity: 1; + transform: scale(1) translate(0px, 0px); + } + 32%, + 100% { + opacity: 0; + transform: scale(0.95) translate(0px, 5px); + } +} + +.cursor-three { + animation: cursor-three 20s infinite; +} + +@keyframes cursor-three { + 0%, + 50% { + transform: scale(1) translate(50px, -250px); + } + 53%, + 66% { + transform: scale(1) translate(-40px, -120px); + } + 68%, + 71% { + transform: scale(1) translate(0px, 0px); + } + 71.3%, + 71.6% { + transform: scale(0.95) translate(0px, 0px); + } + 71.9%, + 80% { + transform: scale(1) translate(0px, 0px); + } + 82%, + 84% { + transform: scale(1) translate(-20px, 10px); + } + 84.5%, + 85% { + transform: scale(0.95) translate(-20px, 10px); + } + 85.5%, + 91% { + transform: scale(1) translate(-20px, 10px); + } + 93%, + 100% { + transform: scale(1) translate(0px, -80px); + } +} + +.cursor-three-comment { + animation: cursor-three-comment 20s infinite; +} + +@keyframes cursor-three-comment { + 0%, + 56% { + opacity: 0; + transform: scale(0.95) translate(0px, 5px); + } + 58%, + 64% { + opacity: 1; + transform: scale(1) translate(0px, 0px); + } + 66%, + 100% { + opacity: 0; + transform: scale(0.95) translate(0px, 5px); + } +} diff --git a/apps/www/pages/realtime/Realtime.tsx b/apps/www/pages/realtime/Realtime.tsx new file mode 100644 index 00000000000..2a448489ba0 --- /dev/null +++ b/apps/www/pages/realtime/Realtime.tsx @@ -0,0 +1,251 @@ +import { Button, IconGrid, IconLayers, IconMenu } from '@supabase/ui' +import ApiExamples from 'data/products/realtime/api-examples' +import AppExamples from 'data/products/realtime/app-examples' +import Solutions from 'data/Solutions.json' +import { NextSeo } from 'next-seo' +import Link from 'next/link' +import { useRouter } from 'next/router' +import CTABanner from '~/components/CTABanner' +import DefaultLayout from '~/components/Layouts/Default' +import SectionContainer from '~/components/Layouts/SectionContainer' +import APISection from '~/components/Sections/APISection' +import ProductHeader from '~/components/Sections/ProductHeader' +import RealtimeStyles from './Realtime.module.css' + +import 'swiper/swiper.min.css' + +const Cursor = ({ className = '', color = 'none' }) => { + return ( + + ) +} + +function RealtimePage() { + // base path for images + const { basePath } = useRouter() + const meta_title = 'Realtime | Sync your data in real time' + const meta_description = + 'Listens to changes in a PostgreSQL Database and broadcasts them over WebSockets' + + return ( + <> + + + Build modern web and mobile applications]} + subheader={['Sync client state globally over WebSockets in Realtime']} + image={[ +
      +
      +

      + Start a project +

      +
      + + +
      +

      🤔

      +
      + +
      +

      😄

      +
      + {/*
      +
      +
      */} + {/*
      +
      +
      */} +
      +
      + + + +
      +
      +
      +
      +
      +
      +
      +
      , + ]} + documentation_url={'/docs/guides/realtime/broadcast'} + /> + + +
      +
      +
      + realtime broadcast +
      +

      Database changes

      +

      + Listen to changes in the Database inserts, updates, and deletes and other changes. +

      +
      + + + +
      +
      +
      +
      + realtime broadcast +
      +

      Presence

      +

      Store and synchronize online user state consistently across clients.

      +
      + + + +
      +
      +
      +
      + realtime broadcast +
      +

      Broadcast

      +

      Send any data to any client subscribed to the same Channel.

      +
      + + + +
      +
      +
      +
      + + +
      +

      What you can build with Realtime

      +

      + Build any kind of Realtime application with ease, including any of these scenarios. +

      +
      +
      + {AppExamples.map((example) => { + return ( + <> +
      + {example.title} + {example.title} +
      +

      {example.title}

      +

      {example.description}

      +
      +
      + + ) + })} +
      +
      + + + +

      + APIs that you can understand. With powerful libraries that work on client and + server-side applications. +

      +

      , + ]} + // [TODO] Point to the correct docs URL + documentation_link={'/docs/guides//docs/guides/realtime/broadcast'} + /> +
      + + + + + ) +} + +export default RealtimePage diff --git a/apps/www/pages/realtime/index.tsx b/apps/www/pages/realtime/index.tsx new file mode 100644 index 00000000000..a8eea95247e --- /dev/null +++ b/apps/www/pages/realtime/index.tsx @@ -0,0 +1,3 @@ +import Realtime from './Realtime' + +export default Realtime diff --git a/apps/www/public/images/blog/2022-october/authentication-server-side-docs.jpg b/apps/www/public/images/blog/2022-october/authentication-server-side-docs.jpg new file mode 100644 index 00000000000..82b6386b377 Binary files /dev/null and b/apps/www/public/images/blog/2022-october/authentication-server-side-docs.jpg differ diff --git a/apps/www/public/images/blog/2022-october/beta-update-october-meme.jpeg b/apps/www/public/images/blog/2022-october/beta-update-october-meme.jpeg new file mode 100644 index 00000000000..eec6660397e Binary files /dev/null and b/apps/www/public/images/blog/2022-october/beta-update-october-meme.jpeg differ diff --git a/apps/www/public/images/blog/2022-october/database-testing-postgres-pgtap.jpg b/apps/www/public/images/blog/2022-october/database-testing-postgres-pgtap.jpg new file mode 100644 index 00000000000..cff6435db94 Binary files /dev/null and b/apps/www/public/images/blog/2022-october/database-testing-postgres-pgtap.jpg differ diff --git a/apps/www/public/images/blog/2022-october/functions-new-methods.jpg b/apps/www/public/images/blog/2022-october/functions-new-methods.jpg new file mode 100644 index 00000000000..1fa61196425 Binary files /dev/null and b/apps/www/public/images/blog/2022-october/functions-new-methods.jpg differ diff --git a/apps/www/public/images/blog/2022-october/monthly-update-october-2022.jpg b/apps/www/public/images/blog/2022-october/monthly-update-october-2022.jpg new file mode 100644 index 00000000000..3aa5e3e6369 Binary files /dev/null and b/apps/www/public/images/blog/2022-october/monthly-update-october-2022.jpg differ diff --git a/apps/www/public/images/blog/2022-october/next-header.jpg b/apps/www/public/images/blog/2022-october/next-header.jpg new file mode 100644 index 00000000000..789a878ac74 Binary files /dev/null and b/apps/www/public/images/blog/2022-october/next-header.jpg differ diff --git a/apps/www/public/images/blog/2022-october/supabase-js-v2-supabase-flutter-v1-header.jpg b/apps/www/public/images/blog/2022-october/supabase-js-v2-supabase-flutter-v1-header.jpg new file mode 100644 index 00000000000..e1d80d2aaf2 Binary files /dev/null and b/apps/www/public/images/blog/2022-october/supabase-js-v2-supabase-flutter-v1-header.jpg differ diff --git a/apps/www/public/images/blog/2022-october/twitter-card-header.jpg b/apps/www/public/images/blog/2022-october/twitter-card-header.jpg new file mode 100644 index 00000000000..fcce0cf3c44 Binary files /dev/null and b/apps/www/public/images/blog/2022-october/twitter-card-header.jpg differ diff --git a/apps/www/public/images/realtime/example-apps/dark/code-editor.svg b/apps/www/public/images/realtime/example-apps/dark/code-editor.svg new file mode 100644 index 00000000000..a049780f110 --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/dark/code-editor.svg @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/dark/form-presence.svg b/apps/www/public/images/realtime/example-apps/dark/form-presence.svg new file mode 100644 index 00000000000..ef3dfe01b3c --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/dark/form-presence.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/dark/in-app-chat.svg b/apps/www/public/images/realtime/example-apps/dark/in-app-chat.svg new file mode 100644 index 00000000000..49956fba709 --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/dark/in-app-chat.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/dark/leaderboard.svg b/apps/www/public/images/realtime/example-apps/dark/leaderboard.svg new file mode 100644 index 00000000000..91b509ca764 --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/dark/leaderboard.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/dark/live-avatars.svg b/apps/www/public/images/realtime/example-apps/dark/live-avatars.svg new file mode 100644 index 00000000000..4e16346cda5 --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/dark/live-avatars.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/dark/live-cursors.svg b/apps/www/public/images/realtime/example-apps/dark/live-cursors.svg new file mode 100644 index 00000000000..4b58c8cca8c --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/dark/live-cursors.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/dark/location.svg b/apps/www/public/images/realtime/example-apps/dark/location.svg new file mode 100644 index 00000000000..47116716afc --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/dark/location.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/dark/multiplayer-game.svg b/apps/www/public/images/realtime/example-apps/dark/multiplayer-game.svg new file mode 100644 index 00000000000..0e828e27da3 --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/dark/multiplayer-game.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/dark/notification.svg b/apps/www/public/images/realtime/example-apps/dark/notification.svg new file mode 100644 index 00000000000..74302e0a18a --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/dark/notification.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/dark/notifications.svg b/apps/www/public/images/realtime/example-apps/dark/notifications.svg new file mode 100644 index 00000000000..dd2df2e7877 --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/dark/notifications.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/dark/stock-market.svg b/apps/www/public/images/realtime/example-apps/dark/stock-market.svg new file mode 100644 index 00000000000..97976f8e926 --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/dark/stock-market.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/dark/text-editor.svg b/apps/www/public/images/realtime/example-apps/dark/text-editor.svg new file mode 100644 index 00000000000..03896ea0d50 --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/dark/text-editor.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/dark/toast-messages.svg b/apps/www/public/images/realtime/example-apps/dark/toast-messages.svg new file mode 100644 index 00000000000..54ff9264735 --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/dark/toast-messages.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/dark/whiteboard.svg b/apps/www/public/images/realtime/example-apps/dark/whiteboard.svg new file mode 100644 index 00000000000..0e4d4fd6d7a --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/dark/whiteboard.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/light/code-editor.svg b/apps/www/public/images/realtime/example-apps/light/code-editor.svg new file mode 100644 index 00000000000..69d17e3091c --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/light/code-editor.svg @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/light/form-presence.svg b/apps/www/public/images/realtime/example-apps/light/form-presence.svg new file mode 100644 index 00000000000..847af89fb7e --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/light/form-presence.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/light/in-app-chat.svg b/apps/www/public/images/realtime/example-apps/light/in-app-chat.svg new file mode 100644 index 00000000000..e145708932b --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/light/in-app-chat.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/light/leaderboard.svg b/apps/www/public/images/realtime/example-apps/light/leaderboard.svg new file mode 100644 index 00000000000..3b006695123 --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/light/leaderboard.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/light/live-avatars.svg b/apps/www/public/images/realtime/example-apps/light/live-avatars.svg new file mode 100644 index 00000000000..07fc6d05c46 --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/light/live-avatars.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/light/live-cursors.svg b/apps/www/public/images/realtime/example-apps/light/live-cursors.svg new file mode 100644 index 00000000000..6eea17cbccd --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/light/live-cursors.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/light/location.svg b/apps/www/public/images/realtime/example-apps/light/location.svg new file mode 100644 index 00000000000..b47bae812b0 --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/light/location.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/light/multiplayer-game.svg b/apps/www/public/images/realtime/example-apps/light/multiplayer-game.svg new file mode 100644 index 00000000000..33da69d507b --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/light/multiplayer-game.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/light/notifications.svg b/apps/www/public/images/realtime/example-apps/light/notifications.svg new file mode 100644 index 00000000000..b5b805eb9fb --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/light/notifications.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/light/stock-market.svg b/apps/www/public/images/realtime/example-apps/light/stock-market.svg new file mode 100644 index 00000000000..b2a3eb371a0 --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/light/stock-market.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/light/text-editor.svg b/apps/www/public/images/realtime/example-apps/light/text-editor.svg new file mode 100644 index 00000000000..867c4900681 --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/light/text-editor.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/light/toast-messages.svg b/apps/www/public/images/realtime/example-apps/light/toast-messages.svg new file mode 100644 index 00000000000..bdf2444078a --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/light/toast-messages.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/light/whiteboard.svg b/apps/www/public/images/realtime/example-apps/light/whiteboard.svg new file mode 100644 index 00000000000..2e1ea53b8ed --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/light/whiteboard.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/apps/www/public/images/realtime/example-apps/realtime-image/shared-editor.svg b/apps/www/public/images/realtime/example-apps/realtime-image/shared-editor.svg new file mode 100644 index 00000000000..56b513c2858 --- /dev/null +++ b/apps/www/public/images/realtime/example-apps/realtime-image/shared-editor.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/apps/www/public/images/realtime/icons/broadcast-alt.svg b/apps/www/public/images/realtime/icons/broadcast-alt.svg new file mode 100644 index 00000000000..f2cf5aabd48 --- /dev/null +++ b/apps/www/public/images/realtime/icons/broadcast-alt.svg @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/www/public/images/realtime/icons/broadcast.svg b/apps/www/public/images/realtime/icons/broadcast.svg new file mode 100644 index 00000000000..27674464239 --- /dev/null +++ b/apps/www/public/images/realtime/icons/broadcast.svg @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/www/public/images/realtime/icons/database-changes.svg b/apps/www/public/images/realtime/icons/database-changes.svg new file mode 100644 index 00000000000..d4c03209f7a --- /dev/null +++ b/apps/www/public/images/realtime/icons/database-changes.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/www/public/images/realtime/icons/presence.svg b/apps/www/public/images/realtime/icons/presence.svg new file mode 100644 index 00000000000..03638b0885f --- /dev/null +++ b/apps/www/public/images/realtime/icons/presence.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/www/public/images/realtime/og.jpg b/apps/www/public/images/realtime/og.jpg new file mode 100644 index 00000000000..56c1348eb1a Binary files /dev/null and b/apps/www/public/images/realtime/og.jpg differ diff --git a/apps/www/public/rss.xml b/apps/www/public/rss.xml index 016a847828e..1bd8a689926 100644 --- a/apps/www/public/rss.xml +++ b/apps/www/public/rss.xml @@ -5,119 +5,133 @@ https://supabase.com Latest news from Supabase en - Wed, 19 Oct 2022 02:02:30 +0000 + Wed, 26 Oct 2022 16:04:00 +0000 + https://supabase.com/blog/postgresql-commitfest + What 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 + + + https://supabase.com/blog/supabase-flutter-sdk-v1-released + supabase-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 + + https://supabase.com/blog/supabase-js-v2-released supabase-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 02:02:30 +0000 + Wed, 19 Oct 2022 16:04:00 +0000 https://supabase.com/blog/postgres-full-text-search-vs-the-rest Postgres 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 02:02:30 +0000 + Thu, 13 Oct 2022 16:04:00 +0000 https://supabase.com/blog/supabase-beta-update-september-2022 Supabase 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 02:02:30 +0000 + Tue, 04 Oct 2022 16:04:00 +0000 https://supabase.com/blog/postgres-wasm Postgres 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 02:02:30 +0000 + Sun, 02 Oct 2022 16:04:00 +0000 https://supabase.com/blog/choosing-a-postgres-primary-key Choosing 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 02:02:30 +0000 + Wed, 07 Sep 2022 16:04:00 +0000 https://supabase.com/blog/supabase-beta-update-august-2022 Supabase 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 02:02:30 +0000 + Tue, 06 Sep 2022 16:04:00 +0000 https://supabase.com/blog/launch-week-5-hackathon-winners Launch 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 02:02:30 +0000 + Wed, 24 Aug 2022 16:04:00 +0000 https://supabase.com/blog/building-a-realtime-trello-board-with-supabase-and-angular Building 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 02:02:30 +0000 + Tue, 23 Aug 2022 16:04:00 +0000 https://supabase.com/blog/supabase-vault Supabase 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 02:02:30 +0000 + Thu, 18 Aug 2022 16:04:00 +0000 https://supabase.com/blog/postgrest-v10 PostgREST 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 02:02:30 +0000 + Thu, 18 Aug 2022 16:04:00 +0000 https://supabase.com/blog/pg-jsonschema-a-postgres-extension-for-json-validation pg_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 02:02:30 +0000 + Thu, 18 Aug 2022 16:04:00 +0000 https://supabase.com/blog/launch-week-5-one-more-thing One 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 02:02:30 +0000 + Thu, 18 Aug 2022 16:04:00 +0000 https://supabase.com/blog/launch-week-5-community-day Community Day https://supabase.com/blog/launch-week-5-community-day Wrapping up Launch Week 5 with contributors, partners, and friends. - Thu, 18 Aug 2022 02:02:30 +0000 + Thu, 18 Aug 2022 16:04:00 +0000 https://supabase.com/blog/supabase-realtime-multiplayer-general-availability Realtime: 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 02:02:30 +0000 + Wed, 17 Aug 2022 16:04:00 +0000 https://supabase.com/blog/supabase-soc2 Supabase 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 02:02:30 +0000 + Tue, 16 Aug 2022 16:04:00 +0000 https://supabase.com/blog/supabase-js-v2 supabase-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 02:02:30 +0000 + Mon, 15 Aug 2022 16:04:00 +0000 https://supabase.com/blog/supabase-cli-v1-and-admin-api-beta @@ -131,763 +145,763 @@ Supabase Series B https://supabase.com/blog/supabase-series-b Supabase raised $80M in May, bringing our total funding to $116M. - Thu, 11 Aug 2022 02:02:30 +0000 + Thu, 11 Aug 2022 16:04:00 +0000 https://supabase.com/blog/launch-week-5-hackathon Launch 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 02:02:30 +0000 + Tue, 09 Aug 2022 16:04:00 +0000 https://supabase.com/blog/slack-consolidate-slackbot-to-consolidate-messages Slack 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 02:02:30 +0000 + Mon, 08 Aug 2022 16:04:00 +0000 https://supabase.com/blog/supabase-beta-update-july-2022 Supabase 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 02:02:30 +0000 + Tue, 02 Aug 2022 16:04:00 +0000 https://supabase.com/blog/supabase-flutter-sdk-1-developer-preview Supabase 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 02:02:30 +0000 + Mon, 01 Aug 2022 16:04:00 +0000 https://supabase.com/blog/seen-by-in-postgresql Implementing "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 02:02:30 +0000 + Sun, 17 Jul 2022 16:04:00 +0000 https://supabase.com/blog/supabase-auth-helpers-with-sveltekit-support Revamped 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 02:02:30 +0000 + Tue, 12 Jul 2022 16:04:00 +0000 https://supabase.com/blog/beta-update-june-2022 Supabase Beta June 2022 https://supabase.com/blog/beta-update-june-2022 Auth Helpers, Unlimited Free Projects, CLI and more... - Tue, 05 Jul 2022 02:02:30 +0000 + Tue, 05 Jul 2022 16:04:00 +0000 https://supabase.com/blog/flutter-tutorial-building-a-chat-app Flutter Tutorial: building a Flutter chat app https://supabase.com/blog/flutter-tutorial-building-a-chat-app How to create a real time chat app using Flutter. - Wed, 29 Jun 2022 02:02:30 +0000 + Wed, 29 Jun 2022 16:04:00 +0000 https://supabase.com/blog/visualizing-supabase-data-using-metabase Visualizing 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 02:02:30 +0000 + Tue, 28 Jun 2022 16:04:00 +0000 https://supabase.com/blog/partial-postgresql-data-dumps-with-rls Partial 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 02:02:30 +0000 + Mon, 27 Jun 2022 16:04:00 +0000 https://supabase.com/blog/loading-data-supabase-python Python 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 02:02:30 +0000 + Thu, 16 Jun 2022 16:04:00 +0000 https://supabase.com/blog/beta-update-may-2022 Supabase 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 02:02:30 +0000 + Tue, 31 May 2022 16:04:00 +0000 https://supabase.com/blog/how-supabase-accelerates-development-of-all-pull-together How 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 02:02:30 +0000 + Wed, 25 May 2022 16:04:00 +0000 https://supabase.com/blog/partner-gallery-works-with-supabase Works 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 02:02:30 +0000 + Tue, 19 Apr 2022 16:04:00 +0000 https://supabase.com/blog/bring-the-func-hackathon-winners Bring 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 02:02:30 +0000 + Sun, 17 Apr 2022 16:04:00 +0000 https://supabase.com/blog/beta-update-march-2022 Supabase Beta March 2022 https://supabase.com/blog/beta-update-march-2022 Functions, GraphQL, and much more. - Thu, 14 Apr 2022 02:02:30 +0000 + Thu, 14 Apr 2022 16:04:00 +0000 https://supabase.com/blog/supabrew Supabrew - Never Code Thirsty https://supabase.com/blog/supabrew A light and refreshing non-alcoholic beer for devs. - Fri, 01 Apr 2022 02:02:30 +0000 + Thu, 31 Mar 2022 16:04:00 +0000 https://supabase.com/blog/supabase-realtime-with-multiplayer-features Supabase 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. - Fri, 01 Apr 2022 02:02:30 +0000 + Thu, 31 Mar 2022 16:04:00 +0000 https://supabase.com/blog/hackathon-bring-the-func Hackathon: 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! - Fri, 01 Apr 2022 02:02:30 +0000 + Thu, 31 Mar 2022 16:04:00 +0000 https://supabase.com/blog/supabase-edge-functions Edge 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 02:02:30 +0000 + Wed, 30 Mar 2022 16:04:00 +0000 https://supabase.com/blog/supabase-enterprise Introducing 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 02:02:30 +0000 + Tue, 29 Mar 2022 16:04:00 +0000 https://supabase.com/blog/graphql-now-available GraphQL 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 02:02:30 +0000 + Mon, 28 Mar 2022 16:04:00 +0000 https://supabase.com/blog/community-day-lw4 Community Day https://supabase.com/blog/community-day-lw4 Kicking off Launch Week 4 with contributors, partners, and friends. - Sun, 27 Mar 2022 02:02:30 +0000 + Sun, 27 Mar 2022 16:04:00 +0000 https://supabase.com/blog/supabase-launch-week-four Supabase 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 02:02:30 +0000 + Thu, 24 Mar 2022 16:04:00 +0000 https://supabase.com/blog/should-i-open-source-my-company Should 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 02:02:30 +0000 + Thu, 24 Mar 2022 16:04:00 +0000 https://supabase.com/blog/audit Postgres 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 03:03:30 +0000 + Mon, 07 Mar 2022 16:04:00 +0000 https://supabase.com/blog/supabase-beta-january-2022 Supabase Beta January 2022 https://supabase.com/blog/supabase-beta-january-2022 New auth providers, SMS providers, and new videos. - Mon, 21 Feb 2022 03:03:30 +0000 + Mon, 21 Feb 2022 16:04:00 +0000 https://supabase.com/blog/supabase-beta-december-2021 Supabase 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 03:03:30 +0000 + Wed, 19 Jan 2022 16:04:00 +0000 https://supabase.com/blog/product-hunt-golden-kitty-awards-2021 Golden 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 03:03:30 +0000 + Wed, 19 Jan 2022 16:04:00 +0000 https://supabase.com/blog/holiday-hackdays-winners-2021 Holiday 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 03:03:30 +0000 + Thu, 16 Dec 2021 16:04:00 +0000 https://supabase.com/blog/beta-november-2021-launch-week-recap Supabase 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 03:03:30 +0000 + Tue, 14 Dec 2021 16:04:00 +0000 https://supabase.com/blog/supabase-holiday-hackdays-hackathon Kicking 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 03:03:30 +0000 + Thu, 02 Dec 2021 16:04:00 +0000 https://supabase.com/blog/pg-graphql pg_graphql: A GraphQL extension for PostgreSQL https://supabase.com/blog/pg-graphql GraphQL support is in development for PostgreSQL + Supabase. - Thu, 02 Dec 2021 03:03:30 +0000 + Thu, 02 Dec 2021 16:04:00 +0000 https://supabase.com/blog/launch-week-three-friday-five-more-things Five more things https://supabase.com/blog/launch-week-three-friday-five-more-things It's never just one more thing! - Thu, 02 Dec 2021 03:03:30 +0000 + Thu, 02 Dec 2021 16:04:00 +0000 https://supabase.com/blog/supabase-acquires-logflare Supabase acquires Logflare https://supabase.com/blog/supabase-acquires-logflare Today, we're ecstatic to announce that Logflare is joining Supabase. - Wed, 01 Dec 2021 03:03:30 +0000 + Wed, 01 Dec 2021 16:04:00 +0000 https://supabase.com/blog/realtime-row-level-security-in-postgresql Realtime 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 03:03:30 +0000 + Tue, 30 Nov 2021 16:04:00 +0000 https://supabase.com/blog/supabase-studio Supabase 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 03:03:30 +0000 + Mon, 29 Nov 2021 16:04:00 +0000 https://supabase.com/blog/community-day-lw3 Community Day https://supabase.com/blog/community-day-lw3 Kicking off launch week by highlighting the communities around Supabase. - Sun, 28 Nov 2021 03:03:30 +0000 + Sun, 28 Nov 2021 16:04:00 +0000 https://supabase.com/blog/whats-new-in-postgres-14 New 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 03:03:30 +0000 + Sat, 27 Nov 2021 16:04:00 +0000 https://supabase.com/blog/postgrest-9 PostgREST 9 https://supabase.com/blog/postgrest-9 New features and updates in PostgREST version 9. - Fri, 26 Nov 2021 03:03:30 +0000 + Fri, 26 Nov 2021 16:04:00 +0000 https://supabase.com/blog/supabase-launch-week-the-trilogy Supabase Launch Week III: Holiday Special https://supabase.com/blog/supabase-launch-week-the-trilogy Tis the season to be shipping. - Thu, 25 Nov 2021 03:03:30 +0000 + Thu, 25 Nov 2021 16:04:00 +0000 https://supabase.com/blog/supabase-how-we-launch How we launch at Supabase https://supabase.com/blog/supabase-how-we-launch The history and methodology of Supabase Launch Week. - Thu, 25 Nov 2021 03:03:30 +0000 + Thu, 25 Nov 2021 16:04:00 +0000 https://supabase.com/blog/supabase-beta-october-2021 Supabase 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 02:02:30 +0000 + Sat, 06 Nov 2021 16:04:00 +0000 https://supabase.com/blog/supabase-series-a Supabase $30m Series A https://supabase.com/blog/supabase-series-a Supabase just raised $30M, bringing our total funding to $36M. - Wed, 27 Oct 2021 02:02:30 +0000 + Wed, 27 Oct 2021 16:04:00 +0000 https://supabase.com/blog/replenysh-time-to-value-in-less-than-24-hours Replenysh 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 02:02:30 +0000 + Mon, 18 Oct 2021 16:04:00 +0000 https://supabase.com/blog/hacktoberfest-hackathon-winners-2021 Hacktoberfest Hackathon Winners 2021 https://supabase.com/blog/hacktoberfest-hackathon-winners-2021 Celebrating many amazing projects submitted to our Hacktoberfest Hackathon. - Wed, 13 Oct 2021 02:02:30 +0000 + Wed, 13 Oct 2021 16:04:00 +0000 https://supabase.com/blog/supabase-beta-sept-2021 Supabase Beta Sept 2021 https://supabase.com/blog/supabase-beta-sept-2021 Hackathon, Aborting request, UI updates, and now Hiring. - Sun, 03 Oct 2021 02:02:30 +0000 + Sun, 03 Oct 2021 16:04:00 +0000 https://supabase.com/blog/supabase-hacktoberfest-hackathon-2021 Supabase Hacktoberfest Hackathon 2021 https://supabase.com/blog/supabase-hacktoberfest-hackathon-2021 We're running another Supabase Hackathon during Hacktoberfest! - Mon, 27 Sep 2021 02:02:30 +0000 + Mon, 27 Sep 2021 16:04:00 +0000 https://supabase.com/blog/supabase-beta-august-2021 Supabase 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 02:02:30 +0000 + Thu, 09 Sep 2021 16:04:00 +0000 https://supabase.com/blog/supabase-beta-july-2021 Supabase 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 02:02:30 +0000 + Wed, 11 Aug 2021 16:04:00 +0000 https://supabase.com/blog/hackathon-winners Open 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 02:02:30 +0000 + Sun, 08 Aug 2021 16:04:00 +0000 https://supabase.com/blog/supabase-swag-store Supabase Swag Store https://supabase.com/blog/supabase-swag-store Today we are officially launching the Supabase Swag Store. - Thu, 29 Jul 2021 02:02:30 +0000 + Thu, 29 Jul 2021 16:04:00 +0000 https://supabase.com/blog/supabase-functions-updates Updates 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 02:02:30 +0000 + Thu, 29 Jul 2021 16:04:00 +0000 https://supabase.com/blog/1-the-supabase-hackathon The Supabase Hackathon https://supabase.com/blog/1-the-supabase-hackathon A whole week of Hacking for Fun and Prizes. - Thu, 29 Jul 2021 02:02:30 +0000 + Thu, 29 Jul 2021 16:04:00 +0000 https://supabase.com/blog/supabase-reports-and-metrics Supabase 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 02:02:30 +0000 + Wed, 28 Jul 2021 16:04:00 +0000 https://supabase.com/blog/supabase-auth-passwordless-sms-login Supabase 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 02:02:30 +0000 + Tue, 27 Jul 2021 16:04:00 +0000 https://supabase.com/blog/mobbin-supabase-200000-users Mobbin 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 02:02:30 +0000 + Tue, 27 Jul 2021 16:04:00 +0000 https://supabase.com/blog/storage-beta Supabase Storage now in Beta https://supabase.com/blog/storage-beta Supabase Storage moves into Beta. - Mon, 26 Jul 2021 02:02:30 +0000 + Mon, 26 Jul 2021 16:04:00 +0000 https://supabase.com/blog/spot-flutter-with-postgres Spot: 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 02:02:30 +0000 + Mon, 26 Jul 2021 16:04:00 +0000 https://supabase.com/blog/supabase-postgres-13 Supabase 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 02:02:30 +0000 + Sun, 25 Jul 2021 16:04:00 +0000 https://supabase.com/blog/supabase-community-day Supabase Community Day https://supabase.com/blog/supabase-community-day Community Day - Sun, 25 Jul 2021 02:02:30 +0000 + Sun, 25 Jul 2021 16:04:00 +0000 https://supabase.com/blog/epsilon3-self-hosting Epsilon3 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 02:02:30 +0000 + Sun, 25 Jul 2021 16:04:00 +0000 https://supabase.com/blog/supabase-launch-week-sql Supabase Launch Week II: The SQL https://supabase.com/blog/supabase-launch-week-sql Five days of Supabase. Again. - Wed, 21 Jul 2021 02:02:30 +0000 + Wed, 21 Jul 2021 16:04:00 +0000 https://supabase.com/blog/roles-postgres-hooks Protecting 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 02:02:30 +0000 + Thu, 01 Jul 2021 16:04:00 +0000 https://supabase.com/blog/supabase-beta-june-2021 Supabase 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 02:02:30 +0000 + Tue, 01 Jun 2021 16:04:00 +0000 https://supabase.com/blog/supabase-beta-may-2021 Supabase Beta May 2021 https://supabase.com/blog/supabase-beta-may-2021 Apple & Twitter Logins, Supabase Grid, Go & Swift Libraries. - Tue, 01 Jun 2021 02:02:30 +0000 + Tue, 01 Jun 2021 16:04:00 +0000 https://supabase.com/blog/supabase-beta-april-2021 Supabase Beta April 2021 https://supabase.com/blog/supabase-beta-april-2021 Supabase "gardening" - stability, security, and community support. - Tue, 04 May 2021 02:02:30 +0000 + Tue, 04 May 2021 16:04:00 +0000 https://supabase.com/blog/supabase-beta-march-2021 Supabase 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 02:02:30 +0000 + Mon, 05 Apr 2021 16:04:00 +0000 https://supabase.com/blog/supabase-workflows Workflows are coming to Supabase https://supabase.com/blog/supabase-workflows Functions are great, but you know what's better? - Thu, 01 Apr 2021 02:02:30 +0000 + Thu, 01 Apr 2021 16:04:00 +0000 https://supabase.com/blog/supabase-pgbouncer PgBouncer is now available in Supabase https://supabase.com/blog/supabase-pgbouncer Better support for Serverless and Postgres. - Thu, 01 Apr 2021 02:02:30 +0000 + Thu, 01 Apr 2021 16:04:00 +0000 https://supabase.com/blog/supabase-dot-com Supabase Dot Com https://supabase.com/blog/supabase-dot-com The Supabase Domain name is changing. - Thu, 01 Apr 2021 02:02:30 +0000 + Thu, 01 Apr 2021 16:04:00 +0000 https://supabase.com/blog/supabase-nft-marketplace Supabase Launches NFT Marketplace https://supabase.com/blog/supabase-nft-marketplace A fully encrypted NFT platform to protect and transact your digital assets - Thu, 01 Apr 2021 02:02:30 +0000 + Wed, 31 Mar 2021 16:04:00 +0000 https://supabase.com/blog/supabase-cli Supabase CLI https://supabase.com/blog/supabase-cli Local development, database migrations, and self-hosting. - Wed, 31 Mar 2021 02:02:30 +0000 + Tue, 30 Mar 2021 16:04:00 +0000 https://supabase.com/blog/supabase-storage Storage is now available in Supabase https://supabase.com/blog/supabase-storage Launching Supabase Storage and how you can use it in your apps - Tue, 30 Mar 2021 02:02:30 +0000 + Mon, 29 Mar 2021 16:04:00 +0000 https://supabase.com/blog/pricing Supabase Beta Pricing https://supabase.com/blog/pricing Supabase launches Beta pricing structure - Mon, 29 Mar 2021 02:02:30 +0000 + Sun, 28 Mar 2021 16:04:00 +0000 https://supabase.com/blog/launch-week Launch week https://supabase.com/blog/launch-week Five days of Supabase. - Wed, 24 Mar 2021 02:02:30 +0000 + Wed, 24 Mar 2021 16:04:00 +0000 https://supabase.com/blog/angels-of-supabase Angels of Supabase https://supabase.com/blog/angels-of-supabase Meet the investors of Supabase. - Wed, 24 Mar 2021 02:02:30 +0000 + Wed, 24 Mar 2021 16:04:00 +0000 https://supabase.com/blog/In-The-Loop Developers stay up to date with intheloop.dev https://supabase.com/blog/In-The-Loop Learn why Kevin is building intheloop.dev with Supabase - Mon, 22 Mar 2021 02:02:30 +0000 + Sun, 21 Mar 2021 16:04:00 +0000 https://supabase.com/blog/using-supabase-replit Using Supabase in Replit https://supabase.com/blog/using-supabase-replit Free hosted relational database from within your node.js repl - Thu, 11 Mar 2021 03:03:30 +0000 + Wed, 10 Mar 2021 16:04:00 +0000 https://supabase.com/blog/toad-a-link-shortener-with-simple-apis-for-low-coders Toad, 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 - Mon, 08 Mar 2021 03:03:30 +0000 + Sun, 07 Mar 2021 16:04:00 +0000 https://supabase.com/blog/postgres-as-a-cron-server Postgres as a CRON Server https://supabase.com/blog/postgres-as-a-cron-server Running repetitive tasks with your Postgres database. - Fri, 05 Mar 2021 03:03:30 +0000 + Thu, 04 Mar 2021 16:04:00 +0000 https://supabase.com/blog/supabase-beta-february-2021 Supabase Beta February 2021 https://supabase.com/blog/supabase-beta-february-2021 One year of building. - Tue, 02 Mar 2021 03:03:30 +0000 + Mon, 01 Mar 2021 16:04:00 +0000 https://supabase.com/blog/cracking-postgres-interview Cracking PostgreSQL Interview Questions https://supabase.com/blog/cracking-postgres-interview Understand the top PostgreSQL Interview Questions - Sat, 27 Feb 2021 03:03:30 +0000 + Fri, 26 Feb 2021 16:04:00 +0000 https://supabase.com/blog/case-study-roboflow Roboflow.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 - Tue, 09 Feb 2021 03:03:30 +0000 + Mon, 08 Feb 2021 16:04:00 +0000 https://supabase.com/blog/supabase-beta-january-2021 Supabase Beta January 2021 https://supabase.com/blog/supabase-beta-january-2021 Eleven months of building. - Tue, 02 Feb 2021 03:03:30 +0000 + Mon, 01 Feb 2021 16:04:00 +0000 https://supabase.com/blog/supabase-beta-december-2020 Supabase Beta December 2020 https://supabase.com/blog/supabase-beta-december-2020 Ten months of building. - Sat, 02 Jan 2021 03:03:30 +0000 + Fri, 01 Jan 2021 16:04:00 +0000 https://supabase.com/blog/supabase-dashboard-performance Making the Supabase Dashboard Supa-fast https://supabase.com/blog/supabase-dashboard-performance Improving the performance of the Supabase dashboard - Sun, 13 Dec 2020 03:03:30 +0000 + Sat, 12 Dec 2020 16:04:00 +0000 https://supabase.com/blog/supabase-striveschool Supabase 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 - Wed, 02 Dec 2020 03:03:30 +0000 + Tue, 01 Dec 2020 16:04:00 +0000 https://supabase.com/blog/case-study-xendit Xendit 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. - Wed, 02 Dec 2020 03:03:30 +0000 + Tue, 01 Dec 2020 16:04:00 +0000 https://supabase.com/blog/case-study-tayfa TAYFA 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. - Wed, 02 Dec 2020 03:03:30 +0000 + Tue, 01 Dec 2020 16:04:00 +0000 https://supabase.com/blog/case-study-monitoro Monitoro 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. - Wed, 02 Dec 2020 03:03:30 +0000 + Tue, 01 Dec 2020 16:04:00 +0000 https://supabase.com/blog/supabase-alpha-november-2020 Supabase Alpha November 2020 https://supabase.com/blog/supabase-alpha-november-2020 Nine months of building. - Tue, 01 Dec 2020 03:03:30 +0000 + Mon, 30 Nov 2020 16:04:00 +0000 https://supabase.com/blog/postgresql-views Postgres Views https://supabase.com/blog/postgresql-views Creating and using a view in PostgreSQL. - Wed, 18 Nov 2020 03:03:30 +0000 + Tue, 17 Nov 2020 16:04:00 +0000 https://supabase.com/blog/supabase-alpha-october-2020 Supabase Alpha October 2020 https://supabase.com/blog/supabase-alpha-october-2020 Eight months of building. - Mon, 02 Nov 2020 03:03:30 +0000 + Sun, 01 Nov 2020 16:04:00 +0000 https://supabase.com/blog/improved-dx Supabase.js 1.0 https://supabase.com/blog/improved-dx We're releasing a new version of our Supabase client with some awesome new improvements. - Fri, 30 Oct 2020 02:02:30 +0000 + Thu, 29 Oct 2020 16:04:00 +0000 https://supabase.com/blog/supabase-alpha-september-2020 Supabase Alpha September 2020 https://supabase.com/blog/supabase-alpha-september-2020 Seven months of building. - Sat, 03 Oct 2020 02:02:30 +0000 + Fri, 02 Oct 2020 16:04:00 +0000 https://supabase.com/blog/supabase-hacktoberfest-2020 Supabase 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. - Fri, 11 Sep 2020 02:02:30 +0000 + Thu, 10 Sep 2020 16:04:00 +0000 https://supabase.com/blog/supabase-alpha-august-2020 Supabase Alpha August 2020 https://supabase.com/blog/supabase-alpha-august-2020 Six months of building - Thu, 03 Sep 2020 02:02:30 +0000 + Wed, 02 Sep 2020 16:04:00 +0000 https://supabase.com/blog/supabase-auth Supabase Auth https://supabase.com/blog/supabase-auth Authenticate and authorize your users with Supabase Auth - Wed, 05 Aug 2020 02:02:30 +0000 + Tue, 04 Aug 2020 16:04:00 +0000 https://supabase.com/blog/supabase-alpha-july-2020 Supabase Alpha July 2020 https://supabase.com/blog/supabase-alpha-july-2020 Five months of building - Sun, 02 Aug 2020 02:02:30 +0000 + Sat, 01 Aug 2020 16:04:00 +0000 https://supabase.com/blog/continuous-postgresql-backup-walg Continuous 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. - Sun, 02 Aug 2020 02:02:30 +0000 + Sat, 01 Aug 2020 16:04:00 +0000 https://supabase.com/blog/alpha-launch-postmortem Alpha Launch Postmortem https://supabase.com/blog/alpha-launch-postmortem Everything that went wrong with Supabase's launch - Fri, 10 Jul 2020 02:02:30 +0000 + Thu, 09 Jul 2020 16:04:00 +0000 https://supabase.com/blog/postgresql-templates What are PostgreSQL Templates? https://supabase.com/blog/postgresql-templates What are PostgreSQL templates and what are they used for? - Thu, 09 Jul 2020 02:02:30 +0000 + Wed, 08 Jul 2020 16:04:00 +0000 https://supabase.com/blog/postgresql-physical-logical-backups Physical vs Logical Backups in PostgreSQL https://supabase.com/blog/postgresql-physical-logical-backups What are physical and logical backups in Postgres? - Tue, 07 Jul 2020 02:02:30 +0000 + Mon, 06 Jul 2020 16:04:00 +0000 https://supabase.com/blog/supabase-alpha-june-2020 Supabase Alpha June 2020 https://supabase.com/blog/supabase-alpha-june-2020 Four months of building - Wed, 01 Jul 2020 02:02:30 +0000 + Tue, 30 Jun 2020 16:04:00 +0000 https://supabase.com/blog/supabase-steve-chavez Steve Chavez has joined Supabase https://supabase.com/blog/supabase-steve-chavez Steve joins Supabase to help build Auth. - Mon, 15 Jun 2020 02:02:30 +0000 + Sun, 14 Jun 2020 16:04:00 +0000 https://supabase.com/blog/supabase-alpha-may-2020 Supabase Alpha May 2020 https://supabase.com/blog/supabase-alpha-may-2020 Three months of building - Mon, 01 Jun 2020 02:02:30 +0000 + Sun, 31 May 2020 16:04:00 +0000 https://supabase.com/blog/supabase-alpha-april-2020 Supabase Alpha April 2020 https://supabase.com/blog/supabase-alpha-april-2020 Two months of building - Mon, 01 Jun 2020 02:02:30 +0000 + Sun, 31 May 2020 16:04:00 +0000 diff --git a/apps/www/public/sitemap_www.xml b/apps/www/public/sitemap_www.xml index 16014f465f9..80c3abb11a8 100644 --- a/apps/www/public/sitemap_www.xml +++ b/apps/www/public/sitemap_www.xml @@ -60,6 +60,18 @@ 0.5 + + https://supabase.com/database + weekly + 0.5 + + + + https://supabase.com/edge-functions + weekly + 0.5 + + https://supabase.com/contact/enterprise weekly @@ -72,18 +84,6 @@ 0.5 - - https://supabase.com/database - weekly - 0.5 - - - - https://supabase.com/edge-functions/edge-functions - weekly - 0.5 - - https://supabase.com/legal/dpa weekly @@ -97,7 +97,13 @@ - https://supabase.com/nextjs/Nextjs + https://supabase.com/nextjs + weekly + 0.5 + + + + https://supabase.com/realtime weekly 0.5 @@ -870,6 +876,12 @@ 0.5 + + https://supabase.com/blog/postgresql-commitfest + weekly + 0.5 + + https://supabase.com/alternatives/supabase-vs-firebase weekly diff --git a/package-lock.json b/package-lock.json index faa6b32827d..9bac5d87d64 100644 --- a/package-lock.json +++ b/package-lock.json @@ -55,7 +55,7 @@ "jsrsasign": "^10.5.26", "lodash": "^4.17.21", "markdown-toc": "^1.2.0", - "next": "12.0.9", + "next": "12.1.0", "next-compose-plugins": "^2.2.1", "next-mdx-remote": "^3.0.8", "next-themes": "0.0.15", @@ -63,6 +63,7 @@ "react": "17.0.2", "react-copy-to-clipboard": "^5.0.2", "react-dom": "17.0.2", + "react-intersection-observer": "^9.4.0", "react-markdown": "^8.0.3", "react-syntax-highlighter": "^15.3.1", "remark": "^14.0.2", @@ -177,176 +178,6 @@ "react": "^16.13.1 || ^17.0.0" } }, - "apps/temp-docs/node_modules/@next/env": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/env/-/env-12.0.9.tgz", - "integrity": "sha512-oBlkyDop0Stf7MPIzETGv5r0YT/G/weBrknoPOUTaa5qwOeGjuy6gsOVc/SBtrBkOoBmRpD+fFhQJPvmo1mS+g==" - }, - "apps/temp-docs/node_modules/@next/swc-android-arm64": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.0.9.tgz", - "integrity": "sha512-aVqgsEn5plmUH2X58sjzhHsH/6majucWTMaaBEs7hHO2+GCwCZc7zaLH4XCBMKPES9Yaja8/pYUbvZQE9DqgFw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "apps/temp-docs/node_modules/@next/swc-darwin-arm64": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.0.9.tgz", - "integrity": "sha512-uAgRKm4a2nVdyBiPPJokvmDD1saugOvxljz9ld2ih0CCg5S9vBhqaj3kPGCQBj9hSu3q+Lng2CHnQqG3ga1jzA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "apps/temp-docs/node_modules/@next/swc-darwin-x64": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.0.9.tgz", - "integrity": "sha512-fDOs2lZIyrAdU18IxMA5orBPn9qLbOdu55gXSTNZOhyRJ8ugtbUAejsK7OL0boJy0CCHPAdVRXm01Mwk8tZ9RQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "apps/temp-docs/node_modules/@next/swc-linux-arm-gnueabihf": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.0.9.tgz", - "integrity": "sha512-/ni0p9DBvATUML9RQ1ycQuf05uOYKdzA6iI8+eRsARjpGbFVUFbge7XPzlj9g2Q9YWgoN8CSjFGnKRlyky5uHA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "apps/temp-docs/node_modules/@next/swc-linux-arm64-gnu": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.0.9.tgz", - "integrity": "sha512-AphxilJDf95rUxJDHgM9Ww1DaYXZWqTvoKwXeej/0SgSvICcRZrLaFDrkojdXz0Rxr4igX2OdYR1S4/Hj1jWOQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "apps/temp-docs/node_modules/@next/swc-linux-arm64-musl": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.0.9.tgz", - "integrity": "sha512-K5jbvNNzF3mRjWmPdxP5Bg87i7FHivfBj/L0KJlxpkLSC8sffBJDmB6jtMnI7wiPj9J6vmLkbGtSosln78xAlQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "apps/temp-docs/node_modules/@next/swc-linux-x64-gnu": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.0.9.tgz", - "integrity": "sha512-bJZ9bkMkQzsY+UyWezEZ77GWQ4TzwKeXdayX3U3+aEkL8k5C6eKBXlidWdrhu0teLmaUXIyWerWrLnJzwGXdfw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "apps/temp-docs/node_modules/@next/swc-linux-x64-musl": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.0.9.tgz", - "integrity": "sha512-SR9p0R+v1T32DTXPVAXZw31pmJAkSDotC6Afy+mfC0xrEL3pp95R8sGXYAAUCEPkQp0MEeUOVy2LrToe92X7hQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "apps/temp-docs/node_modules/@next/swc-win32-arm64-msvc": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.0.9.tgz", - "integrity": "sha512-mzQ1A8vfHhJrvEy5KJZGZWEByXthyKfWofvFaf+oo/5nJl/0Bz1ODP2ajSmbLG++77Eo2AROgbm9pkW1ucvG2A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "apps/temp-docs/node_modules/@next/swc-win32-ia32-msvc": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.0.9.tgz", - "integrity": "sha512-MpD2vj1zjo1u3J3wiz3pEKse19Etz+P0GL6XfQkB/9a84vJQ1JWMaWBjmIdivzZv718Il2pRSSx8hymwPfguYQ==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "apps/temp-docs/node_modules/@next/swc-win32-x64-msvc": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.0.9.tgz", - "integrity": "sha512-1c/sxp/4Qz4F6rCxiYqAnrmghCOFt5hHZ9Kd+rXFW5Mqev4C4XDOUMHdBH55HgnJZqngYhOE0r/XNkCtsIojig==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "apps/temp-docs/node_modules/@radix-ui/primitive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", @@ -812,55 +643,6 @@ "dev": true, "license": "MIT" }, - "apps/temp-docs/node_modules/next": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/next/-/next-12.0.9.tgz", - "integrity": "sha512-omfYqoR/DvbdOIJ6SS1unKJ4mGIxUPs0RPa7wr/Mft22OCKgJhuG+aI9KFYi5ZJBwoFQk1vqaMKpWz5qr+dN0Q==", - "dependencies": { - "@next/env": "12.0.9", - "caniuse-lite": "^1.0.30001283", - "postcss": "8.4.5", - "styled-jsx": "5.0.0", - "use-subscription": "1.5.1" - }, - "bin": { - "next": "dist/bin/next" - }, - "engines": { - "node": ">=12.22.0" - }, - "optionalDependencies": { - "@next/swc-android-arm64": "12.0.9", - "@next/swc-darwin-arm64": "12.0.9", - "@next/swc-darwin-x64": "12.0.9", - "@next/swc-linux-arm-gnueabihf": "12.0.9", - "@next/swc-linux-arm64-gnu": "12.0.9", - "@next/swc-linux-arm64-musl": "12.0.9", - "@next/swc-linux-x64-gnu": "12.0.9", - "@next/swc-linux-x64-musl": "12.0.9", - "@next/swc-win32-arm64-msvc": "12.0.9", - "@next/swc-win32-ia32-msvc": "12.0.9", - "@next/swc-win32-x64-msvc": "12.0.9" - }, - "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0", - "react": "^17.0.2 || ^18.0.0-0", - "react-dom": "^17.0.2 || ^18.0.0-0", - "sass": "^1.3.0" - }, - "peerDependenciesMeta": { - "fibers": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - } - } - }, "apps/temp-docs/node_modules/next-mdx-remote": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/next-mdx-remote/-/next-mdx-remote-3.0.8.tgz", @@ -897,23 +679,6 @@ "node": ">= 0.8.0" } }, - "apps/temp-docs/node_modules/postcss": { - "version": "8.4.5", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz", - "integrity": "sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==", - "dependencies": { - "nanoid": "^3.1.30", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, "apps/temp-docs/node_modules/supports-color": { "version": "7.2.0", "dev": true, @@ -29547,6 +29312,14 @@ "react": "^16.8.4 || ^17.0.0" } }, + "node_modules/react-intersection-observer": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.4.0.tgz", + "integrity": "sha512-v0403CmomOVlzhqFXlzOxg0ziLcVq8mfbP0AwAcEQWgZmR2OulOT79Ikznw4UlB3N+jlUYqLMe4SDHUOyp0t2A==", + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0|| ^18.0.0" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -58843,6 +58616,12 @@ "prop-types": "^15.0.0" } }, + "react-intersection-observer": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.4.0.tgz", + "integrity": "sha512-v0403CmomOVlzhqFXlzOxg0ziLcVq8mfbP0AwAcEQWgZmR2OulOT79Ikznw4UlB3N+jlUYqLMe4SDHUOyp0t2A==", + "requires": {} + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -62159,7 +61938,7 @@ "lodash": "^4.17.21", "markdown-toc": "^1.2.0", "minimist": "^1.2.6", - "next": "12.0.9", + "next": "12.1.0", "next-compose-plugins": "^2.2.1", "next-mdx-remote": "^3.0.8", "next-themes": "0.0.15", @@ -62169,6 +61948,7 @@ "react": "17.0.2", "react-copy-to-clipboard": "^5.0.2", "react-dom": "17.0.2", + "react-intersection-observer": "^9.4.0", "react-markdown": "^8.0.3", "react-syntax-highlighter": "^15.3.1", "remark": "^14.0.2", @@ -62235,77 +62015,6 @@ "version": "1.6.22", "requires": {} }, - "@next/env": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/env/-/env-12.0.9.tgz", - "integrity": "sha512-oBlkyDop0Stf7MPIzETGv5r0YT/G/weBrknoPOUTaa5qwOeGjuy6gsOVc/SBtrBkOoBmRpD+fFhQJPvmo1mS+g==" - }, - "@next/swc-android-arm64": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-android-arm64/-/swc-android-arm64-12.0.9.tgz", - "integrity": "sha512-aVqgsEn5plmUH2X58sjzhHsH/6majucWTMaaBEs7hHO2+GCwCZc7zaLH4XCBMKPES9Yaja8/pYUbvZQE9DqgFw==", - "optional": true - }, - "@next/swc-darwin-arm64": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.0.9.tgz", - "integrity": "sha512-uAgRKm4a2nVdyBiPPJokvmDD1saugOvxljz9ld2ih0CCg5S9vBhqaj3kPGCQBj9hSu3q+Lng2CHnQqG3ga1jzA==", - "optional": true - }, - "@next/swc-darwin-x64": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-12.0.9.tgz", - "integrity": "sha512-fDOs2lZIyrAdU18IxMA5orBPn9qLbOdu55gXSTNZOhyRJ8ugtbUAejsK7OL0boJy0CCHPAdVRXm01Mwk8tZ9RQ==", - "optional": true - }, - "@next/swc-linux-arm-gnueabihf": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.0.9.tgz", - "integrity": "sha512-/ni0p9DBvATUML9RQ1ycQuf05uOYKdzA6iI8+eRsARjpGbFVUFbge7XPzlj9g2Q9YWgoN8CSjFGnKRlyky5uHA==", - "optional": true - }, - "@next/swc-linux-arm64-gnu": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.0.9.tgz", - "integrity": "sha512-AphxilJDf95rUxJDHgM9Ww1DaYXZWqTvoKwXeej/0SgSvICcRZrLaFDrkojdXz0Rxr4igX2OdYR1S4/Hj1jWOQ==", - "optional": true - }, - "@next/swc-linux-arm64-musl": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.0.9.tgz", - "integrity": "sha512-K5jbvNNzF3mRjWmPdxP5Bg87i7FHivfBj/L0KJlxpkLSC8sffBJDmB6jtMnI7wiPj9J6vmLkbGtSosln78xAlQ==", - "optional": true - }, - "@next/swc-linux-x64-gnu": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.0.9.tgz", - "integrity": "sha512-bJZ9bkMkQzsY+UyWezEZ77GWQ4TzwKeXdayX3U3+aEkL8k5C6eKBXlidWdrhu0teLmaUXIyWerWrLnJzwGXdfw==", - "optional": true - }, - "@next/swc-linux-x64-musl": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.0.9.tgz", - "integrity": "sha512-SR9p0R+v1T32DTXPVAXZw31pmJAkSDotC6Afy+mfC0xrEL3pp95R8sGXYAAUCEPkQp0MEeUOVy2LrToe92X7hQ==", - "optional": true - }, - "@next/swc-win32-arm64-msvc": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.0.9.tgz", - "integrity": "sha512-mzQ1A8vfHhJrvEy5KJZGZWEByXthyKfWofvFaf+oo/5nJl/0Bz1ODP2ajSmbLG++77Eo2AROgbm9pkW1ucvG2A==", - "optional": true - }, - "@next/swc-win32-ia32-msvc": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.0.9.tgz", - "integrity": "sha512-MpD2vj1zjo1u3J3wiz3pEKse19Etz+P0GL6XfQkB/9a84vJQ1JWMaWBjmIdivzZv718Il2pRSSx8hymwPfguYQ==", - "optional": true - }, - "@next/swc-win32-x64-msvc": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.0.9.tgz", - "integrity": "sha512-1c/sxp/4Qz4F6rCxiYqAnrmghCOFt5hHZ9Kd+rXFW5Mqev4C4XDOUMHdBH55HgnJZqngYhOE0r/XNkCtsIojig==", - "optional": true - }, "@radix-ui/primitive": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", @@ -62642,29 +62351,6 @@ "version": "0.4.1", "dev": true }, - "next": { - "version": "12.0.9", - "resolved": "https://registry.npmjs.org/next/-/next-12.0.9.tgz", - "integrity": "sha512-omfYqoR/DvbdOIJ6SS1unKJ4mGIxUPs0RPa7wr/Mft22OCKgJhuG+aI9KFYi5ZJBwoFQk1vqaMKpWz5qr+dN0Q==", - "requires": { - "@next/env": "12.0.9", - "@next/swc-android-arm64": "12.0.9", - "@next/swc-darwin-arm64": "12.0.9", - "@next/swc-darwin-x64": "12.0.9", - "@next/swc-linux-arm-gnueabihf": "12.0.9", - "@next/swc-linux-arm64-gnu": "12.0.9", - "@next/swc-linux-arm64-musl": "12.0.9", - "@next/swc-linux-x64-gnu": "12.0.9", - "@next/swc-linux-x64-musl": "12.0.9", - "@next/swc-win32-arm64-msvc": "12.0.9", - "@next/swc-win32-ia32-msvc": "12.0.9", - "@next/swc-win32-x64-msvc": "12.0.9", - "caniuse-lite": "^1.0.30001283", - "postcss": "8.4.5", - "styled-jsx": "5.0.0", - "use-subscription": "1.5.1" - } - }, "next-mdx-remote": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/next-mdx-remote/-/next-mdx-remote-3.0.8.tgz", @@ -62692,16 +62378,6 @@ "word-wrap": "^1.2.3" } }, - "postcss": { - "version": "8.4.5", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz", - "integrity": "sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==", - "requires": { - "nanoid": "^3.1.30", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.1" - } - }, "supports-color": { "version": "7.2.0", "dev": true, diff --git a/spec/supabase_dart_v1.yml b/spec/supabase_dart_v1.yml index d83ffa4af3c..382c76bae08 100644 --- a/spec/supabase_dart_v1.yml +++ b/spec/supabase_dart_v1.yml @@ -1100,9 +1100,14 @@ pages: ``` Using Modifiers: description: | - Modifiers can be used on `select()` queries. + Filters work on the row level—they allow you to return rows that + only match certain conditions without changing the shape of the rows. + Modifiers are everything that don't fit that definition—allowing you to + change the format of the response (e.g., returning a CSV string). - If a Stored Procedure returns a table response, you can also apply modifiers to the `rpc()` function. + Modifiers must be specified after filters. Some modifiers only apply for + queries that return rows (e.g., `select()` or `rpc()` on a function that + returns a table response). limit(): description: | @@ -1180,13 +1185,17 @@ pages: Using Filters: description: | + Filters allow you to only return rows that match certain conditions. + Filters can be used on `select()`, `update()`, and `delete()` queries. - If a Stored Procedure returns a table response, you can also apply filters. + If a Database function returns a table response, you can also apply filters. ### Applying Filters - You must apply your filters to the end of your query. For example: + Filters must be applied after any of `select()`, `update()`, `upsert()`, + `delete()`, and `rpc()` and before + [modifiers](/docs/reference/dart/using-modifiers). ```dart final data = await supabase @@ -1202,7 +1211,8 @@ pages: ### Chaining - Filters can be chained together to produce advanced queries. For example: + Filters can be chained together to produce advanced queries. For example, + to query cities with population between 1,000 and 10,000: ```dart final data = await supabase @@ -1212,6 +1222,146 @@ pages: .lt('population', 10000); ``` + ### Conditional Chaining + + Filters can be built up one step at a time and then executed. For example: + + ```dart + final filterByName = null; + final filterPopLow = 1000; + final filterPopHigh = 10000; + + var query = supabase + .from('cities') + .select('name, country_id'); + + if (filterByName != null) { query = query.eq('name', filterByName); } + if (filterPopLow != null) { query = query.gte('population', filterPopLow); } + if (filterPopHigh != null) { query = query.lt('population', filterPopHigh); } + + final data = await query; + ``` + + ### Filter by values within a JSON column + + + + + ```sql + create table + users ( + id int8 primary key, + name text, + address jsonb + ); + + insert into + users (id, name, address) + values + (1, 'Michael', '{ "postcode": 90210 }'), + (2, 'Jane', null); + ``` + + + + + ```dart + final data = await supabase + .from('users') + .select() + .eq('address->postcode', 90210); + ``` + + + + + ```json + { + "data": [ + { + "id": 1, + "name": "Michael", + "address": { + "postcode": 90210 + } + } + ], + "status": 200, + "statusText": "OK" + } + ``` + + + + + ### Filter Foreign Tables + + You can filter on foreign tables in your `select()` query using dot + notation: + + + + + ```sql + create table + countries (id int8 primary key, name text); + create table + cities ( + id int8 primary key, + country_id int8 not null references countries, + name text + ); + + insert into + countries (id, name) + values + (1, 'Germany'), + (2, 'Indonesia'); + insert into + cities (id, country_id, name) + values + (1, 2, 'Bali'), + (2, 1, 'Munich'); + ``` + + + + + ```dart + final data = await supabase + .from('countries') + .select(''' + name, + cities!inner ( + name + ) + ''') + .eq('cities.name', 'Bali'); + ``` + + + + + ```json + { + "data": [ + { + "name": "Indonesia", + "cities": [ + { + "name": "Bali" + } + ] + } + ], + "status": 200, + "statusText": "OK" + } + ``` + + + + .or(): description: | Finds all rows satisfying at least one of the filters. diff --git a/studio/pages/project/[ref]/logs/pgbouncer-logs.tsx b/studio/pages/project/[ref]/logs/pgbouncer-logs.tsx index 0a4ddf0b520..6d257379b45 100644 --- a/studio/pages/project/[ref]/logs/pgbouncer-logs.tsx +++ b/studio/pages/project/[ref]/logs/pgbouncer-logs.tsx @@ -1,7 +1,7 @@ import React from 'react' import { useRouter } from 'next/router' import { observer } from 'mobx-react-lite' -import { DatabaseLayout } from 'components/layouts' +import { LogsLayout } from 'components/layouts' import LogsPreviewer from 'components/interfaces/Settings/Logs/LogsPreviewer' import { NextPageWithLayout } from 'types' import { LogsTableName } from 'components/interfaces/Settings/Logs' @@ -20,6 +20,6 @@ export const LogPage: NextPageWithLayout = () => { ) } -LogPage.getLayout = (page) => {page} +LogPage.getLayout = (page) => {page} export default observer(LogPage) diff --git a/studio/pages/project/[ref]/logs/postgrest-logs.tsx b/studio/pages/project/[ref]/logs/postgrest-logs.tsx index 78efcdc97f6..cd31e9f66c9 100644 --- a/studio/pages/project/[ref]/logs/postgrest-logs.tsx +++ b/studio/pages/project/[ref]/logs/postgrest-logs.tsx @@ -1,7 +1,7 @@ import React from 'react' import { useRouter } from 'next/router' import { observer } from 'mobx-react-lite' -import { DatabaseLayout } from 'components/layouts' +import { LogsLayout } from 'components/layouts' import LogsPreviewer from 'components/interfaces/Settings/Logs/LogsPreviewer' import { NextPageWithLayout } from 'types' import { LogsTableName } from 'components/interfaces/Settings/Logs' @@ -20,6 +20,6 @@ export const LogPage: NextPageWithLayout = () => { ) } -LogPage.getLayout = (page) => {page} +LogPage.getLayout = (page) => {page} export default observer(LogPage)