A directory of legal technology tools organized by law firm function, with firm tech stack profiles and a resources/blog section.
Built with Next.js 15, Payload CMS v3, PostgreSQL, Redis (optional), and Tailwind CSS v4.
- Tools directory - Browse legal tech tools by category (Document Management, Billing, eDiscovery, etc.)
- Firm profiles - Public submission form where firms showcase their tech stacks (admin-approved)
- Resources/blog - Articles, guides, and YouTube videos with rich text and SEO
- Payload CMS admin at
/adminfor managing all content - SEO-ready - JSON-LD structured data, Open Graph metadata, sitemap, robots.txt
- Redis caching and rate limiting (optional - app works without it)
- Node.js 22+
- PostgreSQL (local or remote)
- Redis (optional)
-
Clone the repo and install dependencies:
git clone <your-repo-url> cd lawyers npm install
-
Copy the env file and fill in values:
cp .env.example .env
Required variables:
DATABASE_URI- PostgreSQL connection stringPAYLOAD_SECRET- A random secret string (generate withopenssl rand -base64 32)NEXT_PUBLIC_SERVER_URL-http://localhost:3000for local dev
Optional:
REDIS_URL- Enables caching and rate limiting
-
Run the dev server:
npm run dev
-
Open http://localhost:3000 for the site, or http://localhost:3000/admin to create your first admin user.
-
(Optional) Seed sample data:
npm run seed
- Sign up at railway.app if you haven't already
- Click New Project → Deploy from GitHub repo
- Select this repository
- In your Railway project, click + New → Database → Add PostgreSQL
- Railway automatically creates a
DATABASE_URLvariable in the Postgres service
- Click + New → Database → Add Redis
- Railway creates a
REDIS_URLvariable in the Redis service
Go to your app service → Variables and add:
| Variable | Value |
|---|---|
DATABASE_URI |
${{Postgres.DATABASE_URL}} (reference the Postgres service) |
PAYLOAD_SECRET |
Generate with openssl rand -base64 32 |
NEXT_PUBLIC_SERVER_URL |
Your Railway app URL (e.g. https://your-app.up.railway.app) |
REDIS_URL |
${{Redis.REDIS_URL}} (if you added Redis) |
Important: Payload uses DATABASE_URI (not DATABASE_URL). Use the reference variable syntax ${{Postgres.DATABASE_URL}} to link them.
- Railway auto-detects the Dockerfile and builds the app
- Once deployed, visit
https://your-app.up.railway.app/admin - Create your first admin user
- Start adding categories, tools, firm profiles, and resources through the admin panel
SSH into your Railway service or run the seed script locally against your Railway database:
DATABASE_URI="<your-railway-postgres-url>" npm run seed- In Railway, go to your app service → Settings → Networking
- Click Generate Domain (free subdomain) or Custom Domain
- Update
NEXT_PUBLIC_SERVER_URLto match your custom domain
src/
├── app/
│ ├── (frontend)/ # Public-facing pages
│ ├── (payload)/ # Payload admin panel
│ └── api/ # Payload REST API
├── collections/ # Payload CMS collections (data models)
├── components/ # Shared React components
├── lib/ # Utilities (payload client, cache, rate limit, media)
└── payload.config.ts # Payload CMS configuration
Once deployed, log in to /admin to manage:
- Categories - Tool categories (Document Management, Billing, etc.)
- Tools - Individual tools with logo, description, pricing, features, and categories
- Firm Profiles - Approve/reject firm submissions and add your own
- Resources - Blog posts, videos, and guides
- Media - Upload images and logos
- Users - Add more admin users
npm run dev # Start dev server
npm run build # Production build
npm run start # Start production server
npm run seed # Seed sample data
npm run generate:types # Generate TypeScript types from Payload collections- Framework: Next.js 15 (App Router)
- CMS: Payload CMS v3 (embedded in Next.js)
- Database: PostgreSQL via
@payloadcms/db-postgres - Cache: Redis via
ioredis(optional) - Styling: Tailwind CSS v4
- Rich Text: Payload Lexical editor
- SEO:
@payloadcms/plugin-seo - Icons: Lucide React
- Deployment: Railway (Docker)