🌐 Web Pages

Pre-built landing page components for marketing websites and public-facing pages

🎯 Overview

Category Components Purpose
🎬 Hero HeroSection Full-width landing hero with CTAs
✨ Features FeaturesGrid Icon cards showcasing product features
πŸ’° Pricing PricingSection Single pricing card with feature checklist
❓ FAQ FAQSection Expandable FAQ using Details/Summary
🦢 Footer PageFooter Multi-column footer with social links
🧭 Nav LandingNavBar Sticky navbar with brand and CTAs
πŸ“„ Pages LandingPage, LandingPageV2 Complete landing page compositions

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Landing Page                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  LandingNavBar (sticky, blur)                           β”‚
β”‚  β”œβ”€ Brand + Navigation Links + CTA Actions              β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  HeroSection                                            β”‚
β”‚  β”œβ”€ Title + Subtitle + Primary/Secondary CTAs           β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  FeaturesGrid                                           β”‚
β”‚  β”œβ”€ 3-column responsive cards with icons                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  PricingSection                                         β”‚
β”‚  β”œβ”€ Centered pricing card with feature bullets          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  FAQSection                                             β”‚
β”‚  β”œβ”€ Expandable Details/Summary items                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  PageFooter                                             β”‚
β”‚  β”œβ”€ Multi-column links + Copyright + Social icons       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“š Quick Reference

# Complete landing page in one call
LandingPage(
    brand_name="MyBrand",
    hero_title="Welcome",
    hero_subtitle="Build faster",
    features=[{'icon': 'speed', 'title': 'Fast', 'description': '...'}],
    faqs=[{'question': 'Q?', 'answer': 'A'}]
)
Code
import socket
import time
import subprocess

def kill_process_on_port(port):
    """Kill any process using the specified port on Windows"""
    try:
        result = subprocess.run(
            f'netstat -ano | findstr :{port}',
            shell=True, capture_output=True, text=True
        )
        
        if result.stdout:
            lines = result.stdout.strip().split('\n')
            for line in lines:
                if 'LISTENING' in line:
                    pid = line.strip().split()[-1]
                    subprocess.run(f'taskkill /PID {pid} /F', shell=True, capture_output=True)
                    print(f"βœ“ Killed process {pid} on port {port}")
                    time.sleep(0.5)
                    return True
        return False
    except Exception as e:
        print(f"⚠ Could not kill process on port {port}: {e}")
        return False

def find_available_port(start_port=5000, max_attempts=10):
    """Find an available port starting from start_port"""
    for port in range(start_port, start_port + max_attempts):
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            try:
                s.bind(('', port))
                return port
            except OSError:
                continue
    raise RuntimeError(f"Could not find an available port in range {start_port}-{start_port+max_attempts}")

# Stop existing server if running
if 'server' in globals(): 
    try:
        server.stop()
        time.sleep(0.5)
    except:
        pass

# Try to kill any process on preferred port, then find available port
preferred_port = 7020
kill_process_on_port(preferred_port)
port = find_available_port(preferred_port)

app = FastHTML(hdrs=MatTheme.blue.headers(title="Page Snippets", mode="dark"))
rt = app.route

try:
    server = JupyUvi(app, port=port)
    preview = partial(HTMX, app=app, port=port)
    print(f"βœ“ Server running on port {port}")
except Exception as e:
    print(f"βœ— Failed to start server: {e}")
    raise
βœ“ Server running on port 7020

🎬 Hero Section

Component Purpose
HeroSection Full-width hero with title, subtitle, and CTA buttons

Features: BeerCSS-first styling, optional secondary CTA, custom CSS/JS hooks


source

HeroSection


def HeroSection(
    title:str, # Main hero title
    subtitle:str, # Hero subtitle/description
    primary_cta_text:str, # Primary CTA button text
    primary_cta_href:str, # Primary CTA button href
    secondary_cta_text:str=None, # Secondary CTA button text (optional)
    secondary_cta_href:str=None, # Secondary CTA button href (optional)
    background:str='primary-container', # BeerCSS background class (without bg- prefix)
    cls:str='', # Additional classes
    extra_css:str | None=None, # Optional custom CSS (minimal; opt-in)
    extra_js:str | None=None, # Optional custom JS (minimal; opt-in)
):

