# Signup — social first

> Signup that leads with GitHub and Google provider buttons, falling back to an email/password form.

A shadcn/ui block from the [@quill](https://www.quilldesignsystem.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/quill/signup-social).

- Page, with a live preview: https://shadcn.exchange/r/quill/signup-social
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/quill/signup-social-light-f876e1277c9d5118.png
- Registry item: https://www.quilldesignsystem.com/r/signup-social.json
- Categories: auth
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://www.quilldesignsystem.com/r/signup-social.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- Registry items: `card`, `input`, `label`, `button`, `separator`

## Notes from the registry

Signup that leads with GitHub and Google provider buttons, falling back to an email/password form. Do: Put the provider buttons above the divider and the email/password fields below it, matching login-oauth's provider-first order. Don't: Bury the provider buttons below a full email/password form — that defeats the point of offering them. Use signup when you don't have OAuth providers configured, or want email/password as the primary path, not a fallback. Use login-oauth when this is sign-in, not new-account creation — login-oauth is the matching pattern for returning users.

## Files

### `registry/blocks/signup-social.tsx`

```tsx
import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
  CardFooter,
} from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Button } from '@/components/ui/button'
import { Separator } from '@/components/ui/separator'

// Official brand marks — inlined because icon fonts (rightly) don't carry
// third-party logos. GitHub's mark is monochrome and follows the text color;
// Google's G keeps its brand colors per their sign-in guidelines.
function GitHubMark({ size = 16 }: { size?: number }) {
  return (
    <svg viewBox="0 0 24 24" width={size} height={size} fill="currentColor" aria-hidden>
      <path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
    </svg>
  )
}

function GoogleG({ size = 16 }: { size?: number }) {
  return (
    <svg viewBox="0 0 18 18" width={size} height={size} aria-hidden>
      {/* quill-check: allow raw-color — Google "G" mark, blue — fixed by Google's brand guidelines */}
      <path fill="#4285F4" d="M17.64 9.2045c0-.6381-.0573-1.2518-.1636-1.8409H9v3.4814h4.8436c-.2086 1.125-.8427 2.0782-1.7959 2.7164v2.2581h2.9087c1.7018-1.5668 2.6836-3.874 2.6836-6.615z" />
      {/* quill-check: allow raw-color — Google "G" mark, green — fixed by Google's brand guidelines */}
      <path fill="#34A853" d="M9 18c2.43 0 4.4673-.806 5.9564-2.1805l-2.9087-2.2581c-.8059.54-1.8368.859-3.0477.859-2.344 0-4.3282-1.5831-5.0359-3.7104H.9573v2.3318C2.4382 15.9832 5.4818 18 9 18z" />
      {/* quill-check: allow raw-color — Google "G" mark, yellow — fixed by Google's brand guidelines */}
      <path fill="#FBBC05" d="M3.9641 10.71c-.18-.54-.2823-1.1168-.2823-1.71s.1023-1.17.2823-1.71V4.9582H.9573C.3477 6.1732 0 7.5477 0 9s.3477 2.8268.9573 4.0418L3.9641 10.71z" />
      {/* quill-check: allow raw-color — Google "G" mark, red — fixed by Google's brand guidelines */}
      <path fill="#EA4335" d="M9 3.5795c1.3214 0 2.5077.4541 3.4405 1.346l2.5813-2.5814C13.4632.8918 11.4259 0 9 0 5.4818 0 2.4382 2.0168.9573 4.9582L3.9641 7.29C4.6718 5.1627 6.6559 3.5795 9 3.5795z" />
    </svg>
  )
}

/** Signup that leads with GitHub and Google provider buttons, falling back to an email/password form. */
export function SignupSocial() {
  return (
    <Card className="w-[380px]">
      <CardHeader className="text-center">
        <CardTitle>Create your account</CardTitle>
        <CardDescription>Start with a provider, or use your email.</CardDescription>
      </CardHeader>
      <CardContent className="flex flex-col gap-4">
        <div className="flex flex-col gap-2">
          <Button variant="outline" className="w-full">
            <GitHubMark /> Continue with GitHub
          </Button>
          <Button variant="outline" className="w-full">
            <GoogleG /> Continue with Google
          </Button>
        </div>
        <div className="flex items-center gap-3">
          <Separator className="flex-1" />
          <span className="text-xs text-muted-foreground">or with email</span>
          <Separator className="flex-1" />
        </div>
        <div className="flex flex-col gap-1.5">
          <Label htmlFor="social-email">Email</Label>
          <Input id="social-email" type="email" placeholder="you@example.com" />
        </div>
        <div className="flex flex-col gap-1.5">
          <Label htmlFor="social-password">Password</Label>
          <Input id="social-password" type="password" placeholder="At least 12 characters" />
        </div>
      </CardContent>
      <CardFooter className="flex-col gap-3">
        <Button className="w-full">Create account</Button>
        <p className="text-center text-xs leading-relaxed text-muted-foreground">
          By continuing you agree to the team terms and privacy note.
        </p>
      </CardFooter>
    </Card>
  )
}
```
