fix(studio): clean up onboarding returnTo paths (#49283)

## What kind of change does this PR introduce?

Bug fix. Follow-up to #41041 and DEPR-318.

## What is the current behavior?

Marketing "Start your project" links go to `/dashboard`, which redirects
unauthenticated users to `/org` and sets `returnTo=/org`. That value
survives when they switch from sign-in to sign-up, so email verification
still lands on the org list instead of org creation.

## What is the new behavior?

- Sign-in's **Sign up** link rewrites `returnTo=/org` (and
`/organizations`) to `/new`
- Docs mobile menu, www homepage/product CTAs, and solution page CTAs
link to `/dashboard/sign-up` for guests
- Signed-in visitors get the dashboard URL instead, so they never hit
the sign-up form
- Shared `DASHBOARD_SIGN_UP_URL` / `getDashboardCtaHref` helpers for www

Stacked on #41041.

## To test

Stacked on #41041. The studio preview below includes both PRs. www and
docs have their own previews.

### Studio: sign-in → sign-up rewrite

Using the [studio-staging
preview](https://studio-staging-git-dnywh-fixonboarding-return-to-supabase.vercel.app/)
from Vercel checks:

1. Open the preview while logged out. It should land on
`/dashboard/sign-in?returnTo=%2Forg`
2. Click **Sign up**. Expect the URL to include `returnTo=%2Fnew`

### Optional: www CTAs

Using the [www
preview](https://zone-www-dot-com-git-dnywh-fixonboarding-return-to-supabase.vercel.app/):

3. Logged out: homepage, product, or solutions **Start your project**
should go to `/dashboard/sign-up`
4. Logged in: the same CTAs should go to `/dashboard` (not sign-up)
(thought this will be hard if not impossible to test on staging)

### Optional: docs CTAs

Using the [docs
preview](https://docs-git-dnywh-fixonboarding-return-to-supabase.vercel.app/):

5. On mobile nav while logged out, click **Start your project**. Expect
`/dashboard/sign-up`

### Compare on supabase.green

Optional. Just to show what happens currently on `master`:

6. Open **supabase.green** while logged out, then click **Sign up** from
`/dashboard/sign-in?returnTo=%2Forg`. `returnTo` should stay as `/org`

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Start-project and sign-up links now direct visitors to registration
while signed-in users continue to reach the dashboard.
* Homepage, product, solution, and mobile navigation CTAs now provide
consistent authentication-aware destinations.
* Sign-up links preserve return destinations and existing navigation
parameters.

* **Bug Fixes**
* Corrected mobile navigation and marketing CTA links that previously
sent visitors to the dashboard root instead of the appropriate sign-up
flow.


<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Danny White authored and GitHub committed 2026-08-24 17:32:56 +10:00
1 parent ee931e49a1
commit fdf33e72c4
32 files changed
+215 -115

No files matched your search

@@ -168,7 +168,9 @@ const GlobalMobileMenu = ({ open, setOpen }: Props) => {
<Link href="https://supabase.com/dashboard/sign-in">Sign in</Link>
</Button>
<Button block size="medium" asChild>
<Link href="https://supabase.com/dashboard/new">Start your project</Link>
<Link href="https://supabase.com/dashboard/sign-up">
Start your project
</Link>
</Button>
</>
)}
+5 -1
View File
@@ -16,6 +16,7 @@ import { useInboundBranding } from '@/hooks/misc/useInboundBranding'
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
import { IS_PLATFORM } from '@/lib/constants'
import type { ExternalIdentityProviderConfig } from '@/lib/external-identity-providers'
import { getSignUpReturnTo } from '@/lib/gotrue'
import type { NextPageWithLayout } from '@/types'
const SignInPage: NextPageWithLayout = () => {
@@ -131,7 +132,10 @@ const SignInPage: NextPageWithLayout = () => {
<div className="self-center my-8 text-sm">
<span className="text-foreground-light">Don’t have an account?</span>{' '}
<Link
href={{ pathname: '/sign-up', query: router.query }}
href={{
pathname: '/sign-up',
query: { ...router.query, returnTo: getSignUpReturnTo(router.query.returnTo) },
}}
className="underline transition text-foreground hover:text-foreground-light"
>
Sign up
@@ -1,10 +1,14 @@
'use client'
import { useSendTelemetryEvent } from '~/lib/telemetry'
import { useIsLoggedIn } from 'common'
import Link from 'next/link'
import { Button } from 'ui'
import { getDashboardCtaHref } from '@/lib/dashboard-links'
export function CTASection() {
const isLoggedIn = useIsLoggedIn()
const sendTelemetryEvent = useSendTelemetryEvent()
return (
@@ -17,7 +21,7 @@ export function CTASection() {
<div className="flex items-center gap-2">
<Button asChild size="medium">
<Link
href="https://supabase.com/dashboard"
href={getDashboardCtaHref(isLoggedIn)}
onClick={() =>
sendTelemetryEvent({
action: 'start_project_button_clicked',
+4 -1
View File
@@ -1,12 +1,15 @@
'use client'
import { useSendTelemetryEvent } from '~/lib/telemetry'
import { useIsLoggedIn } from 'common'
import Link from 'next/link'
import { Button } from 'ui'
import SectionContainer from '@/components/Layouts/SectionContainer'
import { getDashboardCtaHref } from '@/lib/dashboard-links'
export function Hero() {
const isLoggedIn = useIsLoggedIn()
const sendTelemetryEvent = useSendTelemetryEvent()
return (
@@ -25,7 +28,7 @@ export function Hero() {
<div className="flex items-center gap-2">
<Button asChild size="medium">
<Link
href="https://supabase.com/dashboard"
href={getDashboardCtaHref(isLoggedIn)}
onClick={() =>
sendTelemetryEvent({
action: 'start_project_button_clicked',
@@ -2,6 +2,8 @@ import SectionContainerWithCn from '~/components/Layouts/SectionContainerWithCn'
import Link from 'next/link'
import { Button } from 'ui'
import { StartYourProjectButton } from '@/components/StartYourProjectButton'
export function Hero() {
return (
<SectionContainerWithCn>
@@ -17,9 +19,7 @@ export function Hero() {
</p>
</div>
<div className="flex items-center gap-2">
<Button asChild size="medium">
<Link href="https://supabase.com/dashboard">Start your project</Link>
</Button>
<StartYourProjectButton />
<Button asChild size="medium" variant="default">
<Link href="/docs/guides/auth">Documentation</Link>
</Button>
@@ -2,6 +2,8 @@ import SectionContainerWithCn from '~/components/Layouts/SectionContainerWithCn'
import Link from 'next/link'
import { Button } from 'ui'
import { StartYourProjectButton } from '@/components/StartYourProjectButton'
export function Hero() {
return (
<SectionContainerWithCn>
@@ -17,9 +19,7 @@ export function Hero() {
</p>
</div>
<div className="flex items-center gap-2">
<Button asChild size="medium">
<Link href="https://supabase.com/dashboard">Start your project</Link>
</Button>
<StartYourProjectButton />
<Button asChild size="medium" variant="default">
<Link href="/docs/guides/database/overview">Documentation</Link>
</Button>
@@ -6,6 +6,8 @@ import Link from 'next/link'
import { useEffect, useRef, useState } from 'react'
import { Button } from 'ui'
import { StartYourProjectButton } from '@/components/StartYourProjectButton'
const TERMINAL_LINES = [
{ text: '$ supabase functions new hello-world', delay: 0 },
{ text: 'Created function: supabase/functions/hello-world/index.ts', delay: 0.3, dim: true },
@@ -80,9 +82,7 @@ export function CTASection() {
<TerminalAnimation />
<div className="flex items-center gap-2">
<Button asChild size="medium">
<Link href="https://supabase.com/dashboard">Start your project</Link>
</Button>
<StartYourProjectButton />
<Button asChild size="medium" variant="default">
<Link href="/docs/guides/functions/quickstart">Quickstart guide</Link>
</Button>
@@ -3,6 +3,7 @@ import Link from 'next/link'
import { Button } from 'ui'
import { Highlights } from './Highlights'
import { StartYourProjectButton } from '@/components/StartYourProjectButton'
export function Hero() {
return (
@@ -19,9 +20,7 @@ export function Hero() {
</p>
</div>
<div className="flex items-center gap-2">
<Button asChild size="medium">
<Link href="https://supabase.com/dashboard">Start your project</Link>
</Button>
<StartYourProjectButton />
<Button asChild size="medium" variant="default">
<Link href="/docs/guides/functions">Documentation</Link>
</Button>
@@ -2,6 +2,8 @@ import SectionContainerWithCn from '~/components/Layouts/SectionContainerWithCn'
import Link from 'next/link'
import { Button } from 'ui'
import { StartYourProjectButton } from '@/components/StartYourProjectButton'
export function Hero() {
return (
<SectionContainerWithCn>
@@ -17,9 +19,7 @@ export function Hero() {
</p>
</div>
<div className="flex items-center gap-2">
<Button asChild size="medium">
<Link href="https://supabase.com/dashboard">Start your project</Link>
</Button>
<StartYourProjectButton />
<Button asChild size="medium" variant="default">
<Link href="/docs/guides/realtime">Documentation</Link>
</Button>
@@ -2,6 +2,8 @@ import SectionContainerWithCn from '~/components/Layouts/SectionContainerWithCn'
import Link from 'next/link'
import { Button } from 'ui'
import { StartYourProjectButton } from '@/components/StartYourProjectButton'
export function Hero() {
return (
<SectionContainerWithCn>
@@ -17,9 +19,7 @@ export function Hero() {
</p>
</div>
<div className="flex items-center gap-2">
<Button asChild size="medium">
<Link href="https://supabase.com/dashboard">Start your project</Link>
</Button>
<StartYourProjectButton />
<Button asChild size="medium" variant="default">
<Link href="/docs/guides/storage">Documentation</Link>
</Button>
+6 -2
View File
@@ -1,8 +1,11 @@
'use client'
import { useSendTelemetryEvent } from '~/lib/telemetry'
import { useIsLoggedIn } from 'common'
import Link from 'next/link'
import { Button, cn } from 'ui'
import { useSendTelemetryEvent } from '~/lib/telemetry'
import { getDashboardCtaHref } from '@/lib/dashboard-links'
interface Props {
className?: string
@@ -10,6 +13,7 @@ interface Props {
}
const CTABanner = ({ darkerBg, className }: Props) => {
const isLoggedIn = useIsLoggedIn()
const sendTelemetryEvent = useSendTelemetryEvent()
return (
<div
@@ -28,7 +32,7 @@ const CTABanner = ({ darkerBg, className }: Props) => {
<div className="flex items-center justify-center gap-2 col-span-12 mt-4">
<Button asChild size="medium">
<Link
href="https://supabase.com/dashboard"
href={getDashboardCtaHref(isLoggedIn)}
onClick={() =>
sendTelemetryEvent({
action: 'start_project_button_clicked',
+5 -1
View File
@@ -1,10 +1,14 @@
'use client'
import { useSendTelemetryEvent } from '~/lib/telemetry'
import { useIsLoggedIn } from 'common'
import Link from 'next/link'
import { Button } from 'ui'
import { getDashboardCtaHref } from '@/lib/dashboard-links'
export function CTASection() {
const isLoggedIn = useIsLoggedIn()
const sendTelemetryEvent = useSendTelemetryEvent()
return (
@@ -17,7 +21,7 @@ export function CTASection() {
<div className="flex items-center gap-2">
<Button asChild size="medium">
<Link
href="https://supabase.com/dashboard"
href={getDashboardCtaHref(isLoggedIn)}
onClick={() =>
sendTelemetryEvent({
action: 'start_project_button_clicked',
@@ -1,9 +1,11 @@
import { useSendTelemetryEvent } from '~/lib/telemetry'
import { useIsLoggedIn } from 'common'
import { BookOpen } from 'lucide-react'
import Link from 'next/link'
import { Button } from 'ui'
import ProductIcon from '../ProductIcon'
import { getDashboardCtaHref } from '@/lib/dashboard-links'
type subheader = string
interface Types {
@@ -18,6 +20,7 @@ interface Types {
}
const ProductHeader = (props: Types) => {
const isLoggedIn = useIsLoggedIn()
const sendTelemetryEvent = useSendTelemetryEvent()
return (
<div className="section-container relative pt-16 pb-0 lg:pt-28">
@@ -52,8 +55,7 @@ const ProductHeader = (props: Types) => {
<div className="flex flex-row md:flex-row md:items-center">
<Button asChild size="medium">
<Link
href="https://supabase.com/dashboard"
as="https://supabase.com/dashboard"
href={getDashboardCtaHref(isLoggedIn)}
onClick={() =>
sendTelemetryEvent({
action: 'start_project_button_clicked',
+80 -69
View File
@@ -1,10 +1,14 @@
import { CTA } from '~/types/common'
'use client'
import type { CTA } from '~/types/common'
import { useIsLoggedIn } from 'common'
import Link from 'next/link'
import React, { Children, type ReactNode } from 'react'
import { Button, cn } from 'ui'
import SectionContainerWithCn from '../Layouts/SectionContainerWithCn'
import ProductIcon from '../ProductIcon'
import { resolveDashboardCtaHref } from '@/lib/dashboard-links'
// to do: move types to be global
// then solutions.types.ts should extend this
@@ -22,83 +26,90 @@ interface Props {
sectionContainerClassName?: string
}
const ProductHeader = ({ footerPosition = 'left', ...props }: Props) => (
<div
className={cn(
'w-full max-w-full relative mx-auto py-16 lg:py-24 border-b bg-alternative overflow-hidden',
props.className
)}
>
<SectionContainerWithCn
height="none"
className={cn('grid grid-cols-12', props.sectionContainerClassName)}
const ProductHeader = ({ footerPosition = 'left', ...props }: Props) => {
const isLoggedIn = useIsLoggedIn()
return (
<div
className={cn(
'w-full max-w-full relative mx-auto py-16 lg:py-24 border-b bg-alternative overflow-hidden',
props.className
)}
>
<div
className={cn(
'relative z-10 col-span-12 lg:col-span-5',
// if not image is present, center the content
!props.image &&
'lg:col-span-12 lg:mx-auto lg:max-w-2xl text-center flex flex-col items-center'
)}
<SectionContainerWithCn
height="none"
className={cn('grid grid-cols-12', props.sectionContainerClassName)}
>
{(props.icon || props.title) && (
<div className="mb-4 flex items-center gap-3">
{props.icon && <ProductIcon icon={props.icon} />}
{props.title && (
<span
className="text-brand-600 dark:text-brand font-mono uppercase"
key={`product-name-${props.title}`}
>
{props.title}
</span>
)}
</div>
)}
<h1 className="h1 text-3xl md:text-4xl! lg:text-4xl! 2xl:text-6xl! tracking-[-.15px] text-balance">
{props.h1}
</h1>
{props.subheader && (
<div className="">
{Children.map(props.subheader, (subheader, i) => {
<div
className={cn(
'relative z-10 col-span-12 lg:col-span-5',
// if not image is present, center the content
!props.image &&
'lg:col-span-12 lg:mx-auto lg:max-w-2xl text-center flex flex-col items-center'
)}
>
{(props.icon || props.title) && (
<div className="mb-4 flex items-center gap-3">
{props.icon && <ProductIcon icon={props.icon} />}
{props.title && (
<span
className="text-brand-600 dark:text-brand font-mono uppercase"
key={`product-name-${props.title}`}
>
{props.title}
</span>
)}
</div>
)}
<h1 className="h1 text-3xl md:text-4xl! lg:text-4xl! 2xl:text-6xl! tracking-[-.15px] text-balance">
{props.h1}
</h1>
{props.subheader && (
<div className="">
{Children.map(props.subheader, (subheader, i) => {
return (
<p className="p lg:text-lg max-w-lg lg:max-w-none text-pretty" key={i}>
{subheader}
</p>
)
})}
</div>
)}
<div className="flex flex-row md:flex-row md:items-center gap-2 mt-4">
{props.ctas?.map((cta) => {
const href = resolveDashboardCtaHref(cta.href, isLoggedIn)
return (
<p className="p lg:text-lg max-w-lg lg:max-w-none text-pretty" key={i}>
{subheader}
</p>
<Button
key={cta.href}
size="medium"
variant={cta.type ?? 'default'}
onClick={cta.onClick}
asChild
>
<Link href={href}>{cta.label ?? 'Start for free'}</Link>
</Button>
)
})}
</div>
)}
<div className="flex flex-row md:flex-row md:items-center gap-2 mt-4">
{props.ctas?.map((cta) => (
<Button
key={cta.href}
size="medium"
variant={cta.type ?? 'default'}
onClick={cta.onClick}
asChild
>
<Link href={cta.href}>{cta.label ?? 'Start for free'}</Link>
</Button>
))}
{props.footer && footerPosition === 'left' && (
<div className="ph-footer relative z-10 mt-4 md:mt-8 lg:mt-20 xl:mt-32 col-span-12">
{props.footer}
</div>
)}
</div>
{props.footer && footerPosition === 'left' && (
<div className="ph-footer relative z-10 mt-4 md:mt-8 lg:mt-20 xl:mt-32 col-span-12">
{props.image && (
<div className="image-container relative min-h-[300px] col-span-12 mt-8 lg:col-span-7 lg:mt-0 xl:col-span-6 xl:col-start-7">
{props.image}
</div>
)}
{props.footer && footerPosition !== 'left' && (
<div className="relative z-10 mt-4 md:mt-8 lg:mt-20 xl:mt-32 col-span-12">
{props.footer}
</div>
)}
</div>
{props.image && (
<div className="image-container relative min-h-[300px] col-span-12 mt-8 lg:col-span-7 lg:mt-0 xl:col-span-6 xl:col-start-7">
{props.image}
</div>
)}
{props.footer && footerPosition !== 'left' && (
<div className="relative z-10 mt-4 md:mt-8 lg:mt-20 xl:mt-32 col-span-12">
{props.footer}
</div>
)}
</SectionContainerWithCn>
</div>
)
</SectionContainerWithCn>
</div>
)
}
export default ProductHeader
@@ -5,6 +5,8 @@ import Link from 'next/link'
import React from 'react'
import { Button, cn } from 'ui'
import { StartYourProjectButton } from '@/components/StartYourProjectButton'
export type Products = PRODUCT_SHORTNAMES
interface Props {
@@ -26,9 +28,9 @@ function ProductsCta(props: Props) {
<div className="flex flex-col col-span-1 text-center xl:text-left xl:justify-center items-center xl:items-start">
<h2 className="h2 w-max">Ready to start building?</h2>
<div className="flex gap-2 py-2">
<Button asChild variant="primary" size="small" className="h-full">
<Link href="https://supabase.com/dashboard">Start for free</Link>
</Button>
<StartYourProjectButton size="small" className="h-full" variant="primary">
Start for free
</StartYourProjectButton>
<Button asChild variant="default" size="small">
<Link href="https://forms.supabase.com/enterprise">Contact Enterprise</Link>
</Button>
@@ -0,0 +1,34 @@
'use client'
import { useIsLoggedIn } from 'common'
import Link from 'next/link'
import type { ComponentProps } from 'react'
import { Button } from 'ui'
import { getDashboardCtaHref } from '@/lib/dashboard-links'
type StartYourProjectButtonProps = {
children?: React.ReactNode
onClick?: ComponentProps<typeof Link>['onClick']
size?: ComponentProps<typeof Button>['size']
variant?: ComponentProps<typeof Button>['variant']
className?: string
}
export function StartYourProjectButton({
children = 'Start your project',
onClick,
size = 'medium',
variant,
className,
}: StartYourProjectButtonProps) {
const isLoggedIn = useIsLoggedIn()
return (
<Button asChild size={size} variant={variant} className={className}>
<Link href={getDashboardCtaHref(isLoggedIn)} onClick={onClick}>
{children}
</Link>
</Button>
)
}
+2 -1
View File
@@ -1,4 +1,5 @@
import { CubeIcon } from '@heroicons/react/outline'
import { DASHBOARD_SIGN_UP_URL } from '@/lib/dashboard-links'
import {
ArrowLeftRight,
Check,
@@ -85,7 +86,7 @@ const data: {
ctas: [
{
label: 'Start your project',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
type: 'primary' as const,
},
{
+2 -1
View File
@@ -1,4 +1,5 @@
import { CubeIcon } from '@heroicons/react/outline'
import { DASHBOARD_SIGN_UP_URL } from '@/lib/dashboard-links'
import {
Check,
ClipboardCheck,
@@ -91,7 +92,7 @@ const data: () => {
ctas: [
{
label: 'Start your project',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
type: 'primary' as any,
onClick: () =>
sendTelemetryEvent({
+2 -1
View File
@@ -1,4 +1,5 @@
import { CubeIcon } from '@heroicons/react/outline'
import { DASHBOARD_SIGN_UP_URL } from '@/lib/dashboard-links'
import { Timer } from 'lucide-react'
import type {
@@ -39,7 +40,7 @@ const data: {
ctas: [
{
label: 'Start your project',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
type: 'primary' as any,
},
{
+2 -1
View File
@@ -1,4 +1,5 @@
import { CubeIcon } from '@heroicons/react/outline'
import { DASHBOARD_SIGN_UP_URL } from '@/lib/dashboard-links'
import { useBreakpoint } from 'common'
import {
Check,
@@ -91,7 +92,7 @@ const data: () => {
ctas: [
{
label: 'Start your project',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
type: 'primary' as any,
onClick: () =>
sendTelemetryEvent({
+2 -1
View File
@@ -1,4 +1,5 @@
import { CubeIcon } from '@heroicons/react/outline'
import { DASHBOARD_SIGN_UP_URL } from '@/lib/dashboard-links'
import { useBreakpoint } from 'common'
import { Check, Sparkles, Timer } from 'lucide-react'
import dynamic from 'next/dynamic'
@@ -69,7 +70,7 @@ const data: () => {
ctas: [
{
label: 'Start your project',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
type: 'primary' as any,
onClick: () =>
sendTelemetryEvent({
+2 -1
View File
@@ -1,4 +1,5 @@
import { CubeIcon } from '@heroicons/react/outline'
import { DASHBOARD_SIGN_UP_URL } from '@/lib/dashboard-links'
import { useBreakpoint } from 'common'
import {
Check,
@@ -85,7 +86,7 @@ const data: () => {
ctas: [
{
label: 'Start your project',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
type: 'primary' as any,
onClick: () =>
sendTelemetryEvent({
+2 -1
View File
@@ -11,6 +11,7 @@ import {
Users,
UserX,
} from 'lucide-react'
import { DASHBOARD_SIGN_UP_URL } from '@/lib/dashboard-links'
import { PRODUCT_SHORTNAMES } from 'shared-data/products'
import { Image } from 'ui-patterns/Image'
@@ -90,7 +91,7 @@ const data: () => {
ctas: [
{
label: 'Start your project',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
type: 'primary' as any,
onClick: () =>
sendTelemetryEvent({
+2 -1
View File
@@ -1,4 +1,5 @@
import { CubeIcon } from '@heroicons/react/outline'
import { DASHBOARD_SIGN_UP_URL } from '@/lib/dashboard-links'
import { useBreakpoint } from 'common'
import { Check, InfoIcon, Sparkles, Timer } from 'lucide-react'
import dynamic from 'next/dynamic'
@@ -65,7 +66,7 @@ const data: () => {
ctas: [
{
label: 'Start your project',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
type: 'primary' as any,
onClick: () =>
sendTelemetryEvent({
+2 -1
View File
@@ -10,6 +10,7 @@ import {
Users,
UserX,
} from 'lucide-react'
import { DASHBOARD_SIGN_UP_URL } from '@/lib/dashboard-links'
import { Image } from 'ui-patterns/Image'
import { getSharedSections } from './shared-sections'
@@ -89,7 +90,7 @@ const data: () => {
ctas: [
{
label: 'Start your project',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
type: 'primary' as any,
onClick: () =>
sendTelemetryEvent({
+2 -1
View File
@@ -1,4 +1,5 @@
import { useBreakpoint } from 'common'
import { DASHBOARD_SIGN_UP_URL } from '@/lib/dashboard-links'
import {
Activity,
Blocks,
@@ -90,7 +91,7 @@ const data: () => {
ctas: [
{
label: 'Start your project',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
type: 'primary' as any,
onClick: () =>
sendTelemetryEvent({
+3 -2
View File
@@ -1,4 +1,5 @@
import { CubeIcon } from '@heroicons/react/outline'
import { DASHBOARD_SIGN_UP_URL } from '@/lib/dashboard-links'
import { useBreakpoint } from 'common'
import {
ArrowLeftRight,
@@ -134,7 +135,7 @@ const data: () => {
ctas: [
{
label: 'Start Building',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
type: 'primary' as any,
onClick: () =>
sendTelemetryEvent({
@@ -751,7 +752,7 @@ const data: () => {
description: 'Start free with any AI builder + Supabase',
cta: {
label: 'Create Your First App in 5 Minutes',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
},
},
{
+2 -1
View File
@@ -1,4 +1,5 @@
import { Check, PointerIcon, TrendingUp, ZapIcon } from 'lucide-react'
import { DASHBOARD_SIGN_UP_URL } from '@/lib/dashboard-links'
import dynamic from 'next/dynamic'
import { PRODUCT_SHORTNAMES } from 'shared-data/products'
import { cn } from 'ui'
@@ -54,7 +55,7 @@ const data: () => {
ctas: [
{
label: 'Start your project',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
type: 'primary' as any,
onClick: () =>
sendTelemetryEvent({
@@ -1,4 +1,5 @@
import { CubeIcon } from '@heroicons/react/outline'
import { DASHBOARD_SIGN_UP_URL } from '@/lib/dashboard-links'
import { useBreakpoint } from 'common'
import {
Check,
@@ -85,7 +86,7 @@ const data: () => {
ctas: [
{
label: 'Start your project',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
type: 'primary' as any,
onClick: () =>
sendTelemetryEvent({
+2 -1
View File
@@ -1,4 +1,5 @@
import { CubeIcon } from '@heroicons/react/outline'
import { DASHBOARD_SIGN_UP_URL } from '@/lib/dashboard-links'
import { useBreakpoint } from 'common'
import {
Check,
@@ -85,7 +86,7 @@ const data: () => {
ctas: [
{
label: 'Get started with Supabase',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
type: 'primary' as any,
onClick: () =>
sendTelemetryEvent({
+2 -1
View File
@@ -1,4 +1,5 @@
import { useBreakpoint } from 'common'
import { DASHBOARD_SIGN_UP_URL } from '@/lib/dashboard-links'
import { Check, CheckCircle, Sparkles, Timer, Zap } from 'lucide-react'
import dynamic from 'next/dynamic'
import { PRODUCT_SHORTNAMES } from 'shared-data/products'
@@ -62,7 +63,7 @@ const useVibeCodersContent: () => {
ctas: [
{
label: 'Start Your Project',
href: 'https://supabase.com/dashboard',
href: DASHBOARD_SIGN_UP_URL,
type: 'primary' as any,
},
],
+16
View File
@@ -0,0 +1,16 @@
export const DASHBOARD_URL = 'https://supabase.com/dashboard'
export const DASHBOARD_SIGN_IN_URL = 'https://supabase.com/dashboard/sign-in'
export const DASHBOARD_SIGN_UP_URL = 'https://supabase.com/dashboard/sign-up'
/** Homepage/product "Start your project" CTA: sign-up for guests, dashboard for signed-in users. */
export function getDashboardCtaHref(isLoggedIn: boolean): string {
return isLoggedIn ? DASHBOARD_URL : DASHBOARD_SIGN_UP_URL
}
const DASHBOARD_CTA_HREFS = new Set([DASHBOARD_URL, DASHBOARD_SIGN_UP_URL])
/** Rewrite static dashboard/sign-up CTA hrefs when the visitor is already signed in. */
export function resolveDashboardCtaHref(href: string, isLoggedIn: boolean): string {
if (!DASHBOARD_CTA_HREFS.has(href)) return href
return getDashboardCtaHref(isLoggedIn)
}