Page Component
Generic content page layout with title and description
Page Component
The <Page> component provides a simple, flexible layout for generic content pages like About, Contact, Privacy Policy, or any standalone content.
Interface
import type { PageProps } from 'mdxui'
interface PageProps {
/** Page title */
title?: string
/** Page description */
description?: string
/** Page content */
children: ReactNode
}Usage
Basic Example
import { Page } from '@mdxui/beacon'
<Page title="About Us" description="Learn more about our company">
<section className="prose lg:prose-xl">
<p>We are a company that builds amazing products...</p>
<h2>Our Mission</h2>
<p>To make the world a better place...</p>
</section>
</Page>MDX Usage
Perfect for MDX content pages:
import { Page } from '@mdxui/beacon'
<Page title="Privacy Policy" description="How we handle your data">
# Privacy Policy
Last updated: January 2025
## Information We Collect
We collect the following types of information...
## How We Use Your Information
Your information is used to...
</Page>Simple Content Page
<Page title="Contact Us" description="Get in touch with our team">
<div className="container max-w-2xl py-12">
<form className="space-y-6">
<Input name="name" label="Name" />
<Input name="email" label="Email" type="email" />
<Textarea name="message" label="Message" />
<Button type="submit">Send Message</Button>
</form>
</div>
</Page>Without Header
For pages that manage their own layout:
<Page>
<section className="py-24">
<div className="container">
<h1 className="text-4xl font-bold">Custom Layout</h1>
<p>Your content here...</p>
</div>
</section>
</Page>Props
title (optional)
Type: string
Page title displayed at the top of the page. If provided, renders as an h1 heading.
<Page title="About Our Company">
{/* Page content */}
</Page>Rendered output:
<h1 className="text-4xl font-bold tracking-tight">
About Our Company
</h1>description (optional)
Type: string
Page description displayed below the title. Provides context for the page content.
<Page
title="Privacy Policy"
description="How we collect, use, and protect your personal information"
>
{/* Page content */}
</Page>Rendered output:
<p className="text-xl text-muted-foreground">
How we collect, use, and protect your personal information
</p>children (required)
Type: ReactNode
Page content. Can be any valid React elements or MDX content.
<Page title="About">
<section>
<p>Company history...</p>
</section>
<section>
<p>Team members...</p>
</section>
</Page>Implementation Details
The reference implementation from @mdxui/beacon includes:
Features
- Flexible Layout - Minimal wrapper allows custom content structure
- Semantic HTML - Uses
<main>and<article>elements - Typography Support - Works with prose classes for MDX content
- Container Management - Optional container for consistent max-width
- Responsive Spacing - Adaptive padding for mobile and desktop
Structure
<main className="flex-1">
<article className="container py-8 md:py-12 lg:py-16">
{title && (
<header className="mb-8 space-y-4">
<h1 className="text-4xl font-bold tracking-tight md:text-5xl">
{title}
</h1>
{description && (
<p className="text-xl text-muted-foreground">
{description}
</p>
)}
</header>
)}
<div className="max-w-none">
{children}
</div>
</article>
</main>Spacing Scale
Consistent vertical rhythm:
// Outer padding (main)
className="py-8 md:py-12 lg:py-16"
// Header margin (if title present)
className="mb-8"
// Mobile: 2rem (32px)
// Tablet: 3rem (48px)
// Desktop: 4rem (64px)Common Use Cases
About Page
<Page title="About Us" description="Our story and mission">
<div className="prose lg:prose-xl">
<h2>Our Story</h2>
<p>
Founded in 2020, we set out to solve a common problem...
</p>
<h2>Our Team</h2>
<div className="grid grid-cols-3 gap-6 not-prose">
{teamMembers.map(member => (
<TeamMemberCard key={member.id} {...member} />
))}
</div>
<h2>Our Values</h2>
<ul>
<li>Customer First</li>
<li>Innovation</li>
<li>Transparency</li>
</ul>
</div>
</Page>Contact Page
<Page title="Contact Us" description="We'd love to hear from you">
<div className="grid md:grid-cols-2 gap-12">
<div>
<h2 className="text-2xl font-bold mb-4">Send us a message</h2>
<ContactForm />
</div>
<div>
<h2 className="text-2xl font-bold mb-4">Other ways to reach us</h2>
<div className="space-y-4">
<ContactMethod
icon={<Mail />}
label="Email"
value="hello@example.com"
/>
<ContactMethod
icon={<Phone />}
label="Phone"
value="+1 (555) 123-4567"
/>
<ContactMethod
icon={<MapPin />}
label="Address"
value="123 Main St, San Francisco, CA"
/>
</div>
</div>
</div>
</Page>Privacy Policy
<Page title="Privacy Policy" description="Last updated: January 2025">
<div className="prose lg:prose-lg max-w-4xl mx-auto">
<h2>1. Information We Collect</h2>
<p>
We collect information you provide directly to us when you:
</p>
<ul>
<li>Create an account</li>
<li>Make a purchase</li>
<li>Contact customer support</li>
</ul>
<h2>2. How We Use Your Information</h2>
<p>
We use the information we collect to:
</p>
<ul>
<li>Provide, maintain, and improve our services</li>
<li>Process transactions and send related information</li>
<li>Send you technical notices and support messages</li>
</ul>
<h2>3. Information Sharing</h2>
<p>
We do not share your personal information except in the following cases...
</p>
</div>
</Page>Terms of Service
<Page title="Terms of Service" description="Please read these terms carefully">
<div className="prose max-w-4xl mx-auto">
<section>
<h2>1. Acceptance of Terms</h2>
<p>
By accessing and using this service, you accept and agree to be bound
by the terms and provision of this agreement...
</p>
</section>
<section>
<h2>2. Use License</h2>
<p>
Permission is granted to temporarily download one copy of the materials...
</p>
</section>
<section>
<h2>3. Disclaimer</h2>
<p>
The materials on this website are provided on an 'as is' basis...
</p>
</section>
</div>
</Page>Changelog Page
<Page title="Changelog" description="Recent updates and improvements">
<div className="max-w-3xl mx-auto space-y-12">
<ChangelogEntry
version="2.0.0"
date="January 15, 2025"
changes={[
{ type: "feature", text: "New dashboard redesign" },
{ type: "feature", text: "Dark mode support" },
{ type: "fix", text: "Fixed login redirect issue" },
]}
/>
<ChangelogEntry
version="1.9.0"
date="December 20, 2024"
changes={[
{ type: "feature", text: "Export to CSV" },
{ type: "improvement", text: "Faster page loads" },
]}
/>
</div>
</Page>FAQ Page
<Page title="Frequently Asked Questions" description="Find answers to common questions">
<div className="max-w-3xl mx-auto">
<Accordion type="single" collapsible>
{faqItems.map((item, index) => (
<AccordionItem key={index} value={`item-${index}`}>
<AccordionTrigger>{item.question}</AccordionTrigger>
<AccordionContent>{item.answer}</AccordionContent>
</AccordionItem>
))}
</Accordion>
</div>
</Page>Typography with Prose
The Page component works well with Tailwind Typography (@tailwindcss/typography):
<Page title="Blog Post Title">
<div className="prose lg:prose-xl dark:prose-invert mx-auto">
{/* MDX content with automatic styling */}
<p>Paragraph text is automatically styled...</p>
<h2>Subheadings are styled</h2>
<ul>
<li>Lists are styled</li>
<li>With proper spacing</li>
</ul>
<blockquote>
Blockquotes get proper styling too
</blockquote>
</div>
</Page>Prose modifiers:
prose-sm- Smaller textprose-lg- Larger textprose-xl- Extra large textdark:prose-invert- Dark mode supportnot-prose- Opt-out specific elements
Composition with Site
The <Page> component works with <Site> for full page layout:
<Site name="Acme">
<Page title="About" description="Learn about our company">
<section className="prose">
{/* Content */}
</section>
</Page>
</Site>Full page structure:
<Site>
<Header /> {/* Provided by Site */}
<Page> {/* Main content */}
{children}
</Page>
<Footer /> {/* Provided by Site */}
</Site>Accessibility
The reference implementation includes:
- Semantic HTML - Uses
<main>and<article>elements - Heading Hierarchy - Title is h1, content starts at h2
- Landmark Regions - Proper ARIA landmarks for navigation
- Skip Links - Support for "skip to content"
- Focus Management - Keyboard navigation support
<main id="main-content" role="main">
<article>
<header>
<h1>{title}</h1>
<p>{description}</p>
</header>
<div>{children}</div>
</article>
</main>Comparison: Page vs LandingPage
Use <Page> for:
- About, Contact, Privacy pages
- Legal documents (Terms, Privacy)
- Simple content pages
- MDX blog posts or articles
- Documentation pages
Use <LandingPage> for:
- Marketing homepages
- Product launches
- Conversion-focused pages
- Multi-section landing pages
- Pages with Hero, Features, Pricing sections
TypeScript
Full type definitions:
import type { ReactNode } from 'react'
import type { z } from 'zod'
import type { Component } from 'mdxui'
export const PagePropsSchema = z.object({
title: z.string().optional(),
description: z.string().optional(),
children: z.any(),
})
export type PageProps = z.infer<typeof PagePropsSchema>
export type Page = Component<PageProps>Related Components
- Site Component - Root wrapper with Header/Footer
- LandingPage Component - Landing page layout
- DocsPage Component - Documentation page layout
- BlogPost Component - Blog article layout