Hero section with title, subtitle, and CTA buttons.

BeerCSS-first styling. Takes up 75vh by default with gradient overlay. Designed for full-width layout - background extends edge-to-edge naturally. Content is centered using responsive class internally. Mobile-friendly: title scales down via clamp(), text stays centered.

Code
def hero_section():
    return HeroSection(
    title="Welcome to Material UI",
    subtitle="Build beautiful web apps with FastHTML",
    primary_cta_text="Get Started",
    primary_cta_href="/signup",
    secondary_cta_text="Learn More",
    secondary_cta_href="/docs"
) 

preview(hero_section())

✨ Features Grid

Component Purpose
FeaturesGrid Bento-style responsive grid of feature cards with icons

Features: Configurable card sizes (size: 'big'/'small'), BeerCSS 12-column grid, mobile-responsive

🎯 Feature Showcase

Component Purpose
FeatureShowcase Bento-box image-on-top cards for detailed feature highlights

Configuration Options

Section-level parameters:

Parameter Type Default Description
features list required List of feature dicts (see below)
title str None Section heading
subtitle str None Section subheading

Per-feature dict keys:

Key Required Description
title βœ“ Feature title
description βœ“ Feature description
image_src Custom image URL/path (auto-generates placeholder if omitted)
image_alt Alt text for image (defaults to title)
size 'big' (l6) or 'small' (l4) β€” auto-assigned if omitted (first 2 big, rest small)

Bento layout: - First 2 features β†’ big (half-width on desktop, l6) - Remaining features β†’ small (third-width on desktop, l4) - All stack full-width on mobile (s12), 2-col on tablet (m6) - Override per-feature with size key


source

FeatureShowcase


def FeatureShowcase(
    features:list, # List of dicts: {title, description, image_src?, image_alt?, size?}
    title:str=None, # Optional section title
    subtitle:str=None, # Optional section subtitle
    cls:str=''
):

Bento-box feature showcase with image-on-top cards.

Displays features as cards with a large image on top (~75%) and text description on the bottom (~25%). Uses a bento grid layout: first 2 features are β€œbig” (half-width on desktop), remaining are β€œsmall” (third-width on desktop). All stack full-width on mobile.

Each feature can override its size via the β€˜size’ key: - β€˜big’: spans l6 (half width on desktop) - β€˜small’: spans l4 (third width on desktop) - If omitted: first 2 default to β€˜big’, rest to β€˜small’

Auto-generates placeholder images from picsum.photos if no image_src provided.

Args: features: List of feature dicts with keys: - title: Feature title (required) - description: Feature description (required) - image_src: URL/path to image (optional - auto-generates placeholder) - image_alt: Alt text for image (optional, defaults to title) - size: β€˜big’ or β€˜small’ (optional - auto-assigned by position) title: Section heading subtitle: Section subheading cls: Additional CSS classes

Example: FeatureShowcase( title=β€œWhy Choose Us”, features=[ {β€˜title’: β€˜Fast’, β€˜description’: β€˜Lightning quick’}, {β€˜title’: β€˜Secure’, β€˜description’: β€˜Built-in protection’}, {β€˜title’: β€˜Scale’, β€˜description’: β€˜Grows with you’}, {β€˜title’: β€˜Simple’, β€˜description’: β€˜Easy to use’}, {β€˜title’: β€˜Open’, β€˜description’: β€˜Open source’}, ], )

Code
showcase_features = [
    {'title': 'Lightning Fast', 'description': 'Built for speed with optimized rendering and minimal overhead. Your pages load instantly.'},
    {'title': 'Secure by Default', 'description': 'Enterprise-grade security with automatic CSRF protection and input sanitization.'},
    {'title': 'Infinitely Scalable', 'description': 'From prototype to production, scale seamlessly without changing your code.'},
    {'title': 'Beautiful Design', 'description': 'Material Design 3 components that look polished out of the box.'},
    {'title': 'Developer First', 'description': 'Pure Python API β€” no JavaScript or build tools required.'},
]

