From 92e79e67d9f573157fd7f60869214db113e7d478 Mon Sep 17 00:00:00 2001 From: Ivan Vasilov Date: Tue, 16 Jun 2026 19:18:17 +0300 Subject: [PATCH 1/5] feat: Add error state to charts (#46991) This PR adds an error state to the usage charts on the Project home page. Screenshot 2026-06-16 at 18 10 20 I also added an error state to the charts in the [design system](https://design-system-git-feat-chart-error-state-supabase.vercel.app/design-system/docs/ui-patterns/charts#chart-states). ## Summary by CodeRabbit * **New Features** * Charts now display error states when data retrieval or processing fails, providing users with clear feedback about issues. * Improved error visibility and handling across analytics and charting components for better transparency. --- .../default/block/chart-composed-states.tsx | 31 ++++++- .../ProjectHome/ProjectUsageSection.tsx | 78 +++++++++------- .../analytics/useFillTimeseriesSorted.ts | 88 ++++++++++--------- packages/ui-patterns/src/Chart/index.tsx | 16 +++- .../ui-patterns/src/LogsBarChart/index.tsx | 9 ++ 5 files changed, 147 insertions(+), 75 deletions(-) diff --git a/apps/design-system/registry/default/block/chart-composed-states.tsx b/apps/design-system/registry/default/block/chart-composed-states.tsx index c4e25d545c2fe..2d3657cca2c72 100644 --- a/apps/design-system/registry/default/block/chart-composed-states.tsx +++ b/apps/design-system/registry/default/block/chart-composed-states.tsx @@ -1,7 +1,7 @@ 'use client' import { BarChart2, ExternalLink } from 'lucide-react' -import { Badge } from 'ui' +import { Badge, CriticalIcon } from 'ui' import { Chart, ChartActions, @@ -44,6 +44,35 @@ export default function ChartComposedStates() { + + + + Response Errors + + + } + title="Some error happened" + description="Error happened why trying to fetch data. Please try again later." + /> + } + emptyState={ + } + title="No data to show" + description="It may take up to 24 hours for data to refresh" + /> + } + loadingState={} + > + My chart here... + + + + diff --git a/apps/studio/components/interfaces/ProjectHome/ProjectUsageSection.tsx b/apps/studio/components/interfaces/ProjectHome/ProjectUsageSection.tsx index 54c0229972511..db61af89df2df 100644 --- a/apps/studio/components/interfaces/ProjectHome/ProjectUsageSection.tsx +++ b/apps/studio/components/interfaces/ProjectHome/ProjectUsageSection.tsx @@ -3,15 +3,16 @@ import dayjs from 'dayjs' import Link from 'next/link' import { useRouter } from 'next/router' import { useEffect, useMemo, useState } from 'react' -import { Card, CardContent, CardHeader, CardTitle, Loading } from 'ui' +import { Card, CardContent, CardHeader, CardTitle, Loading, WarningIcon } from 'ui' import { Row } from 'ui-patterns' +import { ChartEmptyState } from 'ui-patterns/Chart' import { LogsBarChart } from 'ui-patterns/LogsBarChart' import NoDataPlaceholder from '@/components/ui/Charts/NoDataPlaceholder' import { ChartIntervalDropdown } from '@/components/ui/Logs/ChartIntervalDropdown' import { CHART_INTERVALS } from '@/components/ui/Logs/logs.utils' import { UsageApiCounts, useProjectLogStatsQuery } from '@/data/analytics/project-log-stats-query' -import { useFillTimeseriesSorted } from '@/hooks/analytics/useFillTimeseriesSorted' +import { fillTimeseriesSorted } from '@/hooks/analytics/useFillTimeseriesSorted' import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements' import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' @@ -71,33 +72,42 @@ export const ProjectUsageSection = () => { }, [selectedInterval]) // Use V1 data fetching - const { data: logStatsData, isPending: isLoading } = useProjectLogStatsQuery({ - projectRef, - interval, - }) + const { + data: filledCharts, + isPending: isLoading, + error, + } = useProjectLogStatsQuery( + { + projectRef, + interval, + }, + { + select: (data) => { + // Calculate date range for gap filling + const startDateLocal = dayjs().subtract( + selectedInterval.startValue, + selectedInterval.startUnit as dayjs.ManipulateType + ) + const endDateLocal = dayjs() - // Calculate date range for gap filling - const startDateLocal = dayjs().subtract( - selectedInterval.startValue, - selectedInterval.startUnit as dayjs.ManipulateType + return fillTimeseriesSorted({ + data: data.result, + timestampKey: 'timestamp', + valueKey: [ + 'total_auth_requests', + 'total_rest_requests', + 'total_storage_requests', + 'total_realtime_requests', + ], + defaultValue: 0, + startDate: startDateLocal.toISOString(), + endDate: endDateLocal.toISOString(), + minPointsToFill: 5, + }) + }, + refetchOnWindowFocus: false, + } ) - const endDateLocal = dayjs() - - // Fill gaps in timeseries data - const { data: filledCharts } = useFillTimeseriesSorted({ - data: logStatsData?.result ?? [], - timestampKey: 'timestamp', - valueKey: [ - 'total_auth_requests', - 'total_rest_requests', - 'total_storage_requests', - 'total_realtime_requests', - ], - defaultValue: 0, - startDate: startDateLocal.toISOString(), - endDate: endDateLocal.toISOString(), - minPointsToFill: 5, - }) const serviceBase: ServiceEntry[] = useMemo( () => [ @@ -147,7 +157,7 @@ export const ProjectUsageSection = () => { // Transform V1 data to LogsBarChart format // Since V1 doesn't have error/warning breakdown, we show everything as "ok" - const transformedData: LogsBarChartDatum[] = (filledCharts || []).map((item) => ({ + const transformedData: LogsBarChartDatum[] = (filledCharts?.data || []).map((item) => ({ timestamp: item.timestamp, error_count: 0, warning_count: 0, @@ -162,10 +172,10 @@ export const ProjectUsageSection = () => { data: transformedData, total, isLoading, - error: null, + error: error || filledCharts?.error || null, } }), - [serviceBase, filledCharts, isLoading] + [serviceBase, filledCharts, isLoading, error] ) const handleBarClick = @@ -239,6 +249,7 @@ export const ProjectUsageSection = () => { { label: 'Requests', }, }} + ErrorState={ + } + title="Failed to load project usage" + description="Check our Status Page or try again later." + /> + } EmptyState={ (data: T[], timestampKey: stri */ export const useFillTimeseriesSorted = ( options: FillTimeseriesOptions +): FillTimeseriesResult => { + return useMemo(() => { + return fillTimeseriesSorted(options) + }, [ + JSON.stringify(options.data), + options.timestampKey, + JSON.stringify(options.valueKey), + options.defaultValue, + options.startDate, + options.endDate, + options.minPointsToFill, + options.interval, + ]) +} + +export const fillTimeseriesSorted = ( + options: FillTimeseriesOptions ): FillTimeseriesResult => { const { data, @@ -78,50 +95,39 @@ export const useFillTimeseriesSorted = ( interval, } = options - return useMemo(() => { - // Early return if no valid timestamp - if (!hasValidTimestamp(data, timestampKey)) { - return { - data, - error: null, - isError: false, - } + // Early return if no valid timestamp + if (!hasValidTimestamp(data, timestampKey)) { + return { + data, + error: null, + isError: false, } + } - try { - const filled = fillTimeseries( - data, - timestampKey, - valueKey, - defaultValue, - startDate, - endDate, - minPointsToFill, - interval - ) as T[] + try { + const filled = fillTimeseries( + data, + timestampKey, + valueKey, + defaultValue, + startDate, + endDate, + minPointsToFill, + interval + ) as T[] - const sorted = sortByTimestamp(filled, timestampKey) + const sorted = sortByTimestamp(filled, timestampKey) - return { - data: sorted, - error: null, - isError: false, - } - } catch (error: unknown) { - return { - data: [], - error: error instanceof Error ? error : new Error(String(error)), - isError: true, - } + return { + data: sorted, + error: null, + isError: false, } - }, [ - JSON.stringify(data), - timestampKey, - JSON.stringify(valueKey), - defaultValue, - startDate, - endDate, - minPointsToFill, - interval, - ]) + } catch (error: unknown) { + return { + data: [], + error: error instanceof Error ? error : new Error(String(error)), + isError: true, + } + } } diff --git a/packages/ui-patterns/src/Chart/index.tsx b/packages/ui-patterns/src/Chart/index.tsx index ca9773a529acb..3c0937a61594f 100644 --- a/packages/ui-patterns/src/Chart/index.tsx +++ b/packages/ui-patterns/src/Chart/index.tsx @@ -43,11 +43,13 @@ export type ChartConfig = { interface ChartContextValue { isLoading?: boolean isDisabled?: boolean + isErrored?: boolean } const ChartContext = React.createContext({ isLoading: false, isDisabled: false, + isErrored: false, }) export const useChart = () => { @@ -59,15 +61,19 @@ interface ChartProps extends React.HTMLAttributes { children: React.ReactNode isLoading?: boolean isDisabled?: boolean + isErrored?: boolean className?: string } const chartTableClasses = `[&_tr]:border-b [&_tr]:border-border [&_thead_tr]:bg-transparent! [&_thead_th]:py-2! [&_thead_th]:!px-card [&_thead_th]:h-auto [&_tbody_td]:py-2.5 [&_tbody_td]:px-card [&_tbody_td]:text-xs [&_table]:mb-1 [&_table]:border-b [&_table]:border-border` const Chart = React.forwardRef( - ({ children, isLoading = false, isDisabled = false, className, ...props }, ref) => { + ( + { children, isLoading = false, isDisabled = false, isErrored = false, className, ...props }, + ref + ) => { return ( - +
{children}
@@ -306,6 +312,7 @@ interface ChartContentProps extends React.HTMLAttributes { isEmpty?: boolean emptyState?: React.ReactNode loadingState?: React.ReactNode + errorState?: React.ReactNode disabledState?: React.ReactNode disabledActions?: ChartAction[] } @@ -318,19 +325,22 @@ const ChartContent = React.forwardRef( isEmpty = false, emptyState, loadingState, + errorState, disabledState, disabledActions, ...props }, ref ) => { - const { isLoading, isDisabled } = useChart() + const { isLoading, isDisabled, isErrored } = useChart() let content: React.ReactNode if (isDisabled) { content = disabledState } else if (isLoading) { content = loadingState + } else if (isErrored) { + content = errorState } else if (isEmpty) { content = emptyState } else { diff --git a/packages/ui-patterns/src/LogsBarChart/index.tsx b/packages/ui-patterns/src/LogsBarChart/index.tsx index 20316fc438f70..c0ad0476d8b92 100644 --- a/packages/ui-patterns/src/LogsBarChart/index.tsx +++ b/packages/ui-patterns/src/LogsBarChart/index.tsx @@ -26,8 +26,10 @@ type LogsBarChartDatum = { export const LogsBarChart = ({ data, + error, onBarClick, EmptyState, + ErrorState, DateTimeFormat = 'MMM D, YYYY, hh:mma', isFullHeight = false, chartConfig, @@ -36,8 +38,10 @@ export const LogsBarChart = ({ hideXAxis = false, }: { data: LogsBarChartDatum[] + error?: unknown | null onBarClick?: (datum: LogsBarChartDatum, tooltipData?: CategoricalChartState) => void EmptyState?: ReactNode + ErrorState?: ReactNode DateTimeFormat?: string isFullHeight?: boolean chartConfig?: ChartConfig @@ -47,6 +51,11 @@ export const LogsBarChart = ({ }) => { const [focusDataIndex, setFocusDataIndex] = useState(null) + if (error) { + if (ErrorState) return ErrorState + return null + } + if (data.length === 0) { if (EmptyState) return EmptyState return null From 6a6b7c90858b6b868c6d05bd3263a957357fa84a Mon Sep 17 00:00:00 2001 From: Danny White <3104761+dnywh@users.noreply.github.com> Date: Tue, 16 Jun 2026 12:59:37 -0600 Subject: [PATCH 2/5] fix(docs): remove redundant icons (#47002) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## What kind of change does this PR introduce? UI fix. Resolves DOCS-1051. ## What is the current behavior? Two unnecessary icons on docs homepage add more confusion than help. ## What is the new behavior? Removed and tightened surrounding spacing + rhythm. | Before | After | | --- | --- | | Supabase
Docs-5A137B99-AC36-4A59-85D9-B581307FFE6D | Supabase
Docs-1220594B-29B1-48B0-B976-39CCFB009857 | | Supabase
Docs-23849B84-EE41-45EB-A585-BEE71AB8FFB2 | Supabase
Docs-B5A3344F-32DD-4A49-B7DF-E5B10C8CDD13 | ## Summary by CodeRabbit * **Style** * Simplified documentation page header and section visuals by removing icon-accented wrappers and using cleaner text-based layouts. * **Accessibility / Content** * Updated section heading hierarchy for improved structure (e.g., “Additional resources” and “Self-Hosting”) by promoting headings while keeping existing context and styling. * Refreshed the “Getting Started” section to be text-focused without the prior play icon treatment. --- apps/docs/app/page.tsx | 20 ++++++++------------ apps/docs/components/HomePageCover.tsx | 17 +++++++---------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/apps/docs/app/page.tsx b/apps/docs/app/page.tsx index 186f3548a7980..31eba97aef4e2 100644 --- a/apps/docs/app/page.tsx +++ b/apps/docs/app/page.tsx @@ -1,11 +1,10 @@ import { isFeatureEnabled } from 'common' import { type Metadata, type ResolvingMetadata } from 'next' import Link from 'next/link' -import { cn, IconBackground } from 'ui' +import { cn } from 'ui' import { IconPanel } from 'ui-patterns/IconPanel' import { TextLink } from 'ui-patterns/TextLink' -import MenuIconPicker from '@/components/Navigation/NavigationMenu/MenuIconPicker' import { MIGRATION_PAGES } from '@/components/Navigation/NavigationMenu/NavigationMenu.constants' import { GlassPanelWithIconPicker } from '@/features/ui/GlassPanelWithIconPicker' import { IconPanelWithIconPicker } from '@/features/ui/IconPanelWithIconPicker' @@ -324,10 +323,10 @@ const HomePage = () => ( )}
-
-

+
+

Additional resources -

+

    @@ -351,17 +350,14 @@ const HomePage = () => (
{isFeatureEnabled('docs:full_getting_started') && (
-
+
- - - -

+

Self-Hosting -

+
-

+

Get started with self-hosting Supabase.

{ >
-
- - -

Getting Started

+
+

Getting Started

+

+ Set up and connect a database in just a few minutes. +

-

- Set up and connect a database in just a few minutes. -

From c54168842b36835e50299ef8fd3700371b239e6a Mon Sep 17 00:00:00 2001 From: Matt Rossman <22670878+mattrossman@users.noreply.github.com> Date: Tue, 16 Jun 2026 17:20:06 -0400 Subject: [PATCH 3/5] fix(assistant): prevent parallel approval-required tool calls (#47008) Addresses the issue of parallel tool approvals freezing Assistant and causing UX ambiguity around what happens if only part of multiple dependent invocations is approved. Two layers at which this is addressed: 1. Tightens prompt to clarify approval tools must be issued one per step, not in parallel. 2. In case something slips past the prompt, this also auto-denies all but the first `approval-required` tool call when the model issues multiple in the same step, so the model is forced to reissue them sequentially. **Demo** The following chats demo me explicitly asking Assistant to run those approval-gated tools in parallel, and the Assistant correctly invokes them sequentially instead. | Parallel `execute_sql` request | Parallel `deploy_edge_function` request | |--------|--------| | CleanShot 2026-06-16 at 16 20
23@2x | CleanShot 2026-06-16 at 16 22
59@2x | As shown in [this trace](https://www.braintrust.dev/app/supabase.io/p/Assistant/trace?object_type=project_logs&object_id=5a8d02e5-b3b6-40cc-ba76-ecee286478f4&r=a3a37857-95df-4a95-a5a8-818ea305b2a5&s=a3a37857-95df-4a95-a5a8-818ea305b2a5), parallel tool calls are still allowed for context gathering tools that don't require approval: CleanShot 2026-06-16 at 16 25 42@2x Closes AI-803 ## Summary by CodeRabbit * **Improvements** * Approval-required operations are now processed sequentially rather than in parallel within the AI Assistant. * **Tests** * Added comprehensive test coverage for the parallel approval prevention logic. --- .../ui/AIAssistantPanel/AIAssistant.tsx | 13 ++++ apps/studio/lib/ai/message-utils.test.ts | 78 ++++++++++++++++++- apps/studio/lib/ai/message-utils.ts | 16 +++- apps/studio/lib/ai/prompts.ts | 2 +- 4 files changed, 105 insertions(+), 4 deletions(-) diff --git a/apps/studio/components/ui/AIAssistantPanel/AIAssistant.tsx b/apps/studio/components/ui/AIAssistantPanel/AIAssistant.tsx index 2184f94a8e031..6b8848e44d741 100644 --- a/apps/studio/components/ui/AIAssistantPanel/AIAssistant.tsx +++ b/apps/studio/components/ui/AIAssistantPanel/AIAssistant.tsx @@ -39,6 +39,7 @@ import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage' import { useOrgAiOptInLevel } from '@/hooks/misc/useOrgOptedIntoAi' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' +import { getParallelApprovalIdsToReject } from '@/lib/ai/message-utils' import { DEFAULT_ASSISTANT_BASE_MODEL_ID, defaultAssistantModelId, @@ -366,6 +367,18 @@ export const AIAssistant = ({ className }: AIAssistantProps) => { } }, [isResubmitting, chatStatus, error]) + useEffect(() => { + // Approval-required tools can't run in parallel. Auto-deny extras so the model reissues them sequentially. + for (const id of getParallelApprovalIdsToReject(chatMessages)) { + addToolApprovalResponse?.({ + id, + approved: false, + reason: + 'Only one approval-required tool call is allowed per turn. Please reissue this tool call after the current one completes.', + }) + } + }, [chatMessages, addToolApprovalResponse]) + useEffect(() => { setValue(snap.initialInput || '') if (inputRef.current && snap.initialInput) { diff --git a/apps/studio/lib/ai/message-utils.test.ts b/apps/studio/lib/ai/message-utils.test.ts index 34502f43d2aad..0125996ddc766 100644 --- a/apps/studio/lib/ai/message-utils.test.ts +++ b/apps/studio/lib/ai/message-utils.test.ts @@ -1,7 +1,81 @@ -import type { UIMessage } from 'ai' +import type { DynamicToolUIPart, UIMessage } from 'ai' import { describe, expect, it } from 'vitest' -import { prepareMessagesForAPI } from './message-utils' +import { getParallelApprovalIdsToReject, prepareMessagesForAPI } from './message-utils' + +const makeApprovalPart = (id: string): DynamicToolUIPart => ({ + type: 'dynamic-tool', + toolName: 'test_tool', + toolCallId: id, + state: 'approval-requested', + input: {}, + approval: { id }, +}) + +const makeResultPart = (id: string): DynamicToolUIPart => ({ + type: 'dynamic-tool', + toolName: 'test_tool', + toolCallId: id, + state: 'output-available', + input: {}, + output: {}, +}) + +describe('getParallelApprovalIdsToReject', () => { + it('returns [] for empty messages', () => { + expect(getParallelApprovalIdsToReject([])).toEqual([]) + }) + + it('returns [] when there are no assistant messages', () => { + const messages: UIMessage[] = [{ id: '1', role: 'user', parts: [] }] + expect(getParallelApprovalIdsToReject(messages)).toEqual([]) + }) + + it('returns [] when last assistant message has no pending approvals', () => { + const messages: UIMessage[] = [{ id: '1', role: 'assistant', parts: [makeResultPart('r1')] }] + expect(getParallelApprovalIdsToReject(messages)).toEqual([]) + }) + + it('returns [] when there is only one pending approval', () => { + const messages: UIMessage[] = [{ id: '1', role: 'assistant', parts: [makeApprovalPart('a1')] }] + expect(getParallelApprovalIdsToReject(messages)).toEqual([]) + }) + + it('returns all but the first id when there are multiple pending approvals', () => { + const messages: UIMessage[] = [ + { + id: '1', + role: 'assistant', + parts: [makeApprovalPart('a1'), makeApprovalPart('a2'), makeApprovalPart('a3')], + }, + ] + expect(getParallelApprovalIdsToReject(messages)).toEqual(['a2', 'a3']) + }) + + it('only inspects the last assistant message', () => { + const messages: UIMessage[] = [ + { + id: '1', + role: 'assistant', + parts: [makeApprovalPart('old1'), makeApprovalPart('old2')], + }, + { id: '2', role: 'user', parts: [] }, + { id: '3', role: 'assistant', parts: [makeApprovalPart('new1')] }, + ] + expect(getParallelApprovalIdsToReject(messages)).toEqual([]) + }) + + it('ignores non-approval tool parts', () => { + const messages: UIMessage[] = [ + { + id: '1', + role: 'assistant', + parts: [makeResultPart('r1'), makeApprovalPart('a1'), makeApprovalPart('a2')], + }, + ] + expect(getParallelApprovalIdsToReject(messages)).toEqual(['a2']) + }) +}) describe('prepareMessagesForAPI', () => { it('should limit messages to last 7 entries', () => { diff --git a/apps/studio/lib/ai/message-utils.ts b/apps/studio/lib/ai/message-utils.ts index 2b0cbd6292496..d04e25b5c1d69 100644 --- a/apps/studio/lib/ai/message-utils.ts +++ b/apps/studio/lib/ai/message-utils.ts @@ -1,4 +1,4 @@ -import type { UIMessage } from 'ai' +import { isToolUIPart, type UIMessage } from 'ai' /** * Prepares messages for API transmission by cleaning and limiting history @@ -23,3 +23,17 @@ export function prepareMessagesForAPI(messages: UIMessage[]): UIMessage[] { return cleanedMessages } + +/** + * Returns approval IDs to auto-deny when the model issues multiple approval-required + * tool calls in the same turn — all but the first, so the model reissues them sequentially. + */ +export function getParallelApprovalIdsToReject(messages: UIMessage[]): string[] { + const lastMessage = messages.findLast((m) => m.role === 'assistant') + if (!lastMessage) return [] + + const pendingIds = (lastMessage.parts ?? []).flatMap((part) => + isToolUIPart(part) && part.state === 'approval-requested' ? [part.approval.id] : [] + ) + return pendingIds.slice(1) +} diff --git a/apps/studio/lib/ai/prompts.ts b/apps/studio/lib/ai/prompts.ts index 09f71fb4f5d2d..81c6f0435f605 100644 --- a/apps/studio/lib/ai/prompts.ts +++ b/apps/studio/lib/ai/prompts.ts @@ -733,7 +733,7 @@ export const CHAT_PROMPT = ` - On execution error, explain succinctly and attempt to correct if possible, validating each outcome briefly (1–2 lines) after execution. - If a user skips execution, acknowledge and suggest alternatives. - Use markdown code blocks (\`\`\`sql\`\`\`) for illustrative SQL only if requested by the user or when providing non-executable examples. -- Execute multiple queries separately via \`execute_sql\` and briefly validate outcomes. +- Never call \`execute_sql\` or \`deploy_edge_function\` in parallel within the same step. Each requires user approval, so issue one per step and wait for its result before calling the next. - After execution, summarize outcomes concisely without duplicating results, as the client will present these. ## Edge Functions - Deploy Edge Functions by calling \`deploy_edge_function\` directly with \`name\` and \`code\`; the client handles confirmation and result presentation. From 608040b8cb3f553d142d43d3f91eb6de89624559 Mon Sep 17 00:00:00 2001 From: Miranda Limonczenko Date: Tue, 16 Jun 2026 14:45:55 -0700 Subject: [PATCH 4/5] chore(docs) Resolve 'simple' style warnings where applicable (#46966) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Contributes to DOCS-1052 ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Resolves MDX linting errors related to "simple" where it applies. There was a couple cases that did not apply. For example, a product with "Simple" in the name. These changes are made in context, either by removing or using a more descriptive synonym like "minimal" or "basic". ## Tophatting 1. Read each of the diffs. 2. See that the text still makes sense in context. For extra due diligence, you can run `pnpm lint:mdx` locally and see the 'simple' errors that remain and whether they are worth addressing. ## Summary by CodeRabbit ## Summary by CodeRabbit * **Documentation** * Updated many guide, tutorial, and troubleshooting pages with clearer “basic”/“minimal” wording across setup steps, local testing instructions, security cautions, and RLS guidance. * Refined headings, example descriptions, and inline comments for consistency (including deployment, MCP, metrics API, and search/function phrasing). * Improved readability with small snippet formatting tweaks (whitespace plus import/comment ordering) and added a self-hosting debugging note for Envoy admin endpoints via a short-lived `curl` container. --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: Chris Chinchilla Co-authored-by: Nik Richers --- apps/docs/content/_partials/database_setup.mdx | 2 +- apps/docs/content/_partials/kotlin_project_setup.mdx | 2 +- apps/docs/content/_partials/metrics_access.mdx | 2 +- apps/docs/content/guides/ai-tools/byo-mcp.mdx | 6 ++++-- apps/docs/content/guides/ai.mdx | 8 ++++---- apps/docs/content/guides/ai/engineering-for-scale.mdx | 4 ++-- .../guides/ai/examples/building-chatgpt-plugins.mdx | 2 +- apps/docs/content/guides/ai/keyword-search.mdx | 2 +- apps/docs/content/guides/ai/langchain.mdx | 2 +- apps/docs/content/guides/ai/rag-with-permissions.mdx | 2 +- apps/docs/content/guides/auth/auth-mfa.mdx | 2 +- apps/docs/content/guides/auth/auth-mfa/totp.mdx | 2 +- apps/docs/content/guides/auth/auth-smtp.mdx | 2 +- apps/docs/content/guides/auth/server-side.mdx | 2 +- .../connecting-to-postgres/serverless-drivers.mdx | 2 +- apps/docs/content/guides/database/extensions/http.mdx | 4 ++-- .../docs/content/guides/database/extensions/hypopg.mdx | 2 +- .../content/guides/database/extensions/postgis.mdx | 4 ++-- .../content/guides/database/extensions/timescaledb.mdx | 2 +- apps/docs/content/guides/database/functions.mdx | 6 +++--- apps/docs/content/guides/database/partitions.mdx | 2 +- apps/docs/content/guides/database/postgres/indexes.mdx | 2 +- apps/docs/content/guides/database/tables.mdx | 2 +- apps/docs/content/guides/database/testing.mdx | 2 +- apps/docs/content/guides/deployment.mdx | 6 +++--- .../guides/deployment/shared-responsibility-model.mdx | 2 +- apps/docs/content/guides/functions.mdx | 2 +- apps/docs/content/guides/functions/architecture.mdx | 2 +- .../content/guides/functions/examples/discord-bot.mdx | 5 +++-- .../guides/functions/examples/mcp-server-mcp-lite.mdx | 2 +- .../content/guides/functions/recursive-functions.mdx | 4 ++-- apps/docs/content/guides/functions/routing.mdx | 2 +- apps/docs/content/guides/functions/unit-test.mdx | 2 +- apps/docs/content/guides/functions/wasm.mdx | 2 +- apps/docs/content/guides/getting-started/api-keys.mdx | 2 +- .../content/guides/getting-started/architecture.mdx | 4 ++-- apps/docs/content/guides/getting-started/features.mdx | 2 +- .../guides/getting-started/quickstarts/laravel.mdx | 2 +- .../guides/getting-started/quickstarts/sveltekit.mdx | 2 +- .../getting-started/tutorials/with-redwoodjs.mdx | 9 ++++----- .../guides/integrations/partner-integration-guide.mdx | 4 ++-- .../content/guides/integrations/vercel-marketplace.mdx | 2 +- .../local-development/cli/testing-and-linting.mdx | 2 +- .../guides/local-development/testing/overview.mdx | 4 ++-- .../local-development/testing/pgtap-extended.mdx | 4 ++-- apps/docs/content/guides/platform.mdx | 2 +- apps/docs/content/guides/realtime/broadcast.mdx | 6 +++--- apps/docs/content/guides/realtime/protocol.mdx | 2 +- .../realtime/subscribing-to-database-changes.mdx | 5 ++++- apps/docs/content/guides/resources/glossary.mdx | 2 +- apps/docs/content/guides/security.mdx | 2 +- .../content/guides/self-hosting/self-hosted-envoy.mdx | 2 +- .../guides/storage/uploads/standard-uploads.mdx | 4 +++- apps/docs/content/guides/telemetry/logs.mdx | 2 +- ...xceeds-btree-version-4-maximum-for-index-LMmoeU.mdx | 2 +- ...rom-supabase-auth-helpers-to-ssr-package-5NRunM.mdx | 2 +- apps/docs/content/troubleshooting/http-api-issues.mdx | 2 +- ...esponse-or-zgotmplz-in-magic-link-emails-433665.mdx | 2 +- .../troubleshooting/prisma-error-management-Cm5P_o.mdx | 2 +- .../troubleshooting/realtime-heartbeat-messages.mdx | 10 +++++----- .../troubleshooting/soft-deletes-with-supabase-js.mdx | 2 +- 61 files changed, 95 insertions(+), 88 deletions(-) diff --git a/apps/docs/content/_partials/database_setup.mdx b/apps/docs/content/_partials/database_setup.mdx index 92112438ddc26..09cac33af3c08 100644 --- a/apps/docs/content/_partials/database_setup.mdx +++ b/apps/docs/content/_partials/database_setup.mdx @@ -1,6 +1,6 @@ ## Project setup -Let's create a new Postgres database. This is as simple as starting a new Project in Supabase: +To create a new Postgres database, start a new Project in Supabase: 1. [Create a new project](https://database.new/) in the Supabase dashboard. 1. Enter your project details. Remember to store your password somewhere safe. diff --git a/apps/docs/content/_partials/kotlin_project_setup.mdx b/apps/docs/content/_partials/kotlin_project_setup.mdx index 1f32521eefd97..91b95ad86ecf5 100644 --- a/apps/docs/content/_partials/kotlin_project_setup.mdx +++ b/apps/docs/content/_partials/kotlin_project_setup.mdx @@ -1,6 +1,6 @@ ## Project setup -Before we start building we're going to set up our Database and API. This is as simple as starting a new Project in Supabase and then creating a "schema" inside the database. +Before building, you must set up your Database and API with a new Project in Supabase and then create a "schema" inside the database. ### Create a project diff --git a/apps/docs/content/_partials/metrics_access.mdx b/apps/docs/content/_partials/metrics_access.mdx index 853dcaac14a8d..2aa32d58aeecf 100644 --- a/apps/docs/content/_partials/metrics_access.mdx +++ b/apps/docs/content/_partials/metrics_access.mdx @@ -25,7 +25,7 @@ className="rounded-lg border border-foreground/10 bg-surface-100 text-foreground - **Username**: `service_role` - **Password**: a **Secret API key** (`sb_secret_...`). You can create/copy it in [**Project Settings → API Keys**](/dashboard/project/_/settings/api-keys). For more context, see [Understanding API keys](/docs/guides/getting-started/api-keys). - Testing locally is as simple as running `curl` with your Secret API key: + To test locally, run `curl` with your Secret API key: ```bash curl /customer/v1/privileged/metrics \ diff --git a/apps/docs/content/guides/ai-tools/byo-mcp.mdx b/apps/docs/content/guides/ai-tools/byo-mcp.mdx index 88e708a8c4b9a..2df8f11ed2309 100644 --- a/apps/docs/content/guides/ai-tools/byo-mcp.mdx +++ b/apps/docs/content/guides/ai-tools/byo-mcp.mdx @@ -75,7 +75,7 @@ const server = new McpServer({ version: '0.1.0', }) -// Register a simple addition tool +// Register an addition tool server.registerTool( 'add', { @@ -218,7 +218,9 @@ After this step, you have a fully deployed MCP server accessible from anywhere. You can find ready-to-use MCP server implementations here: -- [Simple MCP server](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/mcp/simple-mcp-server) - Basic unauthenticated example +{/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */} + +- [Simple MCP server](https://github.com/supabase/supabase/tree/master/examples/edge-functions/supabase/functions/mcp/simple-mcp-server) - Unauthenticated example ## Resources diff --git a/apps/docs/content/guides/ai.mdx b/apps/docs/content/guides/ai.mdx index 4fb8c15b66c40..5226d8849aa8b 100644 --- a/apps/docs/content/guides/ai.mdx +++ b/apps/docs/content/guides/ai.mdx @@ -109,8 +109,8 @@ Check out all of the AI [templates and examples](https://github.com/supabase/sup
- OpenAI is an AI research and deployment company. Supabase provides a simple way to use - OpenAI in your applications. + OpenAI is an AI research and deployment company. Supabase provides a way to use OpenAI in + your applications.
@@ -125,8 +125,8 @@ Check out all of the AI [templates and examples](https://github.com/supabase/sup
- Hugging Face is an open-source provider of NLP technologies. Supabase provides a simple way - to use Hugging Face's models in your applications. + Hugging Face is an open-source provider of NLP technologies. Supabase provides a way to use + Hugging Face's models in your applications.
diff --git a/apps/docs/content/guides/ai/engineering-for-scale.mdx b/apps/docs/content/guides/ai/engineering-for-scale.mdx index 55e8990507d8c..a9c74970bd751 100644 --- a/apps/docs/content/guides/ai/engineering-for-scale.mdx +++ b/apps/docs/content/guides/ai/engineering-for-scale.mdx @@ -8,9 +8,9 @@ sidebar_label: 'Engineering for Scale' Content sources for vectors can be extremely large. As you grow you should run your Vector workloads across several secondary databases (sometimes called "pods"), which allows each collection to scale independently. -## Simple workloads +## Small workloads [#simple-workloads] -For small workloads, it's typical to store your data in a single database. +For small workloads, you can typically store your data in a single database. If you've used [Vecs](/docs/guides/ai/vecs-python-client) to create 3 different collections, you can expose collections to your web or mobile application using [views](/docs/guides/database/tables#views): diff --git a/apps/docs/content/guides/ai/examples/building-chatgpt-plugins.mdx b/apps/docs/content/guides/ai/examples/building-chatgpt-plugins.mdx index b6dfa676b9dc6..8d6bc5eb3eede 100644 --- a/apps/docs/content/guides/ai/examples/building-chatgpt-plugins.mdx +++ b/apps/docs/content/guides/ai/examples/building-chatgpt-plugins.mdx @@ -20,7 +20,7 @@ It allows ChatGPT to dynamically pull relevant information into conversations fr ## Example: Chat with Postgres docs -Let’s build an example where we can “ask ChatGPT questions” about the Postgres documentation. Although ChatGPT already knows about the Postgres documentation because it is publicly available, this is a simple example which demonstrates how to work with PDF files. +Let’s build an example where we can “ask ChatGPT questions” about the Postgres documentation. Although ChatGPT already knows about the Postgres documentation because it is publicly available, this is a basic example which demonstrates how to work with PDF files. This plugin requires several steps: diff --git a/apps/docs/content/guides/ai/keyword-search.mdx b/apps/docs/content/guides/ai/keyword-search.mdx index 9ee0387783193..643fa08025f91 100644 --- a/apps/docs/content/guides/ai/keyword-search.mdx +++ b/apps/docs/content/guides/ai/keyword-search.mdx @@ -8,7 +8,7 @@ sidebar_label: 'Keyword search' Keyword search involves locating documents or records that contain specific words or phrases, primarily based on the exact match between the search terms and the text within the data. It differs from [semantic search](/docs/guides/ai/semantic-search), which interprets the meaning behind the query to provide results that are contextually related, even if the exact words aren't present in the text. Semantic search considers synonyms, intent, and natural language nuances to provide a more nuanced approach to information retrieval. -In Postgres, keyword search is implemented using [full-text search](/docs/guides/database/full-text-search). It supports indexing and text analysis for data retrieval, focusing on records that match the search criteria. Postgres' full-text search extends beyond simple keyword matching to address linguistic nuances, making it effective for applications that require precise text queries. +In Postgres, keyword search is implemented using [full-text search](/docs/guides/database/full-text-search). It supports indexing and text analysis for data retrieval, focusing on records that match the search criteria. Postgres' full-text search extends beyond keyword matching to address linguistic nuances, making it effective for applications that require precise text queries. ## When and why to use keyword search diff --git a/apps/docs/content/guides/ai/langchain.mdx b/apps/docs/content/guides/ai/langchain.mdx index b089cb4ab5eb0..09cf1c570fa15 100644 --- a/apps/docs/content/guides/ai/langchain.mdx +++ b/apps/docs/content/guides/ai/langchain.mdx @@ -108,7 +108,7 @@ export const run = async () => { } ``` -### Simple metadata filtering +### Basic metadata filtering [#simple-metadata-filtering] Given the above `match_documents` Postgres function, you can also pass a filter parameter to only return documents with a specific metadata field value. This filter parameter is a JSON object, and the `match_documents` function will use the Postgres JSONB Containment operator `@>` to filter documents by the metadata field values you specify. See details on the [Postgres JSONB Containment operator](https://www.postgresql.org/docs/current/datatype-json.html#JSON-CONTAINMENT) for more information. diff --git a/apps/docs/content/guides/ai/rag-with-permissions.mdx b/apps/docs/content/guides/ai/rag-with-permissions.mdx index 08c8ca7b021a5..4b2df595dce1f 100644 --- a/apps/docs/content/guides/ai/rag-with-permissions.mdx +++ b/apps/docs/content/guides/ai/rag-with-permissions.mdx @@ -231,7 +231,7 @@ order by document_sections.embedding <#> embedding; {/* supa-mdx-lint-disable-next-line Rule004ExcludeWords */} -You might be tempted to discard RLS completely and simply filter by user within the `where` clause. Though this will work, we recommend RLS as a general best practice since RLS is always applied even as new queries and application logic is introduced in the future. +You might be tempted to discard RLS completely and filter by user within the `where` clause. Though this will work, we recommend RLS as a general best practice since RLS is always applied even as new queries and application logic is introduced in the future. diff --git a/apps/docs/content/guides/auth/auth-mfa.mdx b/apps/docs/content/guides/auth/auth-mfa.mdx index 1cb3576ef18c0..542884c5aa879 100644 --- a/apps/docs/content/guides/auth/auth-mfa.mdx +++ b/apps/docs/content/guides/auth/auth-mfa.mdx @@ -127,7 +127,7 @@ Unenrolling a factor will downgrade the assurance level from `aal2` to `aal1` on ```tsx /** - * UnenrollMFA shows a simple table with the list of factors together with a button to unenroll. + * UnenrollMFA shows a table with the list of factors together with a button to unenroll. * When a user types in the factorId of the factor that they wish to unenroll and clicks unenroll * the corresponding factor will be unenrolled. */ diff --git a/apps/docs/content/guides/auth/auth-mfa/totp.mdx b/apps/docs/content/guides/auth/auth-mfa/totp.mdx index c645e15f681cf..c1869fbb097b1 100644 --- a/apps/docs/content/guides/auth/auth-mfa/totp.mdx +++ b/apps/docs/content/guides/auth/auth-mfa/totp.mdx @@ -75,7 +75,7 @@ Below is an example that creates a new `EnrollMFA` component that illustrates th ```tsx /** - * EnrollMFA shows a simple enrollment dialog. When shown on screen it calls + * EnrollMFA shows an enrollment dialog. When shown on screen it calls * the `enroll` API. Each time a user clicks the Enable button it calls the * `challenge` and `verify` APIs to check if the code provided by the user is * valid. diff --git a/apps/docs/content/guides/auth/auth-smtp.mdx b/apps/docs/content/guides/auth/auth-smtp.mdx index 2e4d9fefd334e..b43e261bda768 100644 --- a/apps/docs/content/guides/auth/auth-smtp.mdx +++ b/apps/docs/content/guides/auth/auth-smtp.mdx @@ -13,7 +13,7 @@ If you're using Supabase Auth with the following configuration: You will need to set up a custom SMTP server to handle the delivery of messages to your users. -To get you started and let you explore and set up email message templates for your application, Supabase provides a simple SMTP server for all projects. This server imposes a few important restrictions and is not meant for production use. +To get you started and let you explore and set up email message templates for your application, Supabase provides an SMTP server for all projects. This server imposes a few important restrictions and is not meant for production use. **Send messages only to pre-authorized addresses.** diff --git a/apps/docs/content/guides/auth/server-side.mdx b/apps/docs/content/guides/auth/server-side.mdx index 782db4bc501e6..81ae770cd4a7c 100644 --- a/apps/docs/content/guides/auth/server-side.mdx +++ b/apps/docs/content/guides/auth/server-side.mdx @@ -15,7 +15,7 @@ Make sure to use the PKCE flow instructions where those differ from the implicit ## `@supabase/ssr` -We have developed an [`@supabase/ssr`](https://www.npmjs.com/package/@supabase/ssr) package to make setting up the Supabase client as simple as possible. This package is currently in beta. Adoption is recommended but be aware that the API is still unstable and may have breaking changes in the future. +We have developed an [`@supabase/ssr`](https://www.npmjs.com/package/@supabase/ssr) package for setting up the Supabase client. This package is currently in beta. Adoption is recommended but be aware that the API is still unstable and may have breaking changes in the future. ## Framework quickstarts diff --git a/apps/docs/content/guides/database/connecting-to-postgres/serverless-drivers.mdx b/apps/docs/content/guides/database/connecting-to-postgres/serverless-drivers.mdx index 2459167434089..87a78a6f9260c 100644 --- a/apps/docs/content/guides/database/connecting-to-postgres/serverless-drivers.mdx +++ b/apps/docs/content/guides/database/connecting-to-postgres/serverless-drivers.mdx @@ -35,7 +35,7 @@ Choose one of these Vercel Deploy Templates which use our [Vercel Deploy Integra passHref > - Simple Next.js template that uses Supabase as the database and Kysely as the query builder. + Basic Next.js template that uses Supabase as the database and Kysely as the query builder.
diff --git a/apps/docs/content/guides/database/extensions/http.mdx b/apps/docs/content/guides/database/extensions/http.mdx index ed4052e62e0d0..f987f35493c9a 100644 --- a/apps/docs/content/guides/database/extensions/http.mdx +++ b/apps/docs/content/guides/database/extensions/http.mdx @@ -88,7 +88,7 @@ A successful call to a web URL from the `http` extension returns a record with t ## Examples -### Simple `GET` example +### Basic `GET` example [#simple-get-example] ```sql select @@ -97,7 +97,7 @@ from extensions.http_get('https://jsonplaceholder.typicode.com/todos/1'); ``` -### Simple `POST` example +### Basic `POST` example [#simple-post-example] ```sql select diff --git a/apps/docs/content/guides/database/extensions/hypopg.mdx b/apps/docs/content/guides/database/extensions/hypopg.mdx index 3a3875ef1394f..6bea2618227ea 100644 --- a/apps/docs/content/guides/database/extensions/hypopg.mdx +++ b/apps/docs/content/guides/database/extensions/hypopg.mdx @@ -45,7 +45,7 @@ It's good practice to create the extension within a separate schema (like `exten ### Speeding up a query -Given the following table and a simple query to select from the table by `id`: +Given the following table and a basic query to select from the table by `id`: {/* prettier-ignore */} ```sql diff --git a/apps/docs/content/guides/database/extensions/postgis.mdx b/apps/docs/content/guides/database/extensions/postgis.mdx index 599f65be591d2..61b14e05a4e1e 100644 --- a/apps/docs/content/guides/database/extensions/postgis.mdx +++ b/apps/docs/content/guides/database/extensions/postgis.mdx @@ -9,7 +9,7 @@ tocVideo: 'agFsGDJxjwA' ## Overview -While you may be able to store simple lat/long geographic coordinates as a set of decimals, it does not scale very well when you try to query through a large data set. PostGIS comes with special data types that are efficient, and indexable for high scalability. +While you may be able to store lat/long geographic coordinates as a set of decimals, it does not scale very well when you try to query through a large data set. PostGIS comes with special data types that are efficient, and indexable for high scalability. The additional data types that PostGIS provides include [Point](https://postgis.net/docs/using_postgis_dbmanagement.html#Point), [Polygon](https://postgis.net/docs/using_postgis_dbmanagement.html#Polygon), [LineString](https://postgis.net/docs/using_postgis_dbmanagement.html#LineString), and many more to represent different types of geographical data. In this guide, we will mainly focus on how to interact with `Point` type, which represents a single set of latitude and longitude. If you are interested in digging deeper, you can learn more about different data types on the [data management section of PostGIS docs](https://postgis.net/docs/using_postgis_dbmanagement.html). @@ -47,7 +47,7 @@ drop extension if exists postgis; ## Examples -Now that we are ready to get started with PostGIS, let’s create a table and see how we can utilize PostGIS for some typical use cases. Let’s imagine we are creating a simple restaurant-searching app. +Now that we are ready to get started with PostGIS, let’s create a table and see how we can use PostGIS for some typical use cases. Imagine we are creating a basic restaurant-searching app. Let’s create our table. Each row represents a restaurant with its location stored in `location` column as a `Point` type. diff --git a/apps/docs/content/guides/database/extensions/timescaledb.mdx b/apps/docs/content/guides/database/extensions/timescaledb.mdx index a3aa03036461c..abea2efc8396a 100644 --- a/apps/docs/content/guides/database/extensions/timescaledb.mdx +++ b/apps/docs/content/guides/database/extensions/timescaledb.mdx @@ -60,7 +60,7 @@ It's good practice to create the extension within a separate schema (like `exten ## Usage -To demonstrate how `timescaledb` works, let's consider a simple example where we have a table that stores temperature data from different sensors. We will create a table named "temperatures" and store data for two sensors. +To demonstrate how `timescaledb` works, consider a basic example where we have a table that stores temperature data from different sensors. We will create a table named "temperatures" and store data for two sensors. First we create a hypertable, which is a virtual table that is partitioned into chunks based on time intervals. The hypertable acts as a proxy for the actual table and makes it easy to query and manage time-series data. diff --git a/apps/docs/content/guides/database/functions.mdx b/apps/docs/content/guides/database/functions.mdx index abea38ae77d1f..5dac1acaa3e67 100644 --- a/apps/docs/content/guides/database/functions.mdx +++ b/apps/docs/content/guides/database/functions.mdx @@ -30,7 +30,7 @@ and run the SQL queries yourself. 3. Enter the SQL to create or replace your Database function. 4. Click "Run" or cmd+enter (ctrl+enter). -## Simple functions +## Basic functions [#simple-functions] Let's create a basic Database Function which returns a string "hello world". @@ -53,7 +53,7 @@ At it's most basic a function has the following parts: 2. `returns text`: The type of data that the function returns. If it returns nothing, you can `returns void`. 3. `language sql`: The language used inside the function body. This can also be a procedural language: `plpgsql`, `plpython`, etc. 4. `as $$`: The function wrapper. Anything enclosed inside the `$$` symbols will be part of the function body. -5. `select 'hello world';`: A simple function body. The final `select` statement inside a function body will be returned if there are no statements following it. +5. `select 'hello world';`: A basic function body. The final `select` statement inside a function body will be returned if there are no statements following it. 6. `$$;`: The closing symbols of the function wrapper. @@ -290,7 +290,7 @@ data = supabase.rpc('get_planets').eq('id', 1).execute() ## Passing parameters -Let's create a Function to insert a new planet into the `planets` table and return the new ID. Note that this time we're using the `plpgsql` language. +Create a function to insert a new planet into the `planets` table and return the new ID. Note that this time we're using the `plpgsql` language. ```sql create or replace function add_planet(name text) diff --git a/apps/docs/content/guides/database/partitions.mdx b/apps/docs/content/guides/database/partitions.mdx index 9019ea55e3499..73e9f3a2903dc 100644 --- a/apps/docs/content/guides/database/partitions.mdx +++ b/apps/docs/content/guides/database/partitions.mdx @@ -105,7 +105,7 @@ There is no real threshold to determine when you should use partitions. Partitio ## Examples -Here are simple examples for each of the partitioning types in Postgres. +Here are basic examples for each of the partitioning types in Postgres. ### Range partitioning diff --git a/apps/docs/content/guides/database/postgres/indexes.mdx b/apps/docs/content/guides/database/postgres/indexes.mdx index d0b36b77bf0be..a4a33e4ab6a97 100644 --- a/apps/docs/content/guides/database/postgres/indexes.mdx +++ b/apps/docs/content/guides/database/postgres/indexes.mdx @@ -53,7 +53,7 @@ Seq Scan on persons (cost=0.00..22.75 rows=x width=y) Filter: (age = 32) ``` -To add a simple B-Tree index you can run: +To add a basic B-Tree index you can run: ```sql create index idx_persons_age on persons (age); diff --git a/apps/docs/content/guides/database/tables.mdx b/apps/docs/content/guides/database/tables.mdx index 4f284bc1dd5f8..79c3a43e0facc 100644 --- a/apps/docs/content/guides/database/tables.mdx +++ b/apps/docs/content/guides/database/tables.mdx @@ -92,7 +92,7 @@ You must define the "data type" when you create a column. ### Data types -Every column is a predefined type. Postgres provides many [default types](https://www.postgresql.org/docs/current/datatype.html), and you can even design your own (or use extensions) if the default types don't fit your needs. You can use any data type that Postgres supports via the SQL editor. We only support a subset of these in the Table Editor in an effort to keep the experience simple for people with less experience with databases. +Every column is a predefined type. Postgres provides many [default types](https://www.postgresql.org/docs/current/datatype.html), and you can even design your own (or use extensions) if the default types don't fit your needs. You can use any data type that Postgres supports via the SQL editor. We only support a subset of these in the Table Editor in an effort to keep the experience focused for people with less experience with databases.
Show/Hide default data types diff --git a/apps/docs/content/guides/database/testing.mdx b/apps/docs/content/guides/database/testing.mdx index 8054ecc2b7fdd..a4e93b38eeb55 100644 --- a/apps/docs/content/guides/database/testing.mdx +++ b/apps/docs/content/guides/database/testing.mdx @@ -34,7 +34,7 @@ touch ./supabase/tests/database/hello_world.test.sql All `sql` files use [pgTAP](/docs/guides/database/extensions/pgtap) as the test runner. -Let's write a simple test to check that our `auth.users` table has an ID column. Open `hello_world.test.sql` and add the following code: +Write a test to check that our `auth.users` table has an ID column. Open `hello_world.test.sql` and add the following code: ```sql begin; diff --git a/apps/docs/content/guides/deployment.mdx b/apps/docs/content/guides/deployment.mdx index cea5ad0ff4a0d..5fc4a55cf77e1 100644 --- a/apps/docs/content/guides/deployment.mdx +++ b/apps/docs/content/guides/deployment.mdx @@ -4,11 +4,11 @@ title: Deployment & Branching Deploying your app makes it live and accessible to users. Most apps have at least two environments: a production environment for users and one or more staging or preview environments for development. -Supabase provides flexible options for both simple and advanced deployment workflows. +Supabase provides flexible options for deployment workflows of various complexity. ## Recommended workflow -The simplest way to deploy your Supabase project is with GitHub (recommended, but not required): +You can deploy your Supabase project with GitHub: 1. Develop locally using the [Supabase CLI](/docs/guides/local-development) 2. Push changes to your GitHub repository @@ -41,7 +41,7 @@ You can automate deployments using: ### Is GitHub required? -No. GitHub integration is recommended for the simplest setup, but you can deploy using the [Supabase CLI](/docs/guides/local-development) in your own CI/CD pipeline without connecting a GitHub repository. +No. GitHub integration is recommended, but you can deploy using the [Supabase CLI](/docs/guides/local-development) in your own CI/CD pipeline without connecting a GitHub repository. ### Do you need a paid plan? diff --git a/apps/docs/content/guides/deployment/shared-responsibility-model.mdx b/apps/docs/content/guides/deployment/shared-responsibility-model.mdx index adc1ec62ebd47..41c934fd0088c 100644 --- a/apps/docs/content/guides/deployment/shared-responsibility-model.mdx +++ b/apps/docs/content/guides/deployment/shared-responsibility-model.mdx @@ -69,7 +69,7 @@ If your application architecture relies on such integrations, you should monitor ## You choose your level of comfort with Postgres -Our goal at Supabase is to make _all_ of Postgres easy to use. That doesn’t mean you have to use all of it. If you’re a Postgres veteran, you’ll probably love the tools that we offer. If you’ve never used Postgres before, then start smaller and grow into it. If you just want to treat Postgres like a simple table-store, that’s perfectly fine. +Our goal at Supabase is to make _all_ of Postgres easy to use. That doesn’t mean you have to use all of it. If you’re a Postgres veteran, you’ll probably love the tools that we offer. If you’ve never used Postgres before, then start smaller and grow into it. If you want to treat Postgres like a basic table-store, that’s perfectly fine. ## You are in control of your database diff --git a/apps/docs/content/guides/functions.mdx b/apps/docs/content/guides/functions.mdx index 718391265321a..87d1b7f42e492 100644 --- a/apps/docs/content/guides/functions.mdx +++ b/apps/docs/content/guides/functions.mdx @@ -25,7 +25,7 @@ Edge Functions are server-side TypeScript functions, distributed globally at the ## Quick technical notes -- **Runtime:** Supabase Edge Runtime (Deno compatible runtime with TypeScript first). Functions are simple `.ts` files that export a handler. +- **Runtime:** Supabase Edge Runtime (Deno compatible runtime with TypeScript first). Functions are `.ts` files that export a handler. - **Local dev parity:** Use Supabase CLI for a local runtime similar to production for faster iteration (`supabase functions serve` command). - **Global deployment:** Deploy your Edge Functions via Supabase Dashboard, CLI or MCP. - **Cold starts & concurrency:** cold starts are possible — design for short-lived, idempotent operations. Heavy long-running jobs should be moved to [background workers](/docs/guides/functions/background-tasks). diff --git a/apps/docs/content/guides/functions/architecture.mdx b/apps/docs/content/guides/functions/architecture.mdx index 5bb5eb07f0883..219233e37f6d6 100644 --- a/apps/docs/content/guides/functions/architecture.mdx +++ b/apps/docs/content/guides/functions/architecture.mdx @@ -24,7 +24,7 @@ To illustrate how edge functions operate, consider a photo-sharing app where use - **Why Edge Functions?**: - They handle compute-intensive tasks without burdening the client device or the database. - Execution happens server-side but at the edge, ensuring speed and scalability. - - Developers define the function in a simple JavaScript file within the Supabase functions directory. + - Developers define the function in a JavaScript file within the Supabase functions directory. This example highlights edge functions as lightweight, on-demand code snippets that integrate seamlessly with Supabase services like Storage and Auth. diff --git a/apps/docs/content/guides/functions/examples/discord-bot.mdx b/apps/docs/content/guides/functions/examples/discord-bot.mdx index aa00105e557a8..085e109716b48 100644 --- a/apps/docs/content/guides/functions/examples/discord-bot.mdx +++ b/apps/docs/content/guides/functions/examples/discord-bot.mdx @@ -43,12 +43,13 @@ This will register a Slash Command named `hello` that accepts a parameter named ```ts index.ts // Sift is a small routing library that abstracts away details like starting a -// listener on a port, and provides a simple function (serve) that has an API +// listener on a port, and provides a function (serve) that has an API // to invoke a function for a specific path. -import { json, serve, validateRequest } from 'https://deno.land/x/sift@0.6.0/mod.ts' + // TweetNaCl is a cryptography library that we use to verify requests // from Discord. import nacl from 'https://cdn.skypack.dev/tweetnacl@v1.0.3?dts' +import { json, serve, validateRequest } from 'https://deno.land/x/sift@0.6.0/mod.ts' enum DiscordCommandType { Ping = 1, diff --git a/apps/docs/content/guides/functions/examples/mcp-server-mcp-lite.mdx b/apps/docs/content/guides/functions/examples/mcp-server-mcp-lite.mdx index f81fe9b86f615..fc22b0f717a05 100644 --- a/apps/docs/content/guides/functions/examples/mcp-server-mcp-lite.mdx +++ b/apps/docs/content/guides/functions/examples/mcp-server-mcp-lite.mdx @@ -21,7 +21,7 @@ This combination offers several advantages: - **Direct database access**: Connect directly to your Supabase Postgres - **Minimal footprint**: mcp-lite has zero runtime dependencies - **Full type safety**: TypeScript support in Deno -- **Simple deployment**: One command to production +- **Basic deployment**: One command to production ## Prerequisites diff --git a/apps/docs/content/guides/functions/recursive-functions.mdx b/apps/docs/content/guides/functions/recursive-functions.mdx index ad28b050c1e85..d661924efd16e 100644 --- a/apps/docs/content/guides/functions/recursive-functions.mdx +++ b/apps/docs/content/guides/functions/recursive-functions.mdx @@ -256,7 +256,7 @@ export async function save(data: any) { ```typescript // supabase/functions/process-data/index.ts -import { validate, transform, save } from '../_shared/transform.ts' +import { save, transform, validate } from '../_shared/transform.ts' Deno.serve(async (req) => { const data = await req.json() @@ -284,7 +284,7 @@ async function processWithDelay(items: any[]) { | Pattern | Budget consumption | Recommendation | | ------------------------------- | ------------------ | ----------------- | -| Simple chain (A to B to C) | Low | Generally safe | +| Basic chain (A to B to C) | Low | Generally safe | | Fan-out (A to B, C, D, E) | Moderate | Limit concurrency | | Deep recursion (A to A to A...) | High | Set max depth | | Unbounded loops | Very high | Avoid, use queues | diff --git a/apps/docs/content/guides/functions/routing.mdx b/apps/docs/content/guides/functions/routing.mdx index 3e112ee2d20a4..b6c084fe134c8 100644 --- a/apps/docs/content/guides/functions/routing.mdx +++ b/apps/docs/content/guides/functions/routing.mdx @@ -27,7 +27,7 @@ To combine multiple endpoints into a single Edge Function, you can use web appli ## Basic routing example -Here's a simple hello world example using some popular web frameworks: +Here's a basic hello world example using some popular web frameworks: { if (!supabaseUrl) throw new Error('supabaseUrl is required.') if (!supabaseKey) throw new Error('supabaseKey is required.') - // Test a simple query to the database + // Test a query to the database const { data: table_data, error: table_error } = await client .from('my_table') .select('*') diff --git a/apps/docs/content/guides/functions/wasm.mdx b/apps/docs/content/guides/functions/wasm.mdx index c8377bc6e10b8..fe7e5f61ece21 100644 --- a/apps/docs/content/guides/functions/wasm.mdx +++ b/apps/docs/content/guides/functions/wasm.mdx @@ -20,7 +20,7 @@ For example, libraries like [magick-wasm](/docs/guides/functions/examples/image- ### Writing a Wasm module -You can use different languages and SDKs to write Wasm modules. For this tutorial, we will write a simple Wasm module in Rust that adds two numbers. +You can use different languages and SDKs to write Wasm modules. For this tutorial, we will write a basic Wasm module in Rust that adds two numbers. diff --git a/apps/docs/content/guides/getting-started/api-keys.mdx b/apps/docs/content/guides/getting-started/api-keys.mdx index 696c9578bbe04..3ca3976f52a17 100644 --- a/apps/docs/content/guides/getting-started/api-keys.mdx +++ b/apps/docs/content/guides/getting-started/api-keys.mdx @@ -89,7 +89,7 @@ Never expose your secret keys publicly. Your data is at risk. **Do not:** - Never use in a browser, even on `localhost`. - Do not pass in URLs or query params, as these are often logged. - Be careful passing them in request headers without prior log sanitization. -- Take extra care logging even potentially **invalid API keys**. Simple typos might reveal the real key in the future. +- Take extra care logging even potentially **invalid API keys**. Typos might reveal the real key in the future. - Reveal, copy, use or manipulate on hardware devices without full disk encryption and which you do not directly own or control (such as public computers, friend's laptop, etc.) Ensure you handle them with care and using [secure coding practices](https://owasp.org/www-project-secure-coding-practices-quick-reference-guide/stable-en/). diff --git a/apps/docs/content/guides/getting-started/architecture.mdx b/apps/docs/content/guides/getting-started/architecture.mdx index e75cd4ab38b30..0e8767f5c3ad0 100644 --- a/apps/docs/content/guides/getting-started/architecture.mdx +++ b/apps/docs/content/guides/getting-started/architecture.mdx @@ -4,7 +4,7 @@ description: 'Supabase design and architecture' tocVideo: 'T-qAtAKjqwc' --- -Supabase is open source. We choose open source tools which are scalable and make them simple to use. +Supabase is open source. We choose open source tools which are scalable and make them approachable. Supabase is not a 1-to-1 mapping of Firebase. While we are building many of the features that Firebase offers, we are not going about it the same way: our technological choices are quite different; everything we use is open source; and wherever possible, we use and support existing tools rather than developing from scratch. @@ -13,7 +13,7 @@ Most notably, we use Postgres rather than a NoSQL store. This choice was deliber ## Choose your comfort level -Our goal at Supabase is to make _all_ of Postgres easy to use. That doesn’t mean you have to use all of it. If you’re a Postgres veteran, you’ll probably love the tools that we offer. If you’ve never used Postgres before, then start smaller and grow into it. If you just want to treat Postgres like a simple table-store, that’s perfectly fine. +Our goal at Supabase is to make _all_ of Postgres easy to use. That doesn’t mean you have to use all of it. If you’re a Postgres veteran, you’ll probably love the tools that we offer. If you’ve never used Postgres before, then start smaller and grow into it. If you want to treat Postgres like a basic table-store, that’s perfectly fine. ## Architecture diff --git a/apps/docs/content/guides/getting-started/features.mdx b/apps/docs/content/guides/getting-started/features.mdx index 8dcb43769e0a8..d27f2ca8a6d41 100644 --- a/apps/docs/content/guides/getting-started/features.mdx +++ b/apps/docs/content/guides/getting-started/features.mdx @@ -128,7 +128,7 @@ Helpers for implementing user authentication in popular server-side languages an ### File storage -Supabase Storage makes it simple to store and serve files. [Docs](/docs/guides/storage). +Supabase Storage helps you store and serve files. [Docs](/docs/guides/storage). ### Content Delivery Network diff --git a/apps/docs/content/guides/getting-started/quickstarts/laravel.mdx b/apps/docs/content/guides/getting-started/quickstarts/laravel.mdx index 381caecf2e5d8..6e7744279bf27 100644 --- a/apps/docs/content/guides/getting-started/quickstarts/laravel.mdx +++ b/apps/docs/content/guides/getting-started/quickstarts/laravel.mdx @@ -29,7 +29,7 @@ hideToc: true - Install [Laravel Breeze](https://laravel.com/docs/10.x/starter-kits#laravel-breeze), a simple implementation of all of Laravel's [authentication features](https://laravel.com/docs/10.x/authentication). + Install [Laravel Breeze](https://laravel.com/docs/10.x/starter-kits#laravel-breeze), a basic implementation of all of Laravel's [authentication features](https://laravel.com/docs/10.x/authentication). diff --git a/apps/docs/content/guides/getting-started/quickstarts/sveltekit.mdx b/apps/docs/content/guides/getting-started/quickstarts/sveltekit.mdx index 16fff4527d83d..30be6126edc16 100644 --- a/apps/docs/content/guides/getting-started/quickstarts/sveltekit.mdx +++ b/apps/docs/content/guides/getting-started/quickstarts/sveltekit.mdx @@ -112,7 +112,7 @@ hideToc: true - Use `load` method to fetch the data server-side and display the query results as a simple list. + Use `load` method to fetch the data server-side and display the query results as a list. Create `+page.server.js` file in the `src/routes` directory with the following code. diff --git a/apps/docs/content/guides/getting-started/tutorials/with-redwoodjs.mdx b/apps/docs/content/guides/getting-started/tutorials/with-redwoodjs.mdx index 18f4af415211b..36482c6e839f3 100644 --- a/apps/docs/content/guides/getting-started/tutorials/with-redwoodjs.mdx +++ b/apps/docs/content/guides/getting-started/tutorials/with-redwoodjs.mdx @@ -28,7 +28,7 @@ Important: When this guide refers to "API," that means the Supabase API and when The **`api side`** is an implementation of a GraphQL API. The business logic is organized into "services" that represent their own internal API and can be called both from external GraphQL requests and other internal services. -The **`web side`** is built with React. Redwood's router makes it simple to map URL paths to React "Page" components (and automatically code-split your app on each route). +The **`web side`** is built with React. Redwood's router lets you map URL paths to React "Page" components (and automatically code-split your app on each route). Pages may contain a "Layout" component to wrap content. They also contain "Cells" and regular React components. Cells allow you to declaratively manage the lifecycle of a component that fetches and displays data. @@ -249,8 +249,8 @@ Now, update the `Auth.js` component to contain: <$CodeTabs> ```jsx name=/web/src/components/Auth/Auth.js -import { useState } from 'react' import { useAuth } from '@redwoodjs/auth' +import { useState } from 'react' const Auth = () => { const { logIn } = useAuth() @@ -326,8 +326,8 @@ And then update the file to contain: <$CodeTabs> ```jsx name=web/src/components/Account/Account.js -import { useState, useEffect } from 'react' import { useAuth } from '@redwoodjs/auth' +import { useEffect, useState } from 'react' const Account = () => { const { client: supabase, currentUser, logOut } = useAuth() @@ -464,7 +464,6 @@ With all the components in place, update your `HomePage` page to use them: ```jsx name=web/src/pages/HomePage/HomePage.js import { useAuth } from '@redwoodjs/auth' import { MetaTags } from '@redwoodjs/web' - import Account from 'src/components/Account' import Auth from 'src/components/Auth' @@ -511,8 +510,8 @@ Now, update your Avatar component to contain the following widget: <$CodeTabs> ```jsx name=web/src/components/Avatar/Avatar.js -import { useEffect, useState } from 'react' import { useAuth } from '@redwoodjs/auth' +import { useEffect, useState } from 'react' const Avatar = ({ url, size, onUpload }) => { const { client: supabase } = useAuth() diff --git a/apps/docs/content/guides/integrations/partner-integration-guide.mdx b/apps/docs/content/guides/integrations/partner-integration-guide.mdx index 74ff3e28eebe7..3cf4bd5672658 100644 --- a/apps/docs/content/guides/integrations/partner-integration-guide.mdx +++ b/apps/docs/content/guides/integrations/partner-integration-guide.mdx @@ -9,12 +9,12 @@ This guide assumes you have already followed [the Build a Supabase Integration g When a Supabase user clicks the **Install Integration** button in the Dashboard, they are redirected to your system to begin the OAuth flow. You can implement this redirect in one of two ways: -- **[Simple redirect](#method-1-simple-redirect)**: Easier to build, but your system cannot verify that the incoming user was sent by Supabase. +- **[Redirect](#method-1-redirect)**: Easier to build, but your system cannot verify that the incoming user was sent by Supabase. - **[Signed redirect](#method-2-signed-redirect)**: More work to build, but cryptographically verifies that the redirect originated from Supabase. **Recommended for production integrations.** Pick the method that fits your security requirements, then follow the matching section below. -## Method 1: Simple redirect +## Method 1: Redirect In this method, you implement a single `GET` endpoint. Supabase redirects the user to this endpoint when they click **Install Integration**, and your endpoint kicks off the OAuth flow. diff --git a/apps/docs/content/guides/integrations/vercel-marketplace.mdx b/apps/docs/content/guides/integrations/vercel-marketplace.mdx index 8471fd1cdd442..35c554d169534 100644 --- a/apps/docs/content/guides/integrations/vercel-marketplace.mdx +++ b/apps/docs/content/guides/integrations/vercel-marketplace.mdx @@ -58,7 +58,7 @@ These variables ensure your applications can connect securely to the database an ## Studio support -Accessing Supabase Studio is simple through the Vercel dashboard. You can open Supabase Studio from either the Integration installation page or the Vercel Storage page. +Open Supabase Studio from the Vercel dashboard. You can access it from either the Integration installation page or the Vercel Storage page. Depending on your entry point, you'll either land on the Supabase dashboard homepage or be redirected to the corresponding Supabase Project. Supabase Studio provides tools such as: diff --git a/apps/docs/content/guides/local-development/cli/testing-and-linting.mdx b/apps/docs/content/guides/local-development/cli/testing-and-linting.mdx index 017961afb7c00..2fc83fe1ee915 100644 --- a/apps/docs/content/guides/local-development/cli/testing-and-linting.mdx +++ b/apps/docs/content/guides/local-development/cli/testing-and-linting.mdx @@ -44,7 +44,7 @@ By default, Mailpit is available at [localhost:54324](http://localhost:54324) wh ### Going into production -The "default" email provided by Supabase is only for development purposes. It is [heavily restricted](/docs/guides/platform/going-into-prod#auth-rate-limits) to ensure that it is not used for spam. Before going into production, you must configure your own email provider. This is as simple as enabling a new SMTP credentials in your [project settings](/dashboard/project/_/auth/smtp). +The "default" email provided by Supabase is only for development purposes. It is [heavily restricted](/docs/guides/platform/going-into-prod#auth-rate-limits) to ensure that it is not used for spam. Before going into production, configure your own email provider by enabling SMTP credentials in your [project settings](/dashboard/project/_/auth/smtp). ## Linting your database diff --git a/apps/docs/content/guides/local-development/testing/overview.mdx b/apps/docs/content/guides/local-development/testing/overview.mdx index 8c4624a92a639..9b0e3ac7e09f5 100644 --- a/apps/docs/content/guides/local-development/testing/overview.mdx +++ b/apps/docs/content/guides/local-development/testing/overview.mdx @@ -17,12 +17,12 @@ Testing is a critical part of database development, especially when working with - Functions and procedures - Data integrity -This example demonstrates setting up and testing RLS policies for a simple todo application: +This example demonstrates setting up and testing RLS policies for a basic todo application: 1. Create a test table with RLS enabled: ```sql - -- Create a simple todos table + -- Create a todos table create table todos ( id uuid primary key default gen_random_uuid(), task text not null, diff --git a/apps/docs/content/guides/local-development/testing/pgtap-extended.mdx b/apps/docs/content/guides/local-development/testing/pgtap-extended.mdx index b7bbefecbea95..6401ab340f421 100644 --- a/apps/docs/content/guides/local-development/testing/pgtap-extended.mdx +++ b/apps/docs/content/guides/local-development/testing/pgtap-extended.mdx @@ -83,7 +83,7 @@ The test helpers package provides several advantages over writing raw pgTAP test ## Schema-wide Row Level Security testing -When working with Row Level Security, it's crucial to ensure that RLS is enabled on all tables that need it. Create a simple test to verify RLS is enabled across an entire schema: +When working with Row Level Security, it's crucial to ensure that RLS is enabled on all tables that need it. Create a basic test to verify RLS is enabled across an entire schema: ```sql begin; @@ -112,7 +112,7 @@ This setup file should contain: 1. All shared extensions and dependencies 2. Common test utilities -3. A simple always green test to verify the setup +3. A basic always-green test to verify the setup Here's an example setup file: diff --git a/apps/docs/content/guides/platform.mdx b/apps/docs/content/guides/platform.mdx index f4c58fe84a09b..3953d8a1862a6 100644 --- a/apps/docs/content/guides/platform.mdx +++ b/apps/docs/content/guides/platform.mdx @@ -5,7 +5,7 @@ description: 'Getting started with the Supabase Platform.' sidebar_label: 'Overview' --- -Supabase is a hosted platform which makes it very simple to get started without needing to manage any infrastructure. +Supabase is a hosted platform that allows you to get started without needing to manage any infrastructure. Visit [supabase.com/dashboard](/dashboard) and sign in to start creating projects. diff --git a/apps/docs/content/guides/realtime/broadcast.mdx b/apps/docs/content/guides/realtime/broadcast.mdx index 6714da11ecac9..41dc5b96aea75 100644 --- a/apps/docs/content/guides/realtime/broadcast.mdx +++ b/apps/docs/content/guides/realtime/broadcast.mdx @@ -153,7 +153,7 @@ Binary payloads (`ArrayBuffer` / `ArrayBufferView`) are received automatically f // Join a room/topic. Can be anything except for 'realtime'. const myChannel = supabase.channel('test-channel') - // Simple function to log any messages we receive + // Function to log any messages we receive function messageReceived(payload) { console.log(payload) } @@ -176,7 +176,7 @@ Binary payloads (`ArrayBuffer` / `ArrayBufferView`) are received automatically f ```dart final myChannel = supabase.channel('test-channel'); - // Simple function to log any messages we receive + // Log any messages we receive void messageReceived(payload) { print(payload); } @@ -241,7 +241,7 @@ Binary payloads (`ArrayBuffer` / `ArrayBufferView`) are received automatically f # Join a room/topic. Can be anything except for 'realtime'. my_channel = supabase.channel('test-channel') - # Simple function to log any messages we receive + # Function to log any messages we receive def message_received(payload): print(f"Broadcast received: {payload}") diff --git a/apps/docs/content/guides/realtime/protocol.mdx b/apps/docs/content/guides/realtime/protocol.mdx index 5170749dfc2a5..05c524e642b9d 100644 --- a/apps/docs/content/guides/realtime/protocol.mdx +++ b/apps/docs/content/guides/realtime/protocol.mdx @@ -35,7 +35,7 @@ Messages can be serialized in different formats. The Realtime protocol supports ## 1.0.0 -Version 1.0.0 is extremely simple. It uses JSON as the serialization format for messages. The underlying WebSocket messages are all text frames. +Version 1.0.0 is minimal. It uses JSON as the serialization format for messages. The underlying WebSocket messages are all text frames. Messages contain the following fields: diff --git a/apps/docs/content/guides/realtime/subscribing-to-database-changes.mdx b/apps/docs/content/guides/realtime/subscribing-to-database-changes.mdx index 9984e94d6c229..a32e5609e261b 100644 --- a/apps/docs/content/guides/realtime/subscribing-to-database-changes.mdx +++ b/apps/docs/content/guides/realtime/subscribing-to-database-changes.mdx @@ -73,6 +73,7 @@ Finally, on the client side, listen to the topic `topic:` to receive ```js import { createClient } from '@supabase/supabase-js' + const supabase = createClient('your_project_url', 'your_supabase_api_key') // ---cut--- @@ -90,7 +91,7 @@ const changes = supabase ## Using Postgres Changes -Postgres Changes are simple to use, but have some [limitations](/docs/guides/realtime/postgres-changes#limitations) as your application scales. We recommend using Broadcast for most use cases. +Postgres Changes require minimal setup, but have some [limitations](/docs/guides/realtime/postgres-changes#limitations) as your application scales. We recommend using Broadcast for most use cases.