mirror of
https://github.com/better-auth/better-auth.git
synced 2026-10-25 10:13:54 -05:00
docs: resource reference page (#2357)
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import { ArrowUpRight } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface ResourceCardProps {
|
||||
title: string;
|
||||
description: string;
|
||||
href: string;
|
||||
tags?: string[];
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function ResourceCard({
|
||||
title,
|
||||
description,
|
||||
href,
|
||||
tags,
|
||||
className,
|
||||
}: ResourceCardProps) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"relative flex justify-between rounded-none flex-col group space-y-1 border transition-colors hover:bg-muted/80",
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<div>
|
||||
<ArrowUpRight className="absolute top-3 right-3 h-4 w-4 group-hover:opacity-100 opacity-80 text-muted-foreground transition-colors group-hover:text-foreground no-underline underline-offset-0" />
|
||||
<div className="p-4 py-0 flex items-start justify-between">
|
||||
<a href={href} target="_blank" rel="noopener noreferrer">
|
||||
<h3 className="font-semibold tracking-tight no-underline">
|
||||
{title}
|
||||
</h3>
|
||||
</a>
|
||||
</div>
|
||||
<p
|
||||
dangerouslySetInnerHTML={{ __html: `${description}` }}
|
||||
className="p-4 py-0 text-sm md:decoration-none text-muted-foreground"
|
||||
></p>
|
||||
</div>
|
||||
<div>
|
||||
{tags && tags.length > 0 && (
|
||||
<div className="py-3 border-zinc-700/80 border-t-[1.2px] flex flex-wrap items-end gap-2">
|
||||
{tags.map((tag) => (
|
||||
<span
|
||||
key={tag}
|
||||
className="inline-flex items-end underline underline-offset-2 rounded-md bg-secondary/10 px-2 py-1 text-xs font-medium text-secondary-foreground"
|
||||
>
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ResourceCard } from "./resource-card";
|
||||
|
||||
interface ResourceGridProps {
|
||||
resources: {
|
||||
title: string;
|
||||
description: string;
|
||||
href: string;
|
||||
tags?: string[];
|
||||
}[];
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function ResourceGrid({ resources, className }: ResourceGridProps) {
|
||||
return (
|
||||
<div className={cn("grid gap-4 sm:grid-cols-2 lg:grid-cols-3", className)}>
|
||||
{resources.map((resource) => (
|
||||
<ResourceCard key={resource.href} {...resource} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
"use client";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useState } from "react";
|
||||
import { ResourceCard } from "./resource-card";
|
||||
|
||||
interface Resource {
|
||||
title: string;
|
||||
description: string;
|
||||
href: string;
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
interface ResourceProps {
|
||||
resources: Resource[];
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function Resource({ className, resources }: ResourceProps) {
|
||||
const [activeTag, setActiveTag] = useState<string | null>(null);
|
||||
const tags = Array.from(
|
||||
new Set(resources.flatMap((resource) => resource.tags)),
|
||||
);
|
||||
const filterResources = (activeTag: string | null): Resource[] => {
|
||||
if (!activeTag) return resources;
|
||||
return resources.filter((resource) => resource.tags.includes(activeTag));
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<div className={cn("space-y-4", className)}>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<button
|
||||
onClick={() => setActiveTag(null)}
|
||||
className={cn(
|
||||
"inline-flex items-center rounded-md px-3 py-1 text-sm font-medium transition-colors",
|
||||
activeTag === null
|
||||
? "bg-primary text-primary-foreground"
|
||||
: "bg-secondary/10 text-secondary-foreground hover:bg-secondary/20",
|
||||
)}
|
||||
>
|
||||
All
|
||||
</button>
|
||||
{tags.map((tag) => (
|
||||
<button
|
||||
key={tag}
|
||||
onClick={() => setActiveTag(tag)}
|
||||
className={cn(
|
||||
"inline-flex items-center rounded-md px-3 py-1 text-sm font-medium transition-colors",
|
||||
activeTag === tag
|
||||
? "bg-primary text-primary-foreground"
|
||||
: "bg-secondary/10 text-secondary-foreground hover:bg-secondary/20",
|
||||
)}
|
||||
>
|
||||
{tag}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 mt-2">
|
||||
{filterResources(activeTag).map((resource) => (
|
||||
<ResourceCard key={resource.href} {...resource} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
UserSquare2,
|
||||
Database,
|
||||
KeyRound,
|
||||
Book,
|
||||
} from "lucide-react";
|
||||
import { ReactNode, SVGProps } from "react";
|
||||
import { Icons } from "./icons";
|
||||
@@ -1719,6 +1720,11 @@ C0.7,239.6,62.1,0.5,62.2,0.4c0,0,54,13.8,119.9,30.8S302.1,62,302.2,62c0.2,0,0.2,
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Resources",
|
||||
href: "/docs/reference/resources",
|
||||
icon: () => <Book className="w-4 h-4 text-current" />,
|
||||
},
|
||||
{
|
||||
title: "Security",
|
||||
href: "/docs/reference/security",
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
---
|
||||
title: Resources
|
||||
description: A curated collection of resources to help you learn and master Better Auth.
|
||||
---
|
||||
|
||||
import { Resource } from "@/components/resource-section";
|
||||
|
||||
A curated collection of resources to help you learn and master Better Auth. From blog posts to video tutorials, find everything you need to get started.
|
||||
|
||||
## Video tutorials
|
||||
|
||||
<Resource resources={
|
||||
[
|
||||
{
|
||||
title: "The State of Authentication",
|
||||
description:
|
||||
"<strong>Theo(t3.gg)</strong> explores the current landscape of authentication, discussing trends, challenges, and where the industry is heading.",
|
||||
href: "https://www.youtube.com/watch?v=lxslnp-ZEMw",
|
||||
tags: ["trends", "showcase", "review"],
|
||||
},
|
||||
{
|
||||
title: "Last Authentication You Will Ever Need",
|
||||
description:
|
||||
"A comprehensive tutorial demonstrating why Better Auth could be the final authentication solution you'll need for your projects.",
|
||||
href: "https://www.youtube.com/watch?v=hFtufpaMcLM",
|
||||
tags: ["implementation", "showcase"],
|
||||
},
|
||||
{
|
||||
title: "This Might Be My New Favourite Auth Library",
|
||||
description:
|
||||
"<strong>developedbyed</strong> explores the features and capabilities of Better Auth, explaining why it stands out among authentication libraries.",
|
||||
href: "https://www.youtube.com/watch?v=Hjs3zM7o7NE",
|
||||
tags: ["review", "showcase"],
|
||||
},
|
||||
{
|
||||
title: "Nextjs 15 Authentication Made EASY with Better Auth",
|
||||
description:
|
||||
"A practical guide showing how to seamlessly integrate Better Auth with Next.js 15 for robust authentication.",
|
||||
href: "https://www.youtube.com/watch?v=lxslnp-ZEMw",
|
||||
tags: ["nextjs", "implementation", "tutorial"],
|
||||
},
|
||||
{
|
||||
title: "Best authentication framework for next.js",
|
||||
description:
|
||||
"A detailed comparison of authentication frameworks for Next.js, highlighting why Better Auth might be your best choice.",
|
||||
href: "https://www.youtube.com/watch?v=V--T0q9FrEw",
|
||||
tags: ["nextjs", "comparison"],
|
||||
},
|
||||
{
|
||||
title: "Better-Auth: A First Look",
|
||||
description:
|
||||
"An introductory overview and demonstration of Better Auth's core features and capabilities.",
|
||||
href: "https://www.youtube.com/watch?v=2cQTV6NYxis",
|
||||
tags: ["implementation", "showcase"],
|
||||
},
|
||||
{
|
||||
title: "Stripe was never so easy (with better auth)",
|
||||
description: "A tutorial on how to integrate Stripe with Better Auth.",
|
||||
href: "https://www.youtube.com/watch?v=g-RIrzBEX6M",
|
||||
tags: [ "implementation"],
|
||||
},
|
||||
]
|
||||
} />
|
||||
|
||||
## Blog posts
|
||||
|
||||
<Resource resources={
|
||||
[
|
||||
{
|
||||
title: "Better Auth with Hono, Bun, TypeScript, React and Vite",
|
||||
description:
|
||||
"You'll learn how to implement authentication with Better Auth in a client - server architecture, where the frontend is separate from the backend.",
|
||||
href: "https://catalins.tech/better-auth-with-hono-bun-typescript-react-vite",
|
||||
tags: ["typescript", "react", "bun", "vite"],
|
||||
},
|
||||
{
|
||||
title: "Polar.sh + BetterAuth for Organizations",
|
||||
description:
|
||||
"Polar.sh is a platform for building payment integrations. This article will show you how to use Better Auth to authenticate your users.",
|
||||
href: "https://dev.to/phumudzosly/polarsh-betterauth-for-organizations-1j1b",
|
||||
tags: ["organizations", "integration", "payments"],
|
||||
},
|
||||
{
|
||||
title: "Authenticating users in Astro with Better Auth",
|
||||
description:
|
||||
"Step by step guide on how to authenticate users in Astro with Better Auth.",
|
||||
href: "https://www.launchfa.st/blog/astro-better-auth",
|
||||
tags: ["astro", "integration", "tutorial"],
|
||||
},
|
||||
{
|
||||
title: "Building Multi-Tenant Apps With Better-Auth and ZenStack",
|
||||
description:
|
||||
"Learn how to build multi-tenant apps with Better-Auth and ZenStack.",
|
||||
href: "https://zenstack.dev/blog/better-auth",
|
||||
tags: ["multi-tenant", "zenstack", "architecture"],
|
||||
},
|
||||
]
|
||||
} />
|
||||
Reference in New Issue
Block a user