def test_showcase():
    return FeatureShowcase(
        title="Built for Modern Teams",
        subtitle="Everything you need to ship faster",
        features=showcase_features,
    )

preview(test_showcase())

source

FeaturesGrid


def FeaturesGrid(
    features:list, # List of dicts: {icon, title, description, size?}
    title:str=None, # Optional section title
    subtitle:str=None, # Optional section subtitle
    cls:str='', # Additional classes
):

Bento-style feature grid using BeerCSS 12-column grid.

Creates visual hierarchy with configurable card sizes for a modern bento box layout. Grid auto-fills with BeerCSS responsive column classes.

Each feature dict can include a β€˜size’ key: - β€˜big’: spans half width (l6) - highlighted/featured items - β€˜small’ (default): spans quarter width (l3)

Responsive behavior (BeerCSS breakpoints): - Mobile (s): full width, stacked (s12) - Tablet (m): 2 columns (m6) - Desktop (l): 4-column bento (l3 small, l6 big)

Example: FeaturesGrid([ {β€œicon”: β€œstar”, β€œtitle”: β€œFeatured”, β€œdescription”: β€œβ€¦β€, β€œsize”: β€œbig”}, {β€œicon”: β€œbolt”, β€œtitle”: β€œFast”, β€œdescription”: β€œβ€¦β€}, {β€œicon”: β€œshield”, β€œtitle”: β€œSecure”, β€œdescription”: β€œβ€¦β€}, ])

Code
# Bento layout example: 2 big features + 4 small = nice visual hierarchy
sample_features = [
    {'icon': 'bolt', 'title': 'Lightning Fast', 'description': 'Optimized rendering with minimal overhead. Pages load instantly.', 'size': 'big'},
    {'icon': 'shield', 'title': 'Secure by Default', 'description': 'Enterprise-grade security with automatic CSRF protection.', 'size': 'big'},
    {'icon': 'trending_up', 'title': 'Scalable', 'description': 'Grows with your needs'},
    {'icon': 'palette', 'title': 'Beautiful', 'description': 'Material Design tokens'},
    {'icon': 'extension', 'title': 'Extensible', 'description': 'Compose with any component'},
    {'icon': 'code', 'title': 'Developer First', 'description': 'Pure Python, no JS required'},
]

@rt('/test-fg')
def test_fg():
    return FeaturesGrid(
        features=sample_features,
        title="Why Choose Us",
        subtitle="Everything you need to ship quickly",
    )

preview(test_fg())

πŸ’° Pricing Section

Component Purpose
PricingSection Multi-tier pricing with monthly/yearly toggle

Features: - 1-3 pricing tiers (Starter/Pro/Enterprise pattern) - Monthly/Yearly toggle with automatic savings calculation - Green β€œSave X%” chip with subtle pulse animation - Highlight flag for recommended tier - Responsive grid layout


source

PricingSection


def PricingSection(
    title:str, # Section title
    plans:list, # List of plan dicts: {name, monthly_price, yearly_price, features, cta_text, cta_href, highlight?}
    cls:str='', # Additional classes
):

Multi-tier pricing section with monthly/yearly toggle.

Supports 1-3 pricing tiers with automatic responsive layout. User provides prices; component handles toggle, savings display, and grid.

Args: title: Section heading (e.g., β€œSimple Pricing”) plans: List of plan dicts, each containing: - name: Plan name (e.g., β€œStarter”, β€œPro”, β€œEnterprise”) - monthly_price: Monthly price as float (e.g., 9.99) - yearly_price: Yearly price as float (e.g., 99.99) - features: List of feature strings - cta_text: Button text (e.g., β€œGet Started”) - cta_href: Button link - highlight: Optional bool to emphasize this tier (default False) cls: Additional CSS classes

Example: PricingSection( title=β€œChoose Your Plan”, plans=[ {β€œname”: β€œStarter”, β€œmonthly_price”: 9.99, β€œyearly_price”: 99.99, β€œfeatures”: [β€œ5 users”, β€œBasic support”], β€œcta_text”: β€œStart Free”, β€œcta_href”: β€œ/signup”}, {β€œname”: β€œPro”, β€œmonthly_price”: 29.99, β€œyearly_price”: 299.99, β€œfeatures”: [β€œUnlimited users”, β€œPriority support”], β€œcta_text”: β€œGet Pro”, β€œcta_href”: β€œ/signup”, β€œhighlight”: True}, ] )

