MoveFast is designed to be customized quickly. Most changes involve editing a few config files rather than digging through the codebase.
Branding
Site Name and URLs
Edit src/constants/website.ts:
export const WEBSITE = {
NAME: "YourApp", // Shown in UI, emails, metadata
URL: PUBLIC_ENV.WEBSITE_URL, // Set via NEXT_PUBLIC_WEBSITE_URL env var
SUPPORT_EMAIL: "support@yourapp.com", // Shown in footer, legal pages
ADMIN_EMAIL: "admin@yourapp.com", // Receives notification emails
ADDRESS: "Your Company Address", // Used in legal pages
TWITTER_URL: "https://twitter.com/yourapp",
GITHUB_URL: "https://github.com/yourapp",
LINKEDIN_URL: "https://linkedin.com/company/yourapp",
};This single file controls the brand name everywhere: the navbar, footer, emails, metadata, and legal pages.
Logo
Replace these files in public/:
logo.png- Main logo (used in navbar, light mode)logo-white.png- White version (used on dark backgrounds)og-image.png- Social sharing image (1200x630)web-app-manifest-192x192.png- PWA icon smallweb-app-manifest-512x512.png- PWA icon large
Colors and Theme
MoveFast uses Tailwind CSS 4 with CSS variables for theming. The color system supports both light and dark modes automatically via next-themes.
To change colors, edit the CSS variables in your global stylesheet (src/app/globals.css). The key variables are:
:root {
--primary: ...;
--primary-foreground: ...;
--background: ...;
--foreground: ...;
/* etc. */
}If you are using shadcn/ui's theming system, you can generate new color themes at ui.shadcn.com/themes.
Pricing Configuration
Everything about pricing lives in src/config/pricing.config.ts:
Change Payment Model
// One-time payments (lifetime access)
export const PAYMENT_MODEL = PaymentModel.ONE_TIME;
// Recurring subscriptions
export const PAYMENT_MODEL = PaymentModel.SUBSCRIPTION;Change Currency
export const DEFAULT_CURRENCY = "EUR"; // ISO 4217 code (sent to payment provider)
export const CURRENCY_SYMBOL = "€"; // Displayed in the UIAdd or Remove Pricing Tiers
Edit the PRICING_PLANS array. Each plan has:
{
name: "Plan Name",
description: "Short description",
productIds: {
monthly: "provider-product-id",
yearly: "provider-product-id",
oneTime: "provider-product-id",
},
price: {
monthly: 29, // Monthly price
yearly: 23, // Per-month price when billed yearly
},
oneTimePrice: 149, // One-time payment price
highlighted: true, // Visual emphasis
badge: "Most Popular",
features: [
{ name: "Feature name", description: "Optional detail", included: true },
{ name: "Not included feature", included: false },
],
cta: {
text: "Get Started",
variant: "default", // "default" or "outline"
},
}Free Tier
Use "free" as the product ID for a free plan:
productIds: {
monthly: "free",
yearly: "free",
}Free plans skip the checkout flow entirely.
Platform Access Mode
Control who can sign up in src/config/platform.config.ts:
// Before launch: invite-only with waitlist
export const PLATFORM_ACCESS_MODE = PlatformAccessMode.WAITLIST_WITH_INVITES;
// After launch: open signup
export const PLATFORM_ACCESS_MODE = PlatformAccessMode.OPEN;Landing Page Sections
The landing page is composed of sections in src/components/landing/:
HeroSection- Main headline, CTA button, trust elementsFeaturesSection- Feature highlightsUseCasesSection- Use case cardsPricingSection- Pricing plans with billing toggleFAQSection- Accordion-based FAQCTASection- Final call to action
Each section is a standalone component. You can reorder them, remove ones you do not need, or add new ones by editing src/app/(main)/page.tsx.
Blog Posts
Add new blog posts as MDX files in content/blog/:
---
title: "Your Blog Post Title"
description: "A short description for SEO"
date: "2025-01-15"
tags: ["saas", "startup"]
published: true
pinned: false
author: "Your Name"
authorImage: "/images/authors/you.jpg"
image: "/images/blog/your-post-image.png"
---
Your blog content here. Supports **markdown** and React components.Blog posts are automatically:
- Listed at
/blogswith tag filtering - Accessible at
/blogs/[slug] - Included in the sitemap
- Given proper SEO metadata
Legal Pages
Legal page content is at:
src/app/(main)/privacy-policy/page.tsxsrc/app/(main)/terms-of-service/page.tsxsrc/app/(main)/cookie-policy/page.tsx
These pull the company name, address, and support email from src/constants/website.ts. Update the actual legal text to match your product and jurisdiction.
Adding New Pages
To add a new public page:
- Create a folder in
src/app/(main)/your-page/ - Add a
page.tsx:
import { createMetadata } from "@/lib/seo/metadata";
export const metadata = createMetadata({
title: "Your Page",
description: "Description for SEO",
path: "/your-page",
});
export default function YourPage() {
return (
<div className="container mx-auto px-4 py-20">
<h1>Your Page</h1>
</div>
);
}- Optionally add it to navigation in the navbar/footer components
For protected pages, add auth checking:
import { checkAuth } from "@/lib/auth/page-auth";
import { AccessLevel } from "@/lib/types/auth.enums";
export default async function ProtectedPage() {
const user = await checkAuth({ access: AccessLevel.AUTHENTICATED });
// user is guaranteed to exist here
return <div>Hello {user.name}</div>;
}Email Templates
Customize the look and content of emails in the emails/ folder. The shared components (emails/components/EmailHeader.tsx and EmailFooter.tsx) control the header logo and footer links across all emails.
Preview changes with:
npm run email:devDark Mode
Dark mode is handled by next-themes and works automatically. The theme toggle component lets users switch between light, dark, and system themes.
To set a default theme, edit the ThemeProvider in src/components/theme-provider.tsx.
