Custom Landing Page
Compose home, features, pricing, FAQ, and legal pages from route files and light config.
MuseMVP landing pages are composed in the route file, in render order. Keep src/config/index.ts for brand, auth, billing, and contact delivery. There is no systemShowConfig, useSystemComponent, or landing-page PLACEHOLDER block.
Config Entry
Brand and runtime gates live in src/config/index.ts. Header/footer links live in the components. Legal pages are MDX in content/legal/.
Config Directory Structure
Home Page
src/app/(landing-page)/[locale]/(home)/page.tsx renders sections sequentially and keeps force-static:
export const dynamic = "force-static";
export default async function Home({ params }) {
const { locale } = await params;
setRequestLocale(locale);
return (
<>
<Hero />
<Features />
<CTASection />
<PricingSection />
<FaqSection />
<Newsletter />
</>
);
}| Section | Component | Notes |
|---|---|---|
| Hero | Hero | Product shot: /images/hero-light.png and /images/hero-dark.png |
| Features | Features | Lucide icons; copy in home.json |
| CTA | CTASection | |
| Pricing | PricingSection | Returns null on the homepage when config.payments.enableBilling is false |
| FAQ | FaqSection | Copy in faq.json |
| Newsletter | Newsletter | Copy in newsletter.json |
To hide a section, remove its JSX. To replace a section, change the import. To reorder, move the JSX.
Header and Footer
Edit the components. Do not add a switch matrix to config.ui.
| File | What to change |
|---|---|
src/modules/landing-page/header/SwitchHeader.tsx | Nav links |
src/modules/landing-page/footer/SwitchFooter.tsx | Footer columns, socials, powered-by |
src/modules/landing-page/site-links.ts | GitHub, Discord, X, demo, and powered-by URLs |
src/i18n/translations/{en,zh}/home.json | Header/footer labels |
Hide a public page by deleting its link in header/footer. Delete the route file only if the URL should not stay reachable. Pricing links still follow config.payments.enableBilling.
Pricing Page
The pricing page at src/app/(landing-page)/[locale]/pricing/page.tsx is controlled by config.payments.enableBilling. When false, the pricing route redirects to home. Homepage pricing hides itself inside PricingSection instead of using a route-level flag.
Pricing copy and plan display come from src/config/saas/pricing-desc-usage.ts and pricing-desc.ts.
pricing-desc.ts: plan titles, descriptions, and feature listspricing-desc-usage.ts: actual purchasable price items, stable appproductIdvalues, and billing behavior. Provider product IDs live in Admin → Runtime settings.
If you want to show a compare-at/original price such as $249 and charge $199, configure it in pricing-desc-usage.ts:
{
type: "one-time",
productId: billingProductCatalog.lifetime.productId,
originalAmount: 249,
amount: 199,
currency: "USD",
}Field semantics:
amount: the actual checkout amount sent to the billing gatewayoriginalAmount: optional UI-only compare-at price rendered as a strikethrough price in the pricing card
originalAmount is displayed only when it is greater than amount. If omitted, the pricing UI falls back to showing only the current price.
FAQ
FAQ data is defined in src/modules/landing-page/home/components/FaqSection.tsx via two hooks:
useFaqData(): FAQ list (question, answer) — sourced from i18n translationsuseFaqSectionData(): FAQ section title, description — also from i18n
To customize FAQ content in this template, edit faq.json in src/i18n/translations/en/ and src/i18n/translations/zh/. Derivative products should put replacement copy in mvp.json instead of overwriting those files.
Changelog
/changelog renders a three-column sticky timeline in src/modules/landing-page/changelog/changelog-page-content.tsx. Entry bodies come from content/changelog/ MDX. UI strings, including the expand-full-notes label, live in changelog.json.
Legal Pages
Legal pages are independent MDX files. Edit them directly:
| Page | Files |
|---|---|
| Privacy | content/legal/privacy.en.mdx, content/legal/privacy.zh.mdx |
| Terms | content/legal/terms.en.mdx, content/legal/terms.zh.mdx |
| Community | content/legal/behavior.en.mdx, content/legal/behavior.zh.mdx |
Keep frontmatter title. Do not add another # H1 in the body; the route already renders the title. Footer labels live in home.json.
Quick Customization Flow
Edit the JSX list in src/app/(landing-page)/[locale]/(home)/page.tsx to hide, replace, or reorder homepage sections.
Update SwitchHeader / SwitchFooter and home.json for navigation copy and links.
Customize FAQ via i18n faq.json, changelog via content/changelog/ + changelog.json, and legal content in content/legal/.