Code
# Test with 3-tier pricing (Starter / Pro / Enterprise)
def test_pricing_3tier():
    return PricingSection(
        title="Choose Your Plan",
        plans=[
            {
                "name": "Starter",
                "monthly_price": 9.99,
                "yearly_price": 99.99,
                "features": [
                    "5 team members",
                    "Basic analytics",
                    "Email support",
                    "1GB storage",
                ],
                "cta_text": "Start Free",
                "cta_href": "/signup?plan=starter",
            },
            {
                "name": "Pro",
                "monthly_price": 29.99,
                "yearly_price": 299.99,
                "features": [
                    "Unlimited members",
                    "Advanced analytics",
                    "Priority support",
                    "10GB storage",
                    "API access",
                ],
                "cta_text": "Get Pro",
                "cta_href": "/signup?plan=pro",
                "highlight": True,
            },
            {
                "name": "Enterprise",
                "monthly_price": 99.99,
                "yearly_price": 999.99,
                "features": [
                    "Everything in Pro",
                    "Dedicated support",
                    "Custom SLA",
                    "Unlimited storage",
                    "SSO & SAML",
                ],
                "cta_text": "Contact Sales",
                "cta_href": "/contact",
            },
        ],
    )

preview(test_pricing_3tier())
Code
# Test with single pricing card
def test_pricing_single():
    return PricingSection(
        title="Simple Pricing",
        plans=[
            {
                "name": "Professional",
                "monthly_price": 7.99,
                "yearly_price": 79.99,
                "features": [
                    "Unlimited users",
                    "24/7 priority support",
                    "Custom branding",
                    "Advanced analytics",
                    "Full API access",
                ],
                "cta_text": "Get Started",
                "cta_href": "/signup",
            },
        ],
    )

preview(test_pricing_single())

❓ FAQ Section

Component Purpose
FAQSection Expandable FAQ using native Details/Summary

Features: BeerCSS-first accordion, proper spacing between items


source

FAQSection


def FAQSection(
    title:str, faqs:list, cls:str=''
):

FAQ section using FAQItem from components.

Wraps multiple FAQItem components with a title and consistent spacing. Uses FAQItem from fh_matui.components for the actual collapsible Q&A.

Args: title: Section heading faqs: List of dicts with β€˜question’ and β€˜answer’ keys cls: Additional CSS classes

Code
faqs = [
    {'question': 'What is FastHTML?', 'answer': 'FastHTML is a modern web framework'},
    {'question': 'How much does it cost?', 'answer': 'See our pricing page for details'}
]

def faq_section():
    return  FAQSection(
    title="Frequently Asked Questions",
    faqs=faqs
)

preview(faq_section())

πŸ“„ Landing Page

Component Purpose
LandingPage Complete landing page composition
LandingPageV2 Alternative landing page layout

Features: Combines Hero, Features, Pricing, FAQ, and Footer into one component


source

LandingPageSimple


def LandingPageSimple(
    brand_name:str, # Required
    hero_title:str, hero_subtitle:str, hero_primary_cta:dict, # {'text': 'Get Started', 'href': '/signup'}
    footer_copyright:str, # Required copyright text
    hero_secondary_cta:dict=None, # Optional secondary CTA
    benefits:list=None, # List of dicts: {title, description, icon?, image_src?}
    benefits_title:str=None, benefits_subtitle:str=None,
    features:list=None, # List of dicts: {icon, title, description}
    features_title:str=None, features_subtitle:str=None,
    pricing_plans:list=None, # List of plan dicts for PricingSection
    pricing_title:str='Pricing', faqs:list=None, # List of FAQ dicts
    faq_title:str='Frequently Asked Questions', footer_columns:list=None, # Optional Footer extras
    footer_social_links:list=None, nav_links:list=None, # Override default nav links
    nav_actions:list=None, # CTA buttons in navbar
    cls:str=''
):

Landing page component - supply your content, get a complete page.

This is a reusable template component. Pass your brand info, hero content, features, pricing, and FAQs - it assembles a complete marketing landing page.

Includes smooth scrolling and proper anchor offset to prevent sticky navbar from hiding section headings when navigating via anchor links.

Layout approach: Main uses β€œmax” for full-width backgrounds. Each section handles its own content centering with β€œresponsive” wrapper. This allows gradients/backgrounds to extend edge-to-edge naturally.

Section order: Hero β†’ Benefits β†’ Features β†’ Pricing β†’ FAQ β†’ Footer

Required: brand_name, hero_title, hero_subtitle, hero_primary_cta, footer_copyright Optional: Benefits, Features, Pricing, FAQ (pass None to skip any section)

Code
@rt('/test-lp')
def test_landing_page():
    return LandingPageSimple(
        brand_name="FastHTML",
        hero_title="Build faster with FastHTML",
        hero_subtitle="Compose production-ready pages with Material-inspired components wired for HTMX.",
        hero_primary_cta={'text': 'Get Started', 'href': '/signup'},
        hero_secondary_cta={'text': 'View Docs', 'href': '/docs'},
        footer_copyright="Β© 2026 FastHTML",
        # Benefits (bento showcase) - 2 big + 3 small cards with image on top
        benefits=[
            {'title': 'Lightning Fast', 'description': 'Built for speed with optimized rendering and minimal overhead.'},
            {'title': 'Secure by Default', 'description': 'Enterprise-grade security with automatic CSRF protection.'},
            {'title': 'Infinitely Scalable', 'description': 'From prototype to production, scale seamlessly.'},
            {'title': 'Beautiful Design', 'description': 'Material Design 3 components that look polished out of the box.'},
            {'title': 'Developer First', 'description': 'Pure Python API β€” no JavaScript or build tools required.'},
        ],
        benefits_title="Why FastHTML?",
        benefits_subtitle="Built for modern teams",
        # Features (bento grid) - first 2 are big, rest small
        features=[
            {"icon": "dashboard", "title": "Page primitives", "description": "Hero, feature, pricing sections ready to use.", "size": "big"},
            {"icon": "bolt", "title": "HTMX ready", "description": "Live previews in notebook with zero config.", "size": "big"},
            {"icon": "palette", "title": "Color tokens", "description": "Material container classes."},
            {"icon": "extension", "title": "Composable", "description": "Extend with extra classes."},
            {"icon": "security", "title": "Accessible", "description": "WCAG friendly defaults."},
            {"icon": "rocket_launch", "title": "Fast iteration", "description": "nbdev keeps code and docs together."},
        ],
        features_title="Everything you need",
        features_subtitle="Mix heroes, features, pricing, and FAQs.",
        # Pricing
        pricing_title="Simple Pricing",
        pricing_plans=[
            {"name": "Starter", "monthly_price": 9.99, "yearly_price": 99.99,
             "features": ["5 users", "Basic support"], "cta_text": "Start Free", "cta_href": "/signup"},
            {"name": "Pro", "monthly_price": 29.99, "yearly_price": 299.99,
             "features": ["Unlimited users", "Priority support", "API access"], 
             "cta_text": "Get Pro", "cta_href": "/signup", "highlight": True},
        ],
        # FAQ
        faqs=[
            {"question": "Can I mix components?", "answer": "Yes. Every helper returns plain FastHTML nodes."},
            {"question": "How do colors work?", "answer": "Apply Material container classes to any wrapper."},
            {"question": "Is HTMX required?", "answer": "No. Interactions degrade gracefully."},
        ],
        # Footer uses STANDARD_FOOTER_COLUMNS by default (omit footer_columns to use standard)
        footer_social_links=[{"icon": "code", "href": "https://github.com"}],
    )

preview(test_landing_page())

πŸ“ Content Pages

Component Purpose
MarkdownSection Renders markdown text as HTML (server-side, SEO-friendly)
ContentPage Generic page shell with navbar, content area, and footer

Use Cases: Privacy Policy, Terms of Service, Security, About, Cookie Policy, Disclaimers, Blog posts, etc.


source

MarkdownSection


def MarkdownSection(
    content:str, # Markdown text to render
    title:str=None, # Optional section title (rendered as H3 for appropriate size)
    cls:str='', # Additional classes
):

Renders markdown content server-side for SEO compatibility.

Uses python-markdown to convert markdown to HTML on the server.
Search engines see fully rendered HTML (no JavaScript required).
Content is centered using BeerCSS large-width + row center-align pattern.

Great for text-heavy pages like Privacy Policy, Terms, About, Blog posts, etc.

Args:
    content: Markdown text string (can include headers, lists, links, code blocks, tables)
    title: Optional page title (rendered as H3 for blog-appropriate sizing)
    cls: Additional CSS classes

Example:
    MarkdownSection(
        title="Privacy Policy",
        content='''

Introduction

We value your privacy…

Data Collection

  • We collect minimal data
  • We never sell your data ’’’ )

source

ContentPage


def ContentPage(
    brand_name:str, # Brand name for navbar
    footer_copyright:str, # Copyright text for footer
    sections:VAR_POSITIONAL, # Content sections (MarkdownSection, custom Divs, etc.)
    nav_links:list=None, # Override default nav links
    nav_actions:list=None, # CTA buttons in navbar
    footer_columns:list=None, # Footer link columns (uses STANDARD_FOOTER_COLUMNS by default)
    footer_social_links:list=None, # Footer social icons
    cls:str=''
):

Generic content page with navbar, flexible content area, and footer.

A shell template for text-heavy pages like Privacy Policy, Terms of Service, Security, About, Blog posts, etc. Developer passes any number of content sections.

Layout: Navbar (sticky) -> Content sections (centered with β€˜responsive’) -> Footer

Uses STANDARD_FOOTER_COLUMNS by default for consistent footer across all pages.

Args: brand_name: Brand name for navbar footer_copyright: Copyright text *sections: One or more content sections (MarkdownSection, custom Divs, etc.) nav_links: Navigation links [{β€˜text’: β€˜Home’, β€˜href’: β€˜/’}, …] nav_actions: Action buttons for navbar footer_columns: Footer link columns (defaults to STANDARD_FOOTER_COLUMNS) footer_social_links: Social media icons for footer cls: Additional CSS classes

Example: ContentPage( brand_name=β€œMyBrand”, footer_copyright=β€œ2026 MyBrand”, MarkdownSection(title=β€œPrivacy Policy”, content=β€œβ€¦markdown…”), nav_links=[{β€˜text’: β€˜Home’, β€˜href’: β€˜/’}], )

Code
# Example: Privacy Policy page
privacy_md = '''
#### πŸ“‹ Introduction

This Privacy Policy explains how we collect, use, and protect your personal information when you use our services.

#### πŸ“Š Information We Collect

We may collect the following types of information:

- **Account Information**: Name, email address, and password when you create an account
- **Usage Data**: How you interact with our services, including pages visited and features used
- **Device Information**: Browser type, operating system, and IP address

#### 🎯 How We Use Your Information

We use your information to:

1. Provide and improve our services
2. Communicate with you about updates and offers
3. Ensure security and prevent fraud

## πŸ—„οΈ Data Retention

We retain your data only as long as necessary to provide our services or as required by law.

#### βœ… Your Rights

You have the right to:

- Access your personal data
- Request correction of inaccurate data
- Request deletion of your data
- Opt out of marketing communications

#### πŸ“¬ Contact Us

If you have questions about this Privacy Policy, please contact us at privacy@example.com.

*Last updated: January 2026*
'''

@rt('/privacy')
def privacy_page():
    return ContentPage(
        "FastHTML",           # brand_name
        "Β© 2026 FastHTML",    # footer_copyright
        MarkdownSection(title="Privacy Policy", content=privacy_md),
        # Uses STANDARD_FOOTER_COLUMNS by default
    )

preview(privacy_page())
Code
# Example: Security page
security_md = '''
#### πŸ›‘οΈ Our Commitment to Security

We take the security of your data seriously. Here is how we protect your information:

#### πŸ” Encryption

- All data is encrypted in transit using TLS 1.3
- Sensitive data is encrypted at rest using AES-256
- Passwords are hashed using bcrypt with salt

#### πŸ—οΈ Infrastructure

- Hosted on SOC 2 Type II certified infrastructure
- Regular security audits and penetration testing
- 24/7 monitoring and incident response

#### πŸ”‘ Access Control

- Role-based access control (RBAC) for all systems
- Multi-factor authentication required for all employees
- Principle of least privilege enforced

#### πŸ“œ Compliance

We comply with:

- GDPR (General Data Protection Regulation)
- CCPA (California Consumer Privacy Act)
- SOC 2 Type II

#### 🚨 Reporting Security Issues

If you discover a security vulnerability, please report it to security@example.com. We appreciate responsible disclosure.
'''

@rt('/security')
def security_page():
    return ContentPage(
        "FastHTML",           # brand_name
        "Β© 2026 FastHTML",    # footer_copyright
        MarkdownSection(title="Security", content=security_md),
        # Uses STANDARD_FOOTER_COLUMNS by default
    )

preview(security_page())
Code
# Example: About Us page
about_md = '''
## πŸ‘‹ Who We Are

FastHTML is built by a passionate team of developers who believe building web apps should be **fast, fun, and frustration-free**.

#### 🎯 Our Mission

To empower developers to ship beautiful, production-ready web applications in record time β€” without sacrificing quality or maintainability.

#### πŸ’‘ Our Story

We started FastHTML because we were tired of:

- Wrestling with complex frontend build systems
- Writing the same boilerplate code over and over
- Choosing between speed and quality

So we built a better way. FastHTML combines the best of Python, HTMX, and Material Design into a cohesive framework that just works.

#### 🌟 Our Values

- **Simplicity First**: If it's complicated, we're doing it wrong
- **Developer Experience**: Your time is precious β€” we respect it
- **Open Source**: Built in the open, for everyone

#### 🀝 Join Us

We're always looking for contributors and collaborators. Check out our GitHub or reach out at hello@example.com.

*Building the future of web development, one component at a time.*
'''

@rt('/about')
def about_page():
    return ContentPage(
        "FastHTML",           # brand_name
        "Β© 2026 FastHTML",    # footer_copyright
        MarkdownSection(title="About Us", content=about_md),
        # Uses STANDARD_FOOTER_COLUMNS by default
    )

preview(about_page())
Code
# Example: Terms of Service page
terms_md = '''
#### πŸ“œ Terms of Service

*Effective Date: January 2026*

Please read these Terms of Service carefully before using our services.

#### βœ… Acceptance of Terms

By accessing or using FastHTML, you agree to be bound by these Terms. If you disagree with any part, you may not access the service.

#### πŸ” Account Responsibilities

When you create an account, you must:

- Provide accurate and complete information
- Maintain the security of your password
- Notify us immediately of any unauthorized access
- Accept responsibility for all activities under your account

#### πŸ’³ Payment Terms

For paid plans:

- Billing occurs monthly or annually based on your selection
- Refunds are available within 30 days of initial purchase
- We reserve the right to change pricing with 30 days notice

#### 🚫 Prohibited Uses

You may not use our service to:

1. Violate any laws or regulations
2. Infringe on intellectual property rights
3. Distribute malware or harmful code
4. Attempt to gain unauthorized access to our systems

#### βš–οΈ Limitation of Liability

FastHTML is provided "as is" without warranties of any kind. We are not liable for any indirect, incidental, or consequential damages.

#### πŸ“ Changes to Terms

We may modify these terms at any time. Continued use of the service constitutes acceptance of modified terms.

#### πŸ“§ Contact

Questions about these Terms? Contact us at legal@example.com.
'''

@rt('/terms')
def terms_page():
    return ContentPage(
        "FastHTML",           # brand_name
        "Β© 2026 FastHTML",    # footer_copyright
        MarkdownSection(title="Terms of Service", content=terms_md),
        # Uses STANDARD_FOOTER_COLUMNS by default
    )

preview(terms_page())