MuseMVP Docs
Configuration

Landing Page Configuration

Compose home, features, pricing, FAQ, and legal pages from route files and light config.

Arrange the homepage for your own product: keep the sections you need, replace the copy, and make the navigation lead to useful pages.

Before You Start

Finish Brand Settings. File paths are relative to your selected application's root. Keep dev running to see changes. Public product copy goes in both locales' mvp.json.

A First Edit: Remove the Newsletter Section

Open src/app/(landing-page)/[locale]/(home)/page.tsx. Remove <Newsletter /> and its now-unused import if you do not plan to collect subscriptions yet. Refresh the homepage and confirm the rest of the sections remain in order.

The same approach works for reordering sections: move their JSX. To use a new section, change the import and render that component. Keep the page's existing locale setup and static-rendering configuration. Use the reference below for the other sections and links.

Config Directory Structure

pricing-desc.ts
pricing-desc-usage.ts

Product config is packages/config/src/index.ts; locale metadata is packages/config/src/i18n.ts. The app config directory only owns pricing display/usage files. Derivative public copy belongs only in packages/i18n/src/translations/{en,zh}/mvp.json; default.json is the template layer.

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 />
    </>
  );
}
SectionComponentNotes
HeroHeroProduct shot: /images/hero-light.png and /images/hero-dark.png
FeaturesFeaturesLucide icons; template copy in default.json; derivative overlays in mvp.json
CTACTASection
PricingPricingSectionReturns null on the homepage when config.payments.enableBilling is false
FAQFaqSectionTemplate copy in default.json; derivative overlays in mvp.json
NewsletterNewsletterTemplate copy in default.json; derivative overlays in mvp.json

To hide a section, remove its JSX. To replace a section, change the import. To reorder, move the JSX.


Edit the link arrays in the components below. Update labels in both locales’ mvp.json so your new links read correctly.

FileWhat to change
src/modules/landing-page/header/SwitchHeader.tsxNav links
src/modules/landing-page/footer/SwitchFooter.tsxFooter columns, socials, powered-by
src/modules/landing-page/site-links.tsGitHub, Discord, X, demo, and powered-by URLs
packages/i18n/src/translations/{en,zh}/mvp.jsonDerivative 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 lists
  • pricing-desc-usage.ts: actual purchasable price items, stable app productId values, and billing behavior. Provider product IDs are <GATEWAY>_PRODUCT_ID_<PLAN> environment variables.

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 gateway
  • originalAmount: 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 translations
  • useFaqSectionData(): FAQ section title, description — also from i18n

To customize FAQ content in this template, edit default.json in packages/i18n/src/translations/en/ and packages/i18n/src/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 default.json; derivative replacements belong in mvp.json.


Legal pages are independent MDX files. Edit them directly:

PageFiles
Privacycontent/legal/privacy.en.mdx, content/legal/privacy.zh.mdx
Termscontent/legal/terms.en.mdx, content/legal/terms.zh.mdx
Communitycontent/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 default.json; derivative replacements belong in mvp.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 links in SwitchHeader / SwitchFooter; put derivative navigation copy in both locales’ mvp.json.

Customize derivative FAQ and changelog UI copy via mvp.json, changelog entries via content/changelog/, and legal content via content/legal/.


Check Your Result

Open both language homepages at desktop and phone widths. Check section order, CTA destinations, header/footer links, FAQ, and pricing visibility. Follow each changed link and check its destination exists. For two-app products, run pnpm apps:parity and synchronize eligible page changes before deploying both.

Common Problems

ProblemFix
A removed section leaves an import errorRemove its unused import as well as JSX
Link labels still use template wordingOverlay the consumed home.* keys in both mvp.json files
Hidden page is still reachableNavigation removal leaves the route available; remove the route only if it must be unavailable
Pricing disappearsCheck config.payments.enableBilling and your pricing configuration

On this page