redwood-clerk
Version:
Unofficial Clerk integration for RedwoodSDK
144 lines (106 loc) • 3.15 kB
Markdown
Unofficial [Clerk](https://clerk.com/) integration for RedwoodSDK.
Minimal example: https://github.com/wobsoriano/redwood-clerk-minimal
```bash
npm install redwood-clerk
```
`clerkMiddleware()` grants you access to user authentication state throughout your app.
In your entry point (`src/worker.tsx`) file, add the `clerkMiddleware()` helper to the `defineApp` function:
```tsx
import { clerkMiddleware } from 'redwood-clerk/server';
import type { ClerkAppContext } from 'redwood-clerk/server';
export type AppContext = ClerkAppContext & {
// Addition context properties
};
export default defineApp([
setCommonHeaders(),
clerkMiddleware(),
render(Document, [...]),
]);
```
In your `src/app/headers.ts` file, update the `Content-Security-Policy` header for Clerk to work correctly in your application:
```ts
import { frontendApi } from 'redwood-clerk/server';
const cspHeader = `
default-src 'self';
script-src 'self' 'strict-dynamic' 'nonce-${nonce}' https://${frontendApi} https://challenges.cloudflare.com;
connect-src 'self' https://${frontendApi};
img-src 'self' https://img.clerk.com;
style-src 'self' 'unsafe-inline';
frame-src https://challenges.cloudflare.com;
object-src 'none';
form-action 'self';
`
headers.set('Content-Security-Policy', cspHeader.replace(/\n/g, ''));
```
Add the `<ClerkProvider>` component to your app's layout. This component provides Clerk's authentication context to your app.
```tsx
import {
ClerkProvider,
SignInButton,
SignUpButton,
SignedIn,
SignedOut,
UserButton,
} from 'redwood-clerk';
export const AppLayout = ({ children }) => {
return (
<ClerkProvider>
<header>
<SignedOut>
<SignInButton />
<SignUpButton />
</SignedOut>
<SignedIn>
<UserButton />
</SignedIn>
</header>
{children}
</ClerkProvider>
);
}
```
Run your project in development mode and go to http://localhost:5173
```tsx
import { auth, clerkClient } from 'redwood-clerk/server'
export default async function Page() {
const { userId } = await auth()
// Protect the route by checking if the user is signed in
if (!userId) {
return <div>Sign in to view this page</div>
}
const user = await clerkClient().users.getUser(userId)
return <div>Welcome, {user.firstName}!</div>
}
```
```tsx
'use client'
import { useAuth } from 'redwood-clerk'
export default function Example() {
const { isLoaded, isSignedIn, userId } = useAuth()
// Use `isLoaded` to check if Clerk is loaded
if (!isLoaded) {
return <div>Loading...</div>
}
// Use `isSignedIn` to check if the user is signed in
if (!isSignedIn) {
return <div>Sign in to view this page</div>
}
return (
<div>
Hello, {userId}! Your current active session is {sessionId}.
</div>
)
}
````
MIT