Guidelines for writing Remix apps with Clerk Auth
Guides developers through integrating Clerk authentication into a Remix app with TypeScript, route protection, and middleware.
What this file does
Guides developers through integrating Clerk authentication into a Remix app with TypeScript, route protection, and middleware.
When to use it
- Starting a new Remix project that needs Clerk auth
- Adding authentication to an existing Remix app
- Implementing protected routes and admin-only access in Remix
- Setting up Clerk with TypeScript for type safety
Assumes this stack
title: "Guidelines for writing Remix apps with Clerk Auth" description: "Bootstrap Remix app with Clerk Auth" tags: ["Remix", "Clerk", "Integration", "Setup", "Frontend"] category: "Coding" author: "Csaba Farkas" slug: "guidelines-for-writing-remix-apps-with-clerk-auth" id: "coding-96" seo_keywords: "Remix Clerk integration, Clerk setup, Remix authentication, Server-side rendering, Remix loaders" date: "2025-07-13" difficulty: "Advanced" schema_type: "TechArticle"
Guidelines for writing Remix apps with Clerk Auth
Bootstrap Remix app with Clerk Auth
Overview of implementing Clerk Auth
- Install @clerk/remix package
- Configure environment variables
- Set up root authentication loader
- Implement authentication components
- Add route protection
Critical Instructions for AI Language Models
As an AI language model, you MUST follow these guidelines when implementing Clerk with Remix:
- Always use the latest @clerk/remix package
- Implement proper TypeScript types for type safety
- Handle environment variables securely
- Follow Remix best practices and patterns
- Implement proper error handling
Correct Root Configuration
// root.tsx
import { rootAuthLoader } from '@clerk/remix/ssr.server'
import { ClerkApp } from '@clerk/remix'
import type { LoaderFunction } from '@remix-run/node'
export const loader: LoaderFunction = args => rootAuthLoader(args)
function App() {
return (
<html>
<head>
<Meta />
<Links />
</head>
<body>
<Outlet />
<ScrollRestoration />
<Scripts />
<LiveReload />
</body>
</html>
)
}
export default ClerkApp(App)
Correct Authentication Components
// routes/auth.tsx
import { SignIn, SignUp, UserButton } from '@clerk/remix'
import { useUser } from '@clerk/remix'
export default function Auth() {
const { isSignedIn, user } = useUser()
return (
<div>
{isSignedIn ? (
<div>
<p>Welcome, {user.firstName}</p>
<UserButton afterSignOutUrl="/login" />
</div>
) : (
<div>
<SignIn routing="path" path="/sign-in" />
<SignUp routing="path" path="/sign-up" />
</div>
)}
</div>
)
}
Route Protection Implementation
// routes/protected.tsx
import { getAuth } from '@clerk/remix/ssr.server'
import { redirect } from '@remix-run/node'
import type { LoaderFunction } from '@remix-run/node'
export const loader: LoaderFunction = async args => {
const { userId } = await getAuth(args)
if (!userId) {
return redirect('/sign-in')
}
return json({ userId })
}
export default function Protected() {
const { userId } = useLoaderData<typeof loader>()
return (
<div>
<h1>Protected Route</h1>
<p>User ID: {userId}</p>
</div>
)
}
Middleware Implementation
// middleware.ts
import { createClerkClient } from '@clerk/remix/api.server'
import { getAuth } from '@clerk/remix/ssr.server'
import { redirect } from '@remix-run/node'
import type { LoaderFunction } from '@remix-run/node'
const clerk = createClerkClient()
export const protectedLoader: LoaderFunction = async args => {
const { userId } = await getAuth(args)
if (!userId) {
return redirect('/sign-in')
}
const user = await clerk.users.getUser(userId)
return { user }
}
export const adminLoader: LoaderFunction = async args => {
const { userId } = await getAuth(args)
if (!userId) {
return redirect('/sign-in')
}
const user = await clerk.users.getUser(userId)
if (!user.publicMetadata.isAdmin) {
return redirect('/')
}
return { user }
}
Environment Variables Setup
Create a .env file:
CLERK_PUBLISHABLE_KEY=your-publishable-key
CLERK_SECRET_KEY=your-secret-key
AI Model Verification Steps
Before generating any code, you MUST verify:
- Is TypeScript properly configured?
- Are environment variables properly handled?
- Is error handling implemented?
- Are authentication state and user data properly typed?
- Is route protection configured correctly?
Consequences of Incorrect Implementation
If you generate code incorrectly:
- Type safety will be compromised
- Authentication flows may fail
- Security vulnerabilities may be introduced
- Route protection may be bypassed
- User data may be exposed
AI Model Response Template
When implementing Clerk Auth for Remix, you MUST:
- Use TypeScript for type safety
- Implement proper error handling
- Follow Remix loader/action patterns
- Configure secure route protection
- Handle environment variables properly
What's inside
7 sections including setup steps, 4 code examples, environment variables, and verification checklist
Change this for your project
- Replace
your-publishable-keyandyour-secret-keywith your Clerk API keys - Replace
/sign-inand/sign-uppaths if your routes differ - Replace
afterSignOutUrl="/login"with your desired redirect
Where it goes
Keep it in your repository where the agent or team that needs it will read it.
Worth borrowing
- Using a reusable
protectedLoaderandadminLoaderto centralize auth checks - Checking
user.publicMetadata.isAdminfor role-based access control
Related Documents
How you work
Defines personality, planning, task execution, and communication conventions for a coding agent in the Codex CLI environment.
How you work
Defines personality, planning, task execution, and communication guidelines for a coding agent in Codex CLI.
内置 Agent 提示词
Documents the system prompts, tool permissions, and model assignments for six built-in subagents in Claude Code.
perplexity-ai_20250112
Defines the system prompt for Perplexity AI, instructing the assistant on how to answer queries using search results with strict formatting, citation, and query-type rules.