mirror of
https://github.com/LukeHagar/better-auth.git
synced 2025-12-07 12:27:44 +00:00
docs: add basic remix documentation (#38)
This commit is contained in:
@@ -1,14 +1,14 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import {
|
import {
|
||||||
CheckIcon,
|
CheckIcon,
|
||||||
Globe2Icon,
|
Globe2Icon,
|
||||||
PlugIcon,
|
PlugIcon,
|
||||||
PlugZap2Icon,
|
PlugZap2Icon,
|
||||||
Plus,
|
Plus,
|
||||||
RabbitIcon,
|
RabbitIcon,
|
||||||
ShieldCheckIcon,
|
ShieldCheckIcon,
|
||||||
Webhook,
|
Webhook,
|
||||||
XIcon,
|
XIcon,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { GitHubLogoIcon, LockClosedIcon } from "@radix-ui/react-icons";
|
import { GitHubLogoIcon, LockClosedIcon } from "@radix-ui/react-icons";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
@@ -19,188 +19,188 @@ import { Ripple } from "./ripple";
|
|||||||
import { GithubStat } from "./github-stat";
|
import { GithubStat } from "./github-stat";
|
||||||
|
|
||||||
export default function Features({ stars }: { stars: string | null }) {
|
export default function Features({ stars }: { stars: string | null }) {
|
||||||
return (
|
return (
|
||||||
<div className="md:w-10/12 overflow-hidden mt-10 mx-auto font-geist relative md:border-l-0 md:border-[1.2px] rounded-none -pr-2">
|
<div className="md:w-10/12 overflow-hidden mt-10 mx-auto font-geist relative md:border-l-0 md:border-[1.2px] rounded-none -pr-2">
|
||||||
<Plus className="absolute top-[-17px] left-[-17px] text-black/20 dark:text-white/30 w-8 h-8" />
|
<Plus className="absolute top-[-17px] left-[-17px] text-black/20 dark:text-white/30 w-8 h-8" />
|
||||||
<div className="grid grid-cols-1 md:grid-cols-3 md:mx-0 grid-rows-4 md:grid-rows-4 w-full">
|
<div className="grid grid-cols-1 md:grid-cols-3 md:mx-0 grid-rows-4 md:grid-rows-4 w-full">
|
||||||
<div className="relative items-start justify-start border-l-[1.2px] border-t-[1.2px] md:border-t-0 transform-gpu flex flex-col p-10 overflow-clip">
|
<div className="relative items-start justify-start border-l-[1.2px] border-t-[1.2px] md:border-t-0 transform-gpu flex flex-col p-10 overflow-clip">
|
||||||
<Plus className="absolute bottom-[-17px] left-[-17px] text-black/20 dark:text-white/30 w-8 h-8" />
|
<Plus className="absolute bottom-[-17px] left-[-17px] text-black/20 dark:text-white/30 w-8 h-8" />
|
||||||
|
|
||||||
<div className="flex gap-2 items-center my-1">
|
<div className="flex gap-2 items-center my-1">
|
||||||
<PlugZap2Icon className="w-4 h-4" />
|
<PlugZap2Icon className="w-4 h-4" />
|
||||||
<p className="text-gray-600 dark:text-gray-400">
|
<p className="text-gray-600 dark:text-gray-400">
|
||||||
Framework Agnostic{" "}
|
Framework Agnostic{" "}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<div className="max-w-full">
|
<div className="max-w-full">
|
||||||
<div className="flex gap-3 ">
|
<div className="flex gap-3 ">
|
||||||
<p className="text-xl md:text-2xl tracking-tighter font-normal max-w-lg">
|
<p className="text-xl md:text-2xl tracking-tighter font-normal max-w-lg">
|
||||||
Supports popular <strong>frameworks</strong>
|
Supports popular <strong>frameworks</strong>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-left text-sm mt-2 text-muted-foreground">
|
<p className="text-left text-sm mt-2 text-muted-foreground">
|
||||||
Supports your favorite frontend, backend and meta frameworks,
|
Supports your favorite frontend, backend and meta frameworks,
|
||||||
including React, Vue, Svelte, Astro, Solid, Next.js, Nuxt.js,
|
including React, Vue, Svelte, Astro, Solid, Next.js, Nuxt.js,
|
||||||
Hono, and more{" "}
|
Hono, and more{" "}
|
||||||
<a className="text-gray-50" href="/docs" target="_blank">
|
<a className="text-gray-50" href="/docs" target="_blank">
|
||||||
Learn more
|
Learn more
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative items-start justify-start border-l-[1.2px] border-t-[1.2px] md:border-t-0 transform-gpu flex flex-col p-10">
|
<div className="relative items-start justify-start border-l-[1.2px] border-t-[1.2px] md:border-t-0 transform-gpu flex flex-col p-10">
|
||||||
<Plus className="absolute bottom-[-17px] left-[-17px] text-black/20 dark:text-white/30 w-8 h-8" />
|
<Plus className="absolute bottom-[-17px] left-[-17px] text-black/20 dark:text-white/30 w-8 h-8" />
|
||||||
|
|
||||||
<div className="flex gap-2 items-center my-1">
|
<div className="flex gap-2 items-center my-1">
|
||||||
<LockClosedIcon className="w-4 h-4" />
|
<LockClosedIcon className="w-4 h-4" />
|
||||||
<p className="text-gray-600 dark:text-gray-400">Authentication</p>
|
<p className="text-gray-600 dark:text-gray-400">Authentication</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<div className="max-w-full">
|
<div className="max-w-full">
|
||||||
<div className="flex gap-3 ">
|
<div className="flex gap-3 ">
|
||||||
<p className="text-2xl tracking-tighter font-normal max-w-lg">
|
<p className="text-2xl tracking-tighter font-normal max-w-lg">
|
||||||
Email & Password <strong>Authentication</strong>
|
Email & Password <strong>Authentication</strong>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-left text-sm mt-2 text-muted-foreground">
|
<p className="text-left text-sm mt-2 text-muted-foreground">
|
||||||
Builtin support for email and password authentication, with secure
|
Builtin support for email and password authentication, with secure
|
||||||
password hashing and account management features{" "}
|
password hashing and account management features{" "}
|
||||||
<a className="text-gray-50" href="/docs" target="_blank">
|
<a className="text-gray-50" href="/docs" target="_blank">
|
||||||
Learn more
|
Learn more
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative items-start justify-start md:border-l-[0.2px] border-t-[1.2px] md:border-t-0 flex flex-col p-10">
|
<div className="relative items-start justify-start md:border-l-[0.2px] border-t-[1.2px] md:border-t-0 flex flex-col p-10">
|
||||||
<Plus className="absolute bottom-[-17px] left-[-17px] text-black/20 dark:text-white/30 w-8 h-8" />
|
<Plus className="absolute bottom-[-17px] left-[-17px] text-black/20 dark:text-white/30 w-8 h-8" />
|
||||||
|
|
||||||
<div className="flex gap-2 items-center my-1">
|
<div className="flex gap-2 items-center my-1">
|
||||||
<Webhook className="w-4 h-4" />
|
<Webhook className="w-4 h-4" />
|
||||||
<p className="text-gray-600 dark:text-gray-400">Social Sign-on</p>
|
<p className="text-gray-600 dark:text-gray-400">Social Sign-on</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<div className="max-w-full">
|
<div className="max-w-full">
|
||||||
<div className="flex gap-3 ">
|
<div className="flex gap-3 ">
|
||||||
<p className="text-2xl tracking-tighter font-normal max-w-lg">
|
<p className="text-2xl tracking-tighter font-normal max-w-lg">
|
||||||
Support multiple <strong>OAuth providers.</strong>
|
Support multiple <strong>OAuth providers.</strong>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-left text-sm mt-2 text-muted-foreground">
|
<p className="text-left text-sm mt-2 text-muted-foreground">
|
||||||
Allow users to sign in with their accounts, including Github,
|
Allow users to sign in with their accounts, including Github,
|
||||||
Google, Discord, Twitter, and more.{" "}
|
Google, Discord, Twitter, and more.{" "}
|
||||||
<a className="text-gray-50" href="#" target="_blank">
|
<a className="text-gray-50" href="#" target="_blank">
|
||||||
Learn more
|
Learn more
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="items-start justify-start border-l-[1.2px] border-t-[1.2px] flex flex-col p-10 ">
|
<div className="items-start justify-start border-l-[1.2px] border-t-[1.2px] flex flex-col p-10 ">
|
||||||
<div className="flex gap-2 items-center my-1">
|
<div className="flex gap-2 items-center my-1">
|
||||||
<ShieldCheckIcon className="w-4 h-4" />
|
<ShieldCheckIcon className="w-4 h-4" />
|
||||||
<p className="text-gray-600 dark:text-gray-400">Two Factor</p>
|
<p className="text-gray-600 dark:text-gray-400">Two Factor</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<div className="max-w-full">
|
<div className="max-w-full">
|
||||||
<div className="flex gap-3 ">
|
<div className="flex gap-3 ">
|
||||||
<p className="text-2xl tracking-tighter font-normal max-w-lg">
|
<p className="text-2xl tracking-tighter font-normal max-w-lg">
|
||||||
Two Factor <strong>Authentication</strong>
|
Two Factor <strong>Authentication</strong>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-left text-sm mt-2 text-muted-foreground">
|
<p className="text-left text-sm mt-2 text-muted-foreground">
|
||||||
With our built-in two factor authentication plugin, you can add an
|
With our built-in two factor authentication plugin, you can add an
|
||||||
extra layer of security to your account.{" "}
|
extra layer of security to your account.{" "}
|
||||||
<Link className="text-gray-50" href="/docs" target="_blank">
|
<Link className="text-gray-50" href="/docs" target="_blank">
|
||||||
Learn more
|
Learn more
|
||||||
</Link>
|
</Link>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="items-start justify-staart border-l-[1.2px] border-t-[1.2px] flex flex-col p-10 ">
|
<div className="items-start justify-staart border-l-[1.2px] border-t-[1.2px] flex flex-col p-10 ">
|
||||||
<div className="flex gap-2 items-center my-1">
|
<div className="flex gap-2 items-center my-1">
|
||||||
<RabbitIcon className="w-4 h-4" />
|
<RabbitIcon className="w-4 h-4" />
|
||||||
<p className="text-gray-600 dark:text-gray-400">
|
<p className="text-gray-600 dark:text-gray-400">
|
||||||
Organization & Access Control{" "}
|
Organization & Access Control{" "}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<div className="max-w-full">
|
<div className="max-w-full">
|
||||||
<div className="flex gap-3 ">
|
<div className="flex gap-3 ">
|
||||||
<p className="text-2xl tracking-tighter font-normal max-w-lg">
|
<p className="text-2xl tracking-tighter font-normal max-w-lg">
|
||||||
Gain and manage <strong>access.</strong>
|
Gain and manage <strong>access.</strong>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-left text-sm mt-2 text-muted-foreground">
|
<p className="text-left text-sm mt-2 text-muted-foreground">
|
||||||
Manage users and their access to resources within your
|
Manage users and their access to resources within your
|
||||||
application.{" "}
|
application.{" "}
|
||||||
<a className="text-gray-50" href="/docs" target="_blank">
|
<a className="text-gray-50" href="/docs" target="_blank">
|
||||||
Learn more
|
Learn more
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="items-start justify-start border-l-[1.2px] border-t-[1.2px] transform-gpu relative flex flex-col p-10 ">
|
<div className="items-start justify-start border-l-[1.2px] border-t-[1.2px] transform-gpu relative flex flex-col p-10 ">
|
||||||
<div className="flex gap-2 items-center my-1">
|
<div className="flex gap-2 items-center my-1">
|
||||||
<PlugIcon className="w-4 h-4" />
|
<PlugIcon className="w-4 h-4" />
|
||||||
<p className="text-gray-600 dark:text-gray-400">
|
<p className="text-gray-600 dark:text-gray-400">
|
||||||
Plugin Ecosystem{" "}
|
Plugin Ecosystem{" "}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="max-w-full">
|
<div className="max-w-full">
|
||||||
<div className="flex gap-3 ">
|
<div className="flex gap-3 ">
|
||||||
<p className="text-2xl tracking-tighter font-normal max-w-lg">
|
<p className="text-2xl tracking-tighter font-normal max-w-lg">
|
||||||
Pluggable with <strong>custom.</strong>
|
Pluggable with <strong>custom.</strong>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<p className="text-left text-sm mt-2 text-muted-foreground">
|
<p className="text-left text-sm mt-2 text-muted-foreground">
|
||||||
Enhance your application with our official plugins and those
|
Enhance your application with our official plugins and those
|
||||||
created by the community.{" "}
|
created by the community.{" "}
|
||||||
<a className="text-gray-50" href="/docs" target="_blank">
|
<a className="text-gray-50" href="/docs" target="_blank">
|
||||||
Learn more
|
Learn more
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative md:grid md:col-span-3 grid-cols-2 row-span-2 border-t-[1.2px] border-l-[1.2px] md:border-b-[1.2px] dark:border-b-0 h-full py-20 ">
|
<div className="relative md:grid md:col-span-3 grid-cols-2 row-span-2 border-t-[1.2px] border-l-[1.2px] md:border-b-[1.2px] dark:border-b-0 h-full py-20 ">
|
||||||
<div className="p-16 pt-10 md:px-10 h-full md:absolute top-0 left-0 w-full">
|
<div className="p-16 pt-10 md:px-10 h-full md:absolute top-0 left-0 w-full">
|
||||||
<div className="flex flex-col gap-3 justify-center h-full items-center w-full">
|
<div className="flex flex-col gap-3 justify-center h-full items-center w-full">
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex gap-2 items-center">
|
||||||
<Globe2Icon className="w-4 h-4" />
|
<Globe2Icon className="w-4 h-4" />
|
||||||
<p className="text-gray-600 dark:text-gray-400">
|
<p className="text-gray-600 dark:text-gray-400">
|
||||||
Own your auth
|
Own your auth
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-4xl md:text-4xl mt-4 tracking-tighter font-normal max-w-md mx-auto text-center">
|
<p className="text-4xl md:text-4xl mt-4 tracking-tighter font-normal max-w-md mx-auto text-center">
|
||||||
<strong>Roll your own auth with confidence in minutes!</strong>
|
<strong>Roll your own auth with confidence in minutes!</strong>
|
||||||
</p>
|
</p>
|
||||||
<div className="flex mt-[10px] z-20 justify-center items-start">
|
<div className="flex mt-[10px] z-20 justify-center items-start">
|
||||||
<TechStackDisplay
|
<TechStackDisplay
|
||||||
skills={[
|
skills={[
|
||||||
"nextJs",
|
"nextJs",
|
||||||
"nuxt",
|
"nuxt",
|
||||||
"svelteKit",
|
"svelteKit",
|
||||||
"astro",
|
"astro",
|
||||||
"solidStart",
|
"solidStart",
|
||||||
"react",
|
"react",
|
||||||
"hono",
|
"hono",
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<GithubStat stars={stars} />
|
<GithubStat stars={stars} />
|
||||||
</div>
|
</div>
|
||||||
<Ripple />
|
<Ripple />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,35 @@
|
|||||||
export function GithubStat({ stars }: { stars: string | null }) {
|
export function GithubStat({ stars }: { stars: string | null }) {
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
href="https://github.com/better-auth/better-auth"
|
href="https://github.com/better-auth/better-auth"
|
||||||
className="flex mt-4 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground rounded-none h-10 p-5 ml-auto z-50 overflow-hidden items-center text-sm font-medium focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 bg-transprent text-white px-4 py-2 max-w-52 whitespace-pre md:flex group relative w-full justify-center gap-2 transition-all duration-300 ease-out hover:ring-black "
|
className="flex mt-4 border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground rounded-none h-10 p-5 ml-auto z-50 overflow-hidden items-center text-sm font-medium focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 bg-transprent text-white px-4 py-2 max-w-52 whitespace-pre md:flex group relative w-full justify-center gap-2 transition-all duration-300 ease-out hover:ring-black "
|
||||||
>
|
>
|
||||||
<span className="absolute right-0 -mt-12 h-32 w-8 translate-x-12 rotate-12 bg-white/60 opacity-10 transition-all duration-1000 ease-out group-hover:-translate-x-40"></span>
|
<span className="absolute right-0 -mt-12 h-32 w-8 translate-x-12 rotate-12 bg-white/60 opacity-10 transition-all duration-1000 ease-out group-hover:-translate-x-40"></span>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
<svg className="w-4 h-4 fill-current" viewBox="0 0 438.549 438.549">
|
<svg className="w-4 h-4 fill-current" viewBox="0 0 438.549 438.549">
|
||||||
<path d="M409.132 114.573c-19.608-33.596-46.205-60.194-79.798-79.8-33.598-19.607-70.277-29.408-110.063-29.408-39.781 0-76.472 9.804-110.063 29.408-33.596 19.605-60.192 46.204-79.8 79.8C9.803 148.168 0 184.854 0 224.63c0 47.78 13.94 90.745 41.827 128.906 27.884 38.164 63.906 64.572 108.063 79.227 5.14.954 8.945.283 11.419-1.996 2.475-2.282 3.711-5.14 3.711-8.562 0-.571-.049-5.708-.144-15.417a2549.81 2549.81 0 01-.144-25.406l-6.567 1.136c-4.187.767-9.469 1.092-15.846 1-6.374-.089-12.991-.757-19.842-1.999-6.854-1.231-13.229-4.086-19.13-8.559-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-.951-2.568-2.098-3.711-3.429-1.142-1.331-1.997-2.663-2.568-3.997-.572-1.335-.098-2.43 1.427-3.289 1.525-.859 4.281-1.276 8.28-1.276l5.708.853c3.807.763 8.516 3.042 14.133 6.851 5.614 3.806 10.229 8.754 13.846 14.842 4.38 7.806 9.657 13.754 15.846 17.847 6.184 4.093 12.419 6.136 18.699 6.136 6.28 0 11.704-.476 16.274-1.423 4.565-.952 8.848-2.383 12.847-4.285 1.713-12.758 6.377-22.559 13.988-29.41-10.848-1.14-20.601-2.857-29.264-5.14-8.658-2.286-17.605-5.996-26.835-11.14-9.235-5.137-16.896-11.516-22.985-19.126-6.09-7.614-11.088-17.61-14.987-29.979-3.901-12.374-5.852-26.648-5.852-42.826 0-23.035 7.52-42.637 22.557-58.817-7.044-17.318-6.379-36.732 1.997-58.24 5.52-1.715 13.706-.428 24.554 3.853 10.85 4.283 18.794 7.952 23.84 10.994 5.046 3.041 9.089 5.618 12.135 7.708 17.705-4.947 35.976-7.421 54.818-7.421s37.117 2.474 54.823 7.421l10.849-6.849c7.419-4.57 16.18-8.758 26.262-12.565 10.088-3.805 17.802-4.853 23.134-3.138 8.562 21.509 9.325 40.922 2.279 58.24 15.036 16.18 22.559 35.787 22.559 58.817 0 16.178-1.958 30.497-5.853 42.966-3.9 12.471-8.941 22.457-15.125 29.979-6.191 7.521-13.901 13.85-23.131 18.986-9.232 5.14-18.182 8.85-26.84 11.136-8.662 2.286-18.415 4.004-29.263 5.146 9.894 8.562 14.842 22.077 14.842 40.539v60.237c0 3.422 1.19 6.279 3.572 8.562 2.379 2.279 6.136 2.95 11.276 1.995 44.163-14.653 80.185-41.062 108.068-79.226 27.88-38.161 41.825-81.126 41.825-128.906-.01-39.771-9.818-76.454-29.414-110.049z"></path>
|
<path d="M409.132 114.573c-19.608-33.596-46.205-60.194-79.798-79.8-33.598-19.607-70.277-29.408-110.063-29.408-39.781 0-76.472 9.804-110.063 29.408-33.596 19.605-60.192 46.204-79.8 79.8C9.803 148.168 0 184.854 0 224.63c0 47.78 13.94 90.745 41.827 128.906 27.884 38.164 63.906 64.572 108.063 79.227 5.14.954 8.945.283 11.419-1.996 2.475-2.282 3.711-5.14 3.711-8.562 0-.571-.049-5.708-.144-15.417a2549.81 2549.81 0 01-.144-25.406l-6.567 1.136c-4.187.767-9.469 1.092-15.846 1-6.374-.089-12.991-.757-19.842-1.999-6.854-1.231-13.229-4.086-19.13-8.559-5.898-4.473-10.085-10.328-12.56-17.556l-2.855-6.57c-1.903-4.374-4.899-9.233-8.992-14.559-4.093-5.331-8.232-8.945-12.419-10.848l-1.999-1.431c-1.332-.951-2.568-2.098-3.711-3.429-1.142-1.331-1.997-2.663-2.568-3.997-.572-1.335-.098-2.43 1.427-3.289 1.525-.859 4.281-1.276 8.28-1.276l5.708.853c3.807.763 8.516 3.042 14.133 6.851 5.614 3.806 10.229 8.754 13.846 14.842 4.38 7.806 9.657 13.754 15.846 17.847 6.184 4.093 12.419 6.136 18.699 6.136 6.28 0 11.704-.476 16.274-1.423 4.565-.952 8.848-2.383 12.847-4.285 1.713-12.758 6.377-22.559 13.988-29.41-10.848-1.14-20.601-2.857-29.264-5.14-8.658-2.286-17.605-5.996-26.835-11.14-9.235-5.137-16.896-11.516-22.985-19.126-6.09-7.614-11.088-17.61-14.987-29.979-3.901-12.374-5.852-26.648-5.852-42.826 0-23.035 7.52-42.637 22.557-58.817-7.044-17.318-6.379-36.732 1.997-58.24 5.52-1.715 13.706-.428 24.554 3.853 10.85 4.283 18.794 7.952 23.84 10.994 5.046 3.041 9.089 5.618 12.135 7.708 17.705-4.947 35.976-7.421 54.818-7.421s37.117 2.474 54.823 7.421l10.849-6.849c7.419-4.57 16.18-8.758 26.262-12.565 10.088-3.805 17.802-4.853 23.134-3.138 8.562 21.509 9.325 40.922 2.279 58.24 15.036 16.18 22.559 35.787 22.559 58.817 0 16.178-1.958 30.497-5.853 42.966-3.9 12.471-8.941 22.457-15.125 29.979-6.191 7.521-13.901 13.85-23.131 18.986-9.232 5.14-18.182 8.85-26.84 11.136-8.662 2.286-18.415 4.004-29.263 5.146 9.894 8.562 14.842 22.077 14.842 40.539v60.237c0 3.422 1.19 6.279 3.572 8.562 2.379 2.279 6.136 2.95 11.276 1.995 44.163-14.653 80.185-41.062 108.068-79.226 27.88-38.161 41.825-81.126 41.825-128.906-.01-39.771-9.818-76.454-29.414-110.049z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
<span className="ml-2 text-white">Star on GitHub</span>
|
<span className="ml-2 text-white">Star on GitHub</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="ml-2 flex items-center gap-1 text-sm md:flex">
|
<div className="ml-2 flex items-center gap-1 text-sm md:flex">
|
||||||
<svg
|
<svg
|
||||||
className="w-4 h-4 text-gray-500 transition-all duration-300 group-hover:text-yellow-300"
|
className="w-4 h-4 text-gray-500 transition-all duration-300 group-hover:text-yellow-300"
|
||||||
data-slot="icon"
|
data-slot="icon"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
clip-rule="evenodd"
|
clip-rule="evenodd"
|
||||||
d="M10.788 3.21c.448-1.077 1.976-1.077 2.424 0l2.082 5.006 5.404.434c1.164.093 1.636 1.545.749 2.305l-4.117 3.527 1.257 5.273c.271 1.136-.964 2.033-1.96 1.425L12 18.354 7.373 21.18c-.996.608-2.231-.29-1.96-1.425l1.257-5.273-4.117-3.527c-.887-.76-.415-2.212.749-2.305l5.404-.434 2.082-5.005Z"
|
d="M10.788 3.21c.448-1.077 1.976-1.077 2.424 0l2.082 5.006 5.404.434c1.164.093 1.636 1.545.749 2.305l-4.117 3.527 1.257 5.273c.271 1.136-.964 2.033-1.96 1.425L12 18.354 7.373 21.18c-.996.608-2.231-.29-1.96-1.425l1.257-5.273-4.117-3.527c-.887-.76-.415-2.212.749-2.305l5.404-.434 2.082-5.005Z"
|
||||||
fill-rule="evenodd"
|
fill-rule="evenodd"
|
||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
<span className="inline-block tabular-nums tracking-wider font-display font-medium text-white">
|
<span className="inline-block tabular-nums tracking-wider font-display font-medium text-white">
|
||||||
{stars}
|
{stars}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,4 +186,29 @@ export const Icons = {
|
|||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
),
|
),
|
||||||
|
remix: () => (
|
||||||
|
<svg
|
||||||
|
width="1em"
|
||||||
|
height="1em"
|
||||||
|
viewBox="0 0 412 474"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
d="M393.946 364.768C398.201 419.418 398.201 445.036 398.201 473H271.756C271.756 466.909 271.865 461.337 271.975 455.687C272.317 438.123 272.674 419.807 269.828 382.819C266.067 328.667 242.748 316.634 199.871 316.634H161.883H1V218.109H205.889C260.049 218.109 287.13 201.633 287.13 158.011C287.13 119.654 260.049 96.4098 205.889 96.4098H1V0H228.456C351.069 0 412 57.9117 412 150.42C412 219.613 369.123 264.739 311.201 272.26C360.096 282.037 388.681 309.865 393.946 364.768Z"
|
||||||
|
fill="white"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M1 473V399.553H134.697C157.029 399.553 161.878 416.116 161.878 425.994V473H1Z"
|
||||||
|
fill="white"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M1 399.053H0.5V399.553V473V473.5H1H161.878H162.378V473V425.994C162.378 420.988 161.152 414.26 157.063 408.77C152.955 403.255 146.004 399.053 134.697 399.053H1Z"
|
||||||
|
stroke="white"
|
||||||
|
stroke-opacity="0.8"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -501,6 +501,11 @@ export const contents: Content[] = [
|
|||||||
href: "/docs/integrations/astro",
|
href: "/docs/integrations/astro",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: "Remix",
|
||||||
|
icon: Icons.remix,
|
||||||
|
href: "/docs/integrations/remix",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "Next",
|
title: "Next",
|
||||||
icon: Icons.nextJS,
|
icon: Icons.nextJS,
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export default function SignUp() {
|
|||||||
onRequest: (ctx) => {
|
onRequest: (ctx) => {
|
||||||
//show loading
|
//show loading
|
||||||
},
|
},
|
||||||
onsSuccess: (ctx) => {
|
onSuccess: (ctx) => {
|
||||||
//redirect to the dashboard
|
//redirect to the dashboard
|
||||||
},
|
},
|
||||||
onError: (ctx) => {
|
onError: (ctx) => {
|
||||||
@@ -317,6 +317,19 @@ The server provides a `session` object that you can use to access the session da
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
</Tab>
|
</Tab>
|
||||||
|
<Tab value="Remix">
|
||||||
|
```ts title="route.ts"
|
||||||
|
import { auth } from "lib/auth"; // path to your better auth server instance
|
||||||
|
|
||||||
|
export async function loader({ request }: LoaderFunctionArgs) {
|
||||||
|
const session = await auth.api.getSession({
|
||||||
|
headers: request.headers
|
||||||
|
})
|
||||||
|
|
||||||
|
return json({ session })
|
||||||
|
}
|
||||||
|
```
|
||||||
|
</Tab>
|
||||||
<Tab value="Astro">
|
<Tab value="Astro">
|
||||||
```astro title="index.astro"
|
```astro title="index.astro"
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ Create a new file or route in your framework's designated catch-all route handle
|
|||||||
Better auth supports any backend framework with standard Request and Response objects and offers helper functions for popular frameworks.
|
Better auth supports any backend framework with standard Request and Response objects and offers helper functions for popular frameworks.
|
||||||
</Callout>
|
</Callout>
|
||||||
|
|
||||||
<Tabs items={["next-js", "nuxt", "svelte-kit", "solid-start", "hono", "express"]} defaultValue="react">
|
<Tabs items={["next-js", "remix", "nuxt", "svelte-kit", "solid-start", "hono", "express"]} defaultValue="react">
|
||||||
<Tab value="next-js">
|
<Tab value="next-js">
|
||||||
```ts title="/app/api/auth/[...all]/route.ts"
|
```ts title="/app/api/auth/[...all]/route.ts"
|
||||||
import { auth } from "@/lib/auth"; // path to your auth file
|
import { auth } from "@/lib/auth"; // path to your auth file
|
||||||
@@ -218,6 +218,15 @@ Better auth supports any backend framework with standard Request and Response ob
|
|||||||
export const { POST, GET } = toNextJsHandler(auth);
|
export const { POST, GET } = toNextJsHandler(auth);
|
||||||
```
|
```
|
||||||
</Tab>
|
</Tab>
|
||||||
|
<Tab value="remix">
|
||||||
|
```ts title="/app/routes/api.auth.$.ts"
|
||||||
|
import { auth } from "@/lib/auth"; // path to your auth file
|
||||||
|
|
||||||
|
export async function loader({ request }) {
|
||||||
|
return auth.handler(request);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
</Tab>
|
||||||
<Tab value="nuxt">
|
<Tab value="nuxt">
|
||||||
```ts title="/server/api/auth/[...all].ts"
|
```ts title="/server/api/auth/[...all].ts"
|
||||||
import { auth } from "~/utils/auth"; // path to your auth file
|
import { auth } from "~/utils/auth"; // path to your auth file
|
||||||
|
|||||||
203
docs/content/docs/integrations/remix.mdx
Normal file
203
docs/content/docs/integrations/remix.mdx
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
---
|
||||||
|
title: Remix Integration
|
||||||
|
description: Integrate Better Auth with Remix
|
||||||
|
---
|
||||||
|
|
||||||
|
Better Auth can be easily integrated with Remix. This guide will show you how to integrate better auth with Remix.
|
||||||
|
|
||||||
|
You can follow the steps from [installation](/docs/installation) to get started or you can follow this guide to make it the Remix-way.
|
||||||
|
|
||||||
|
If you have followed the installation steps, you can skip the first step.
|
||||||
|
|
||||||
|
## Create auth instance
|
||||||
|
|
||||||
|
|
||||||
|
Create a file named `auth.server.ts` in one of these locations:
|
||||||
|
- Project root
|
||||||
|
- `lib/` folder
|
||||||
|
- `utils/` folder
|
||||||
|
|
||||||
|
You can also nest any of these folders under `app/` folder. (e.g. `app/lib/auth.server.ts`)
|
||||||
|
|
||||||
|
And in this file, import Better Auth and create your instance.
|
||||||
|
|
||||||
|
<Callout type="warn">
|
||||||
|
Make sure to export the auth instance with the variable name `auth` or as a `default` export.
|
||||||
|
</Callout>
|
||||||
|
|
||||||
|
```ts title="app/lib/auth.server.ts"
|
||||||
|
import { betterAuth } from "better-auth"
|
||||||
|
|
||||||
|
export const auth = betterAuth({
|
||||||
|
database: {
|
||||||
|
provider: "postgres", //change this to your database provider
|
||||||
|
url: process.env.DATABASE_URL, // path to your database or connection string
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
## Create API Route
|
||||||
|
|
||||||
|
We need to mount the handler to a API route. Create a resource route file `api.auth.$.ts` inside `app/routes/` directory. And add the following code:
|
||||||
|
|
||||||
|
```ts title="app/routes/api.auth.$.ts"
|
||||||
|
import { auth } from '~/lib/auth.server' // Adjust the path as necessary
|
||||||
|
import type { LoaderFunctionArgs, ActionFunctionArgs } from "@remix-run/node"
|
||||||
|
|
||||||
|
export async function loader({ request }: LoaderFunctionArgs) {
|
||||||
|
return auth.handler(request)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function action({ request }: ActionFunctionArgs) {
|
||||||
|
return auth.handler(request)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
<Callout type="info">
|
||||||
|
You can change the path on your better-auth configuration but it's recommended to keep it as `routes/api.auth.$.ts`
|
||||||
|
</Callout>
|
||||||
|
|
||||||
|
## Create a client
|
||||||
|
|
||||||
|
Create a client instance. Here we are creating `auth.client.ts` file inside the `lib/` directory.
|
||||||
|
|
||||||
|
```ts title="app/lib/auth.client.ts"
|
||||||
|
import { createAuthClient } from "better-auth/react" // make sure to import from better-auth/react
|
||||||
|
|
||||||
|
export const client = createAuthClient({
|
||||||
|
//you can pass client configuration here
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Once you have created the client, you can use it to sign up, sign in, and perform other actions.
|
||||||
|
|
||||||
|
### Example usage
|
||||||
|
|
||||||
|
#### Sign Up
|
||||||
|
|
||||||
|
```ts title="app/routes/signup.tsx"
|
||||||
|
import { Form } from "@remix-run/react"
|
||||||
|
import { useState } from "react"
|
||||||
|
import { client } from "~/lib/auth.client"
|
||||||
|
|
||||||
|
export default function Signup() {
|
||||||
|
const [email, setEmail] = useState("")
|
||||||
|
const [name, setName] = useState("")
|
||||||
|
const [password, setPassword] = useState("")
|
||||||
|
|
||||||
|
const signUp = async () => {
|
||||||
|
await authClient.signUp.email(
|
||||||
|
{
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
name,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onRequest: (ctx) => {
|
||||||
|
// show loading state
|
||||||
|
},
|
||||||
|
onSuccess: (ctx) => {
|
||||||
|
// redirect to home
|
||||||
|
},
|
||||||
|
onError: (ctx) => {
|
||||||
|
alert(ctx.error)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>
|
||||||
|
Sign Up
|
||||||
|
</h2>
|
||||||
|
<Form
|
||||||
|
onSubmit={signUp}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={name}
|
||||||
|
onChange={(e) => setName(e.target.value)}
|
||||||
|
placeholder="Name"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
|
placeholder="Email"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
value={password}
|
||||||
|
onChange={(e) => setPassword(e.target.value)}
|
||||||
|
placeholder="Password"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
Sign Up
|
||||||
|
</button>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Sign In
|
||||||
|
|
||||||
|
```ts title="app/routes/signin.tsx"
|
||||||
|
import { Form } from "@remix-run/react"
|
||||||
|
import { useState } from "react"
|
||||||
|
import { authClient } from "~/services/auth.client"
|
||||||
|
|
||||||
|
export default function Signup() {
|
||||||
|
const [email, setEmail] = useState("")
|
||||||
|
const [password, setPassword] = useState("")
|
||||||
|
|
||||||
|
const signIn = async () => {
|
||||||
|
await authClient.signIn.email(
|
||||||
|
{
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onRequest: (ctx) => {
|
||||||
|
// show loading state
|
||||||
|
},
|
||||||
|
onSuccess: (ctx) => {
|
||||||
|
// redirect to home
|
||||||
|
},
|
||||||
|
onError: (ctx) => {
|
||||||
|
alert(ctx.error)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>
|
||||||
|
Sign In
|
||||||
|
</h2>
|
||||||
|
<Form onSubmit={signIn}>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
value={password}
|
||||||
|
onChange={(e) => setPassword(e.target.value)}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
>
|
||||||
|
Sign In
|
||||||
|
</button>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user