Remix Adapter
The Remix adapter provides helper functions for using @loewen-digital/fullstack in Remix loaders and actions. Because Remix already uses Web Standard Request and Response objects, integration is straightforward.
Import
ts
import { getUser, requireUser } from '@loewen-digital/fullstack/adapters/remix'Setup
1. Create your stack
ts
// app/lib/stack.server.ts
import { createDb } from '@loewen-digital/fullstack/db'
import { createAuth } from '@loewen-digital/fullstack/auth'
export const db = createDb({ driver: 'sqlite', url: './app.db' })
export const auth = createAuth({
db,
session: { driver: 'cookie', secret: process.env.SESSION_SECRET! },
})2. Create adapter helpers
ts
// app/lib/auth.server.ts
import { getUser, requireUser } from '@loewen-digital/fullstack/adapters/remix'
import { auth } from './stack.server.js'
export const getCurrentUser = getUser(auth)
export const requireAuth = requireUser(auth, '/login')Using in loaders
ts
// app/routes/dashboard.tsx
import { json, type LoaderFunctionArgs } from '@remix-run/node'
import { requireAuth } from '~/lib/auth.server'
export async function loader({ request }: LoaderFunctionArgs) {
const user = await requireAuth(request)
// Redirects to /login if not authenticated
return json({ user })
}Login action
ts
// app/routes/login.tsx
import { json, redirect, type ActionFunctionArgs } from '@remix-run/node'
import { validate } from '@loewen-digital/fullstack/validation'
import { auth } from '~/lib/stack.server'
export async function action({ request }: ActionFunctionArgs) {
const data = Object.fromEntries(await request.formData())
const result = validate(data, {
email: ['required', 'email'],
password: ['required'],
})
if (!result.passes) {
return json({ errors: result.errors }, { status: 422 })
}
const user = await auth.attempt(result.data)
if (!user) {
return json({ error: 'Invalid credentials' }, { status: 401 })
}
const response = redirect('/dashboard')
await auth.login(user, response)
return response
}Logout action
ts
export async function action({ request }: ActionFunctionArgs) {
return auth.logout(request)
// Returns a redirect Response that clears the session
}Notes
- Remix already uses
RequestandResponse— no conversion layer is needed - The adapter helpers are thin wrappers that call
auth.user(request)under the hood - All
@loewen-digital/fullstackmodules work directly with Remix's nativeRequestobjects