Customization
Landing Page
Customize the marketing landing page.
Overview
The landing page is in src/app/(marketing)/page.tsx.
Default sections:
- Hero
- Features
- Pricing
- FAQ
- CTA
Hero Section
export function HeroSection() {
return (
<section className="py-24 text-center">
<h1 className="text-5xl font-bold">
Your Product Headline
</h1>
<p className="mt-4 text-xl text-muted-foreground">
A brief description of what you offer.
</p>
<div className="mt-8 flex justify-center gap-4">
<Button size="lg" asChild>
<Link href="/signup">Get Started</Link>
</Button>
<Button size="lg" variant="outline" asChild>
<Link href="/docs">Documentation</Link>
</Button>
</div>
</section>
);
}Features Section
const features = [
{
title: 'Feature One',
description: 'Description of feature one.',
icon: <Zap className="h-6 w-6" />,
},
{
title: 'Feature Two',
description: 'Description of feature two.',
icon: <Shield className="h-6 w-6" />,
},
// ...
];
export function FeaturesSection() {
return (
<section className="py-16">
<h2 className="text-3xl font-bold text-center">Features</h2>
<div className="mt-12 grid md:grid-cols-3 gap-8">
{features.map((feature) => (
<FeatureCard key={feature.title} {...feature} />
))}
</div>
</section>
);
}Pricing Section
The pricing section pulls from Stripe products:
export default async function PricingPage() {
const products = await stripe.products.list({
active: true,
expand: ['data.default_price'],
});
return <PricingCards products={products.data} />;
}Customizing Pricing Cards
Edit src/components/pricing/pricing-card.tsx:
function PricingCard({ product, price, popular }) {
return (
<Card className={popular ? 'border-primary' : ''}>
<CardHeader>
<CardTitle>{product.name}</CardTitle>
<div className="text-3xl font-bold">
${price.unit_amount / 100}
</div>
</CardHeader>
<CardContent>
<ul className="space-y-2">
{product.features.map((feature) => (
<li key={feature} className="flex items-center gap-2">
<Check className="h-4 w-4 text-green-500" />
{feature}
</li>
))}
</ul>
<Button className="w-full mt-6">Get Started</Button>
</CardContent>
</Card>
);
}FAQ Section
const faqs = [
{
question: 'What payment methods do you accept?',
answer: 'We accept all major credit cards via Stripe.',
},
{
question: 'Can I cancel my subscription?',
answer: 'Yes, you can cancel anytime from your dashboard.',
},
];
export function FAQSection() {
return (
<section className="py-16">
<h2 className="text-3xl font-bold text-center">FAQ</h2>
<Accordion type="single" collapsible className="mt-8 max-w-2xl mx-auto">
{faqs.map((faq, i) => (
<AccordionItem key={i} value={`item-${i}`}>
<AccordionTrigger>{faq.question}</AccordionTrigger>
<AccordionContent>{faq.answer}</AccordionContent>
</AccordionItem>
))}
</Accordion>
</section>
);
}CTA Section
export function CTASection() {
return (
<section className="py-24 bg-primary text-primary-foreground text-center">
<h2 className="text-3xl font-bold">Ready to get started?</h2>
<p className="mt-4">Start your free trial today.</p>
<Button size="lg" variant="secondary" className="mt-8" asChild>
<Link href="/signup">Sign Up Free</Link>
</Button>
</section>
);
}Layout
Combine sections in the landing page:
export default function LandingPage() {
return (
<main>
<HeroSection />
<FeaturesSection />
<PricingSection />
<FAQSection />
<CTASection />
</main>
);
}Related
- Components - Component library
- Theming - Visual styling
Was this page helpful?