Package Exports
- @ernes7/clerk-auth
Readme
@ernes7/clerk-auth
TypeScript wrapper for @clerk/nextjs with enhanced API integration and React hooks for Django backend communication.
Installation
npm install @ernes7/clerk-authPeer Dependencies: This package requires @clerk/nextjs, react, and next to be installed.
npm install @clerk/nextjs react nextQuick Start
1. Wrap Your App with AuthProvider
// app/layout.tsx
import { ClerkProvider } from '@clerk/nextjs'
import { AuthProvider } from '@ernes7/clerk-auth'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<ClerkProvider>
<html lang="en">
<body>
<AuthProvider apiUrl={process.env.NEXT_PUBLIC_API_URL}>
{children}
</AuthProvider>
</body>
</html>
</ClerkProvider>
)
}2. Use Hooks in Your Components
// app/dashboard/page.tsx
'use client'
import { useAPI, useRole, Protected } from '@ernes7/clerk-auth'
interface Invoice {
id: string
amount: number
status: string
}
export default function Dashboard() {
// Auto-fetch data from Django API
const { data, loading, error } = useAPI<Invoice[]>('/api/invoices/')
const { isAdmin, role } = useRole()
if (loading) return <div>Loading...</div>
if (error) return <div>Error: {error}</div>
return (
<div>
<h1>Dashboard</h1>
{/* Show data */}
<InvoiceList data={data} />
{/* Role-based rendering */}
<Protected role="admin">
<AdminPanel />
</Protected>
{isAdmin && <button>Admin Actions</button>}
</div>
)
}3. Make API Calls with Automatic Auth
'use client'
import { useAPI } from '@ernes7/clerk-auth'
export default function CreateInvoice() {
const api = useAPI()
const handleCreate = async () => {
try {
const invoice = await api.post('/api/invoices/', {
amount: 100.00,
description: 'New invoice'
})
console.log('Created:', invoice)
} catch (error) {
console.error('Error:', error)
}
}
return <button onClick={handleCreate}>Create Invoice</button>
}Features
Automatic JWT Token Injection
All API requests automatically include the Clerk JWT token in the Authorization header:
// No need to manually add auth headers!
const api = useAPI()
await api.get('/api/invoices/') // Authorization header added automaticallyReact Hooks
useAPI<T>(endpoint?, options?)
Fetch data from your API with automatic token injection and type safety.
// Auto-fetch on mount
const { data, loading, error, refetch } = useAPI<Invoice[]>('/api/invoices/')
// Manual API calls
const api = useAPI()
await api.post('/api/invoices/', data)
await api.put('/api/invoices/123/', data)
await api.delete('/api/invoices/123/')useRole()
Access user's organization role and check permissions.
const { role, isAdmin, hasRole } = useRole()
if (isAdmin) {
// Show admin UI
}
if (hasRole('editor')) {
// Allow editing
}useOrg()
Access organization context.
const { orgId, orgRole, isOrgMember } = useOrg()Components
<Protected>
Render content based on role or permission.
<Protected role="admin">
<AdminPanel />
</Protected>
<Protected permission="write:invoices">
<CreateButton />
</Protected><AdminOnly>
Shortcut for admin-only content.
<AdminOnly>
<AdminSettings />
</AdminOnly><HasPermission>
Render based on permission.
<HasPermission permission="read:invoices">
<InvoiceList />
</HasPermission>API Reference
AuthProvider
Provider component that configures the API client.
Props:
apiUrl(required): Base URL for your Django APIorgHeader(optional): Header name for organization context (default:X-Organization-ID)
useAPI<T>(endpoint?, options?)
Hook for API calls with automatic authentication.
Returns:
data: Response data (if endpoint provided)loading: Loading stateerror: Error message if request failedrefetch(): Function to refetch dataget(endpoint): Make GET requestpost(endpoint, data): Make POST requestput(endpoint, data): Make PUT requestpatch(endpoint, data): Make PATCH requestdelete(endpoint): Make DELETE request
Options:
method: HTTP method (default: 'GET')headers: Additional headersbody: Request body
useRole()
Hook to access user's role and permissions.
Returns:
role: User's organization roleisAdmin: Boolean if user has admin rolehasRole(role): Function to check specific role
useOrg()
Hook to access organization context.
Returns:
orgId: Current organization IDorgRole: User's role in organizationisOrgMember: Boolean if user is org member
TypeScript Support
Full TypeScript support with type inference:
interface Invoice {
id: string
amount: number
}
// Type-safe data fetching
const { data } = useAPI<Invoice[]>('/api/invoices/')
// data is typed as Invoice[] | null
// Type-safe mutations
const api = useAPI()
const invoice = await api.post<Invoice>('/api/invoices/', {
amount: 100
})
// invoice is typed as InvoiceLicense
MIT License - see LICENSE file for details.