EmpiezaTuSaaS
Funcionalidades

Google OAuth

Login con Google usando Better Auth

Social Login

El boilerplate incluye login social con Google preconfigurado, usando un componente SocialButton reutilizable que se integra en los formularios de login y registro.

Provider incluido

El boilerplate viene con Google configurado. Puedes agregar mas providers en lib/auth.ts siguiendo la misma estructura.

Configuración de Google

Crear proyecto en Google Cloud

  1. Ve a Google Cloud Console
  2. Crea un nuevo proyecto
  3. Ve a APIs & Services > Credentials
  4. Click en Create Credentials > OAuth client ID
  5. Selecciona Web application

Configurar URIs

Authorized JavaScript origins:

http://localhost:3000
https://tuapp.com

Authorized redirect URIs:

http://localhost:3000/api/auth/callback/google
https://tuapp.com/api/auth/callback/google

Copiar credenciales

Copia el Client ID y Client Secret a tu .env:

GOOGLE_CLIENT_ID="tu-client-id"
GOOGLE_CLIENT_SECRET="tu-client-secret"

Configuración en Better Auth

El provider social ya está configurado en lib/auth.ts:

lib/auth.ts
import { betterAuth } from "better-auth";

export const auth = betterAuth({
  // ... database, emailAndPassword, etc.

  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    },
  },
});

Componente SocialButton

El boilerplate usa un componente SocialButton reutilizable en components/auth/social-button.tsx. Recibe el provider y opcionalmente un callbackURL:

components/auth/social-button.tsx
"use client";

import { useState } from "react";
import { Loader2 } from "lucide-react";
import { Button } from "@/components/ui/button";
import { signIn } from "@/lib/auth-client";
import { toast } from "sonner";

interface SocialButtonProps {
  provider: "google";
  callbackURL?: string;
}

const providerConfig = {
  google: {
    label: "Continuar con Google",
    icon: (
      <svg className="h-4 w-4" viewBox="0 0 24 24">
        <path
          fill="currentColor"
          d="M12.545,10.239v3.821h5.445c-0.712,2.315-2.647,3.972-5.445,3.972c-3.332,0-6.033-2.701-6.033-6.032s2.701-6.032,6.033-6.032c1.498,0,2.866,0.549,3.921,1.453l2.814-2.814C17.503,2.988,15.139,2,12.545,2C7.021,2,2.543,6.477,2.543,12s4.478,10,10.002,10c8.396,0,10.249-7.85,9.426-11.748L12.545,10.239z"
        />
      </svg>
    ),
  },
};

export function SocialButton({ provider, callbackURL = "/dashboard" }: SocialButtonProps) {
  const [isLoading, setIsLoading] = useState(false);
  const config = providerConfig[provider];

  const handleSignIn = async () => {
    setIsLoading(true);
    try {
      await signIn.social({
        provider,
        callbackURL,
      });
    } catch {
      toast.error("Error al iniciar sesión. Intentalo de nuevo.");
      setIsLoading(false);
    }
  };

  return (
    <Button
      variant="outline"
      className="w-full"
      onClick={handleSignIn}
      disabled={isLoading}
    >
      {isLoading ? (
        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
      ) : (
        <span className="mr-2">{config.icon}</span>
      )}
      {config.label}
    </Button>
  );
}

Uso en formularios

El componente SocialButton se usa dentro de LoginForm y RegisterForm con un separador visual:

Dentro de LoginForm y RegisterForm
{/* Social login */}
<SocialButton provider="google" />

<div className="relative">
  <div className="absolute inset-0 flex items-center">
    <span className="w-full border-t" />
  </div>
  <div className="relative flex justify-center text-xs uppercase">
    <span className="bg-card px-2 text-muted-foreground">o continua con</span>
  </div>
</div>

{/* Email form below... */}

Props del componente

PropTipoDefectoDescripción
provider"google"requeridoEl provider de OAuth a usar
callbackURLstring"/dashboard"URL de redirección tras login exitoso

Agregar mas providers

Para agregar un nuevo provider (por ejemplo, GitHub):

  1. Agrega el provider en lib/auth.ts:
lib/auth.ts
socialProviders: {
  google: { /* ... */ },
  github: {
    clientId: process.env.GITHUB_CLIENT_ID!,
    clientSecret: process.env.GITHUB_CLIENT_SECRET!,
  },
},
  1. Agrega la configuración en providerConfig dentro de social-button.tsx:
const providerConfig = {
  // ... google
  github: {
    label: "Continuar con GitHub",
    icon: (
      <svg className="h-4 w-4" viewBox="0 0 24 24">
        {/* GitHub icon SVG */}
      </svg>
    ),
  },
};
  1. Actualiza el tipo de SocialButtonProps:
interface SocialButtonProps {
  provider: "google" | "github";
  callbackURL?: string;
}
  1. Agrega las variables de entorno:
GITHUB_CLIENT_ID="tu-client-id"
GITHUB_CLIENT_SECRET="tu-client-secret"

Better Auth automáticamente vincula cuentas si el email del provider coincide con una cuenta existente.

On this page