Configuration & Customization
Learn how to configure and customize your SAMS instance to match your business needs.
Configuration & Customization
SAMS is highly configurable, allowing you to customize everything from branding to feature availability. This guide covers all configuration options.
Central Configuration
The main configuration file is located at config/index.ts. This file controls all major features and settings:
// config/index.ts
export const config = {
appName: "Your App Name",
companyName: "Your Company",
// Feature toggles
organizations: {
enable: true,
enableBilling: true,
enableUsersToCreateOrganizations: false,
requireOrganization: false,
},
// Authentication settings
auth: {
enableSignup: true,
enableMagicLink: true,
enableSocialLogin: true,
enablePasskeys: true,
enablePasswordLogin: true,
enableTwoFactor: true,
},
// UI settings
ui: {
enabledThemes: ["light", "dark"],
defaultTheme: "light",
saas: {
enabled: true,
useSidebarLayout: true,
},
},
// ... more configuration options
}Application Branding
Basic Branding
Update your application's basic branding:
// config/index.ts
export const config = {
appName: "Your SaaS Platform",
companyName: "Your Company Inc.",
// Email settings
mails: {
from: "noreply@yourdomain.com",
},
}Logo and Assets
Replace the default logos and assets:
- App Icon: Replace
apps/web/public/icon.png - Favicon: Replace
apps/web/public/favicon.ico - Logo: Update logo in navigation components
- Login Images: Replace images in
apps/web/public/images/
Color Theme
Customize the color scheme in apps/web/app/globals.css:
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--primary: 221.2 83.2% 53.3%;
--primary-foreground: 210 40% 98%;
/* ... more color variables */
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
/* ... dark mode colors */
}Feature Configuration
Organizations
Control organization features:
// config/index.ts
organizations: {
// Enable/disable organizations entirely
enable: true,
// Enable organization-level billing
enableBilling: true,
// Hide organizations from users (single-tenant mode)
hideOrganization: false,
// Allow users to create organizations
enableUsersToCreateOrganizations: false,
// Require users to be in an organization
requireOrganization: false,
// Forbidden organization slugs
forbiddenOrganizationSlugs: [
"admin", "api", "app", "www", "mail", "ftp"
],
}Authentication
Configure authentication methods:
// config/index.ts
auth: {
// User registration
enableSignup: true,
// Authentication methods
enableMagicLink: true,
enableSocialLogin: true,
enablePasskeys: true,
enablePasswordLogin: true,
enableTwoFactor: true,
// Redirects
redirectAfterSignIn: "/app",
redirectAfterLogout: "/",
// Session duration (seconds)
sessionCookieMaxAge: 60 * 60 * 24 * 30, // 30 days
}UI Features
Control UI behavior:
// config/index.ts
ui: {
// Available themes
enabledThemes: ["light", "dark"],
defaultTheme: "light",
// SaaS application
saas: {
enabled: true,
useSidebarLayout: true,
},
// Marketing site
marketing: {
enabled: true,
},
}User Settings
Configure user features:
// config/index.ts
users: {
// Enable user-level billing (vs organization billing)
enableBilling: false,
// Onboarding flow
enableOnboarding: true,
}Payment Configuration
Payment Plans
Define your subscription plans:
// config/index.ts
payments: {
enabled: true,
provider: "stripe", // or "mock" for development
plans: {
free: {
isFree: true,
features: ["basic_features"],
},
starter: {
features: ["core_features", "email_support"],
prices: [
{
type: "recurring",
productId: process.env.NEXT_PUBLIC_PRICE_ID_STARTER_MONTHLY,
interval: "month",
amount: 49,
currency: "USD",
trialPeriodDays: 14,
},
// ... more price options
],
},
// ... more plans
}
}Payment Providers
Configure your payment provider in the environment:
# Stripe
STRIPE_SECRET_KEY="sk_live_your_stripe_secret_key"
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_live_your_stripe_publishable_key"
STRIPE_WEBHOOK_SECRET="whsec_your_webhook_secret"
# Other providers can be added in packages/payments/Internationalization
SAMS supports multiple languages:
Enable i18n
// config/index.ts
i18n: {
enabled: true,
locales: {
en: {
currency: "USD",
label: "English",
},
de: {
currency: "EUR",
label: "Deutsch",
},
es: {
currency: "EUR",
label: "Español",
},
},
defaultLocale: "en",
defaultCurrency: "USD",
localeCookieName: "NEXT_LOCALE",
}Add Translations
Add translations in packages/i18n/translations/:
translations/
├── en.json
├── de.json
└── es.jsonExample translation file:
{
"navigation": {
"dashboard": "Dashboard",
"marketplace": "Marketplace",
"settings": "Settings"
},
"auth": {
"signIn": "Sign In",
"signUp": "Sign Up",
"signOut": "Sign Out"
}
}Email Configuration
Email Provider Setup
Configure email sending:
# Resend (recommended)
RESEND_API_KEY="re_your_resend_api_key"
# Or Postmark
POSTMARK_API_KEY="your_postmark_api_key"
# Or SMTP
SMTP_HOST="smtp.yourdomain.com"
SMTP_PORT="587"
SMTP_USER="your_smtp_user"
SMTP_PASS="your_smtp_password"Email Templates
Customize email templates in packages/emails/templates/:
- Welcome emails
- Password reset emails
- Organization invitations
- Billing notifications
Database Customization
Adding Custom Fields
To add custom fields to existing models:
- Update Prisma Schema (
packages/database/schema.prisma):
model User {
id String @id @default(cuid())
email String @unique
name String?
// Add your custom fields
company String?
phone String?
// ... existing fields
}- Generate Migration:
cd packages/database
pnpm migrate dev --name add_user_custom_fields- Update Zod Schemas:
pnpm generateAdding New Models
Create new models by adding them to the Prisma schema and running migrations:
model CustomData {
id String @id @default(cuid())
userId String
data Json
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@map("custom_data")
}API Customization
Adding Custom Endpoints
Create custom API endpoints in packages/api/src/routes/:
// packages/api/src/routes/custom.ts
import { Hono } from 'hono'
import { z } from 'zod'
const app = new Hono()
app.get('/custom-data', async (c) => {
// Your custom logic here
return c.json({ message: 'Custom endpoint' })
})
export default appRegister in main app:
// packages/api/src/app.ts
import customRoutes from './routes/custom'
app.route('/api/custom', customRoutes)Custom Middleware
Add custom middleware for your specific needs:
// packages/api/src/middleware/custom.ts
import { createMiddleware } from 'hono/factory'
export const customMiddleware = createMiddleware(async (c, next) => {
// Your custom logic
await next()
})Environment Variables
Required Variables
# Database
DATABASE_URL="postgresql://..."
# Authentication
NEXTAUTH_SECRET="your-secret-key"
NEXTAUTH_URL="https://yourdomain.com"
# Application
NEXT_PUBLIC_APP_URL="https://yourdomain.com"
NEXT_PUBLIC_APP_NAME="Your App Name"Optional Variables
# Email
RESEND_API_KEY="re_..."
EMAIL_FROM="noreply@yourdomain.com"
# Payments
STRIPE_SECRET_KEY="sk_..."
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_..."
# OAuth Providers
GOOGLE_CLIENT_ID="..."
GOOGLE_CLIENT_SECRET="..."
GITHUB_CLIENT_ID="..."
GITHUB_CLIENT_SECRET="..."
# Analytics
GOOGLE_ANALYTICS_ID="GA_..."
MIXPANEL_TOKEN="..."
# Storage
AWS_ACCESS_KEY_ID="..."
AWS_SECRET_ACCESS_KEY="..."
AWS_REGION="us-east-1"
AWS_BUCKET_NAME="your-bucket"Advanced Customization
Custom Components
Replace default components by creating alternatives in your app:
// apps/web/components/custom/CustomDashboard.tsx
export function CustomDashboard() {
return (
<div>
{/* Your custom dashboard */}
</div>
)
}Custom Layouts
Override default layouts in your app router:
// apps/web/app/(saas)/app/layout.tsx
import { CustomSidebar } from '@/components/custom/CustomSidebar'
export default function CustomAppLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<div className="flex">
<CustomSidebar />
<main className="flex-1">
{children}
</main>
</div>
)
}Theme Customization
Create custom themes:
// apps/web/lib/themes.ts
export const customTheme = {
light: {
primary: "210 100% 50%",
secondary: "210 100% 95%",
// ... other colors
},
dark: {
primary: "210 100% 60%",
secondary: "210 100% 10%",
// ... other colors
}
}Best Practices
Configuration
- Environment-specific configs: Use different values for development/production
- Type safety: Keep TypeScript types for all configuration
- Validation: Validate configuration on startup
- Documentation: Document all custom configuration options
Customization
- Backup originals: Keep copies of original files before modifying
- Version control: Track all customizations in git
- Update strategy: Plan how to handle framework updates
- Testing: Test all customizations thoroughly
Performance
- Bundle size: Monitor impact of customizations on bundle size
- Database indexes: Add indexes for custom queries
- Caching: Implement caching for custom data
- Monitoring: Monitor performance of custom features
Next: Learn about Authentication Setup to configure auth providers and security settings.