Footer Component
Site footer with logo, links, social media, and legal information
Footer Component
The <Footer> component provides the site footer with logo, link groups, social media links, copyright, and optional status indicator.
Interface
import type { FooterProps } from 'mdxui'
interface FooterLinkGroup {
title: string
links: Array<{
label: string
href: string
}>
}
interface FooterProps {
/** Logo element */
logo: ReactNode
/** Footer link groups */
links: FooterLinkGroup[]
/** Social media links */
social?: Array<{
platform: string
href: string
icon?: ReactNode
}>
/** Copyright text */
copyright?: string
}Usage
Basic Example
import { Footer } from '@mdxui/beacon'
<Footer
logo={<Logo />}
companyName="Acme Inc"
linkGroups={[
{
group: "Product",
items: [
{ title: "Features", href: "/features" },
{ title: "Pricing", href: "/pricing" },
{ title: "Security", href: "/security" },
]
},
{
group: "Company",
items: [
{ title: "About", href: "/about" },
{ title: "Blog", href: "/blog" },
{ title: "Careers", href: "/careers" },
]
},
]}
socialLinks={[
{ name: "Twitter", href: "https://twitter.com/acme", icon: <Twitter /> },
{ name: "GitHub", href: "https://github.com/acme", icon: <GitHub /> },
]}
/>With Description
<Footer
logo={<Logo />}
description="The fastest way to build modern web applications."
companyName="Acme Inc"
linkGroups={footerLinks}
/>With Status Indicator
<Footer
logo={<Logo />}
companyName="Acme Inc"
linkGroups={footerLinks}
statusText="All Systems Normal"
showStatus={true}
/>Props
logo (required)
Type: ReactNode
Logo element displayed in the footer.
<Footer logo={<Logo variant="light" />} />description (optional)
Type: string
Description text displayed below the logo.
<Footer
logo={<Logo />}
description="Building the future of web development."
/>companyName (required)
Type: string
Company name used in the copyright notice.
<Footer companyName="Acme Inc" />
// Renders: © 2024 Acme Inc, All rights reservedlinkGroups (optional)
Type: FooterLinkGroup[]
Array of link groups organized into columns.
interface FooterLinkGroup {
group: string // Column title
items: FooterLink[]
}
interface FooterLink {
title: string // Link text
href: string // Link URL
}
<Footer
linkGroups={[
{
group: "Product",
items: [
{ title: "Features", href: "/features" },
{ title: "Pricing", href: "/pricing" },
{ title: "Security", href: "/security" },
{ title: "Changelog", href: "/changelog" },
]
},
{
group: "Resources",
items: [
{ title: "Documentation", href: "/docs" },
{ title: "API Reference", href: "/docs/api" },
{ title: "Guides", href: "/guides" },
{ title: "Blog", href: "/blog" },
]
},
{
group: "Company",
items: [
{ title: "About", href: "/about" },
{ title: "Careers", href: "/careers" },
{ title: "Contact", href: "/contact" },
{ title: "Partners", href: "/partners" },
]
},
{
group: "Legal",
items: [
{ title: "Privacy", href: "/privacy" },
{ title: "Terms", href: "/terms" },
{ title: "Security", href: "/security" },
]
},
]}
/>socialLinks (optional)
Type: SocialLink[]
Array of social media links with icons.
interface SocialLink {
name: string // Platform name (for aria-label)
href: string // Social profile URL
icon: ReactNode // Icon component
}
import { Twitter, GitHub, LinkedIn } from 'lucide-react'
<Footer
socialLinks={[
{
name: "Twitter",
href: "https://twitter.com/acme",
icon: <Twitter className="size-5" />
},
{
name: "GitHub",
href: "https://github.com/acme",
icon: <GitHub className="size-5" />
},
{
name: "LinkedIn",
href: "https://linkedin.com/company/acme",
icon: <LinkedIn className="size-5" />
},
]}
/>statusText (optional)
Type: string
Default: "All Systems Normal"
Status text displayed in the bottom right (e.g., system status).
<Footer statusText="All Systems Operational" />showStatus (optional)
Type: boolean
Default: true
Whether to display the status indicator.
<Footer showStatus={true} />LinkComponent (optional)
Type: ComponentType<FooterLinkComponentProps>
Custom link component for routing (e.g., Next.js Link).
import Link from 'next/link'
<Footer LinkComponent={Link} />className (optional)
Type: string
Additional CSS classes for custom styling.
<Footer className="bg-slate-900 text-white" />Implementation Details
The reference implementation from @mdxui/beacon includes:
Structure
<footer className="bg-background border-t py-8 sm:py-16 lg:pt-32">
<div className="container max-w-5xl">
{/* Main Grid */}
<div className="grid gap-12 md:grid-cols-5">
{/* Logo + Description (2 columns) */}
<div className="md:col-span-2">
<LinkComponent href="/">
{logo}
</LinkComponent>
{description && (
<p className="text-muted-foreground">{description}</p>
)}
</div>
{/* Link Groups (3 columns) */}
<div className="col-span-3 grid gap-6 sm:grid-cols-3">
{linkGroups.map(group => (
<div key={group.group}>
<span className="font-medium">{group.group}</span>
<div className="flex flex-col gap-4">
{group.items.map(link => (
<LinkComponent href={link.href}>
{link.title}
</LinkComponent>
))}
</div>
</div>
))}
{/* Social Links */}
{socialLinks.length > 0 && (
<div>
<span className="font-medium">Community</span>
<div className="flex gap-3">
{socialLinks.map(social => (
<LinkComponent
href={social.href}
target="_blank"
rel="noopener noreferrer"
aria-label={social.name}
>
{social.icon}
</LinkComponent>
))}
</div>
</div>
)}
</div>
</div>
{/* Divider */}
<div className="h-px bg-foreground/10" />
{/* Bottom Row: Copyright + Status */}
<div className="flex justify-between">
<span className="text-muted-foreground text-sm">
© {new Date().getFullYear()} {companyName}, All rights reserved
</span>
{showStatus && (
<span className="text-sm text-emerald-500">{statusText}</span>
)}
</div>
</div>
</footer>Responsive Layout
- Mobile: Single column, stacked layout
- Tablet: 2-3 column grid for link groups
- Desktop: 5 column grid (logo takes 2, links take 3)
Spacing
- Top padding scales from
py-8(mobile) tolg:pt-32(desktop) - Consistent gap between columns (
gap-6togap-12)
Real-World Examples
Marketing Site Footer
const marketingFooter = {
linkGroups: [
{
group: "Product",
items: [
{ title: "Features", href: "/features" },
{ title: "Pricing", href: "/pricing" },
{ title: "Customers", href: "/customers" },
{ title: "Integrations", href: "/integrations" },
]
},
{
group: "Developers",
items: [
{ title: "Documentation", href: "/docs" },
{ title: "API Reference", href: "/docs/api" },
{ title: "SDKs", href: "/sdks" },
{ title: "Status", href: "/status" },
]
},
{
group: "Company",
items: [
{ title: "About", href: "/about" },
{ title: "Blog", href: "/blog" },
{ title: "Careers", href: "/careers" },
{ title: "Contact", href: "/contact" },
]
},
],
socialLinks: [
{ name: "Twitter", href: "https://twitter.com/acme", icon: <Twitter /> },
{ name: "GitHub", href: "https://github.com/acme", icon: <GitHub /> },
{ name: "Discord", href: "https://discord.gg/acme", icon: <MessageCircle /> },
]
}
<Footer
logo={<Logo />}
description="Build better products, faster."
companyName="Acme Inc"
{...marketingFooter}
statusText="All Systems Normal"
/>Documentation Footer
<Footer
logo={<Logo />}
companyName="Acme"
linkGroups={[
{
group: "Documentation",
items: [
{ title: "Getting Started", href: "/docs" },
{ title: "API Reference", href: "/docs/api" },
{ title: "Examples", href: "/examples" },
]
},
{
group: "Community",
items: [
{ title: "GitHub", href: "https://github.com/acme" },
{ title: "Discord", href: "https://discord.gg/acme" },
{ title: "Twitter", href: "https://twitter.com/acme" },
]
},
]}
showStatus={false}
/>Minimal Footer
<Footer
logo={<Logo />}
companyName="Acme Inc"
linkGroups={[
{
group: "Legal",
items: [
{ title: "Privacy", href: "/privacy" },
{ title: "Terms", href: "/terms" },
]
},
]}
showStatus={false}
/>Accessibility
The reference implementation includes:
- Semantic HTML - Uses
<footer>element - Link Attributes - External links have
target="_blank"andrel="noopener noreferrer" - ARIA Labels - Social links include
aria-labelwith platform name - Color Contrast - Muted text meets WCAG AA standards
- Focus Indicators - Visible focus states on all links
<LinkComponent
href={social.href}
target="_blank"
rel="noopener noreferrer"
aria-label={social.name}
>
{social.icon}
</LinkComponent>Composition with Site
The <Footer> component is typically rendered by <Site>:
<Site name="Acme">
{/* Site automatically renders Footer */}
<LandingPage>...</LandingPage>
</Site>How it works:
- The
<Site>component includes<Footer>automatically - Footer props are configured in the template implementation
- Logo is inherited from
<Site>component
TypeScript
Full type definitions:
import type { ReactNode, ComponentType } from 'react'
import type { z } from 'zod'
export const FooterLinkGroupSchema = z.object({
title: z.string(),
links: z.array(z.object({
label: z.string(),
href: z.string(),
})),
})
export const FooterPropsSchema = z.object({
logo: z.any(),
links: z.array(FooterLinkGroupSchema),
social: z.array(z.object({
platform: z.string(),
href: z.string(),
icon: z.any().optional(),
})).optional(),
copyright: z.string().optional(),
})
export type FooterLinkGroup = z.infer<typeof FooterLinkGroupSchema>
export type FooterProps = z.infer<typeof FooterPropsSchema>
export type Footer = Component<FooterProps>Reference Implementation Types:
// From @mdxui/beacon
export interface FooterLink {
title: string
href: string
}
export interface FooterLinkGroup {
group: string
items: FooterLink[]
}
export interface SocialLink {
name: string
href: string
icon: ReactNode
}
export interface FooterProps {
logo: ReactNode
description?: string
companyName: string
linkGroups?: FooterLinkGroup[]
socialLinks?: SocialLink[]
statusText?: string
showStatus?: boolean
LinkComponent?: ComponentType<FooterLinkComponentProps>
className?: string
}Related Components
- Site Component - Root wrapper (renders Footer)
- Header Component - Site navigation
- Logo - Logo component