| name | atomic-design-templates |
| description | Use when creating page layouts without real content. Templates define the skeletal structure of pages using organisms, molecules, and atoms. |
| allowed-tools | ["Bash","Read","Write","Edit","Glob","Grep"] |
Atomic Design: Templates
Master the creation of templates - page-level layouts that define content structure without actual content. Templates establish the skeletal structure that pages will use.
What Are Templates?
Templates are the page-level objects that place components into a layout and articulate the design's underlying content structure. They are:
- Composed of organisms: Arrange organisms into page layouts
- Content-agnostic: Use placeholder content, not real data
- Structural: Define where content types will appear
- Reusable: Same template can be used by multiple pages
- Responsive: Handle all viewport sizes
Common Template Types
Marketing Templates
- Landing page layouts
- Homepage layouts
- Product showcase layouts
- About/Company layouts
Application Templates
- Dashboard layouts
- Settings page layouts
- Profile page layouts
- List/Detail page layouts
Content Templates
- Blog post layouts
- Article layouts
- Documentation layouts
- Help center layouts
E-commerce Templates
- Product listing layouts
- Product detail layouts
- Checkout layouts
- Order confirmation layouts
MainLayout Template Example
Complete Implementation
import React from 'react';
import { Header, type HeaderProps } from '@/components/organisms/Header';
import { Footer, type FooterProps } from '@/components/organisms/Footer';
import styles from './MainLayout.module.css';
export interface MainLayoutProps {
headerProps: HeaderProps;
footerProps: FooterProps;
children: React.ReactNode;
showBreadcrumbs?: boolean;
breadcrumbs?: React.ReactNode;
maxWidth?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
background?: 'white' | 'gray' | ;
}
: .<> = {
(
);
};
. = ;
.layout {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.main {
flex: 1;
display: flex;
flex-direction: column;
}
.breadcrumbs {
padding: 16px 24px;
background-color: var(--color-neutral-50);
border-bottom: 1px solid var(--color-neutral-200);
}
.content {
flex: 1;
margin: 0 auto;
padding: 24px;
width: 100%;
}
.max-sm {
max-width: 640px;
}
.max-md {
max-width: 768px;
}
.max-lg {
max-width: 1024px;
}
.max-xl {
max-width: 1280px;
}
.max-full {
max-width: 100%;
}
.bg-white {
background-color: var(--color-white);
}
{
: (--color-neutral-);
}
{
: (--color-primary-);
}
(: ) {
{
: ;
}
}
DashboardLayout Template Example
import React, { useState } from 'react';
import { Header } from '@/components/organisms/Header';
import { Sidebar, type SidebarProps } from '@/components/organisms/Sidebar';
import styles from './DashboardLayout.module.css';
export interface DashboardLayoutProps {
headerProps: {
logo: React.ReactNode;
user?: { name: string; email: string; avatar?: string };
onLogout?: () => void;
};
sidebarProps: SidebarProps;
children: React.ReactNode;
pageTitle?: string;
pageDescription?: string;
pageActions?: .;
?: ;
}
: .<> = {
[isCollapsed, setIsCollapsed] = (sidebarCollapsed);
(
);
};
. = ;
.layout {
display: flex;
flex-direction: column;
min-height: 100vh;
}
.body {
display: flex;
flex: 1;
}
.main {
flex: 1;
display: flex;
flex-direction: column;
overflow-x: hidden;
background-color: var(--color-neutral-50);
}
.pageHeader {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 24px;
padding: 24px;
background-color: var(--color-white);
border-bottom: 1px solid var(--color-neutral-200);
}
.titleSection {
flex: 1;
}
.pageTitle {
margin: 0;
font-size: 24px;
font-weight: 600;
color: var(--color-neutral-900);
}
.pageDescription {
margin: 4px 0 ;
: ;
: (--color-neutral-);
}
{
: flex;
: ;
: ;
}
{
: ;
: ;
: auto;
}
(: ) {
{
: column;
: stretch;
}
{
: ;
}
{
: ;
}
}
AuthLayout Template Example
import React from 'react';
import styles from './AuthLayout.module.css';
export interface AuthLayoutProps {
logo: React.ReactNode;
title: string;
subtitle?: string;
children: React.ReactNode;
footer?: React.ReactNode;
backgroundImage?: string;
showSidePanel?: boolean;
sidePanelContent?: React.ReactNode;
}
export const AuthLayout: React.FC<AuthLayoutProps> = ({
logo,
title,
subtitle,
children,
footer,
backgroundImage,
showSidePanel = false,
sidePanelContent,
}) => {
return (
);
};
. = ;
.layout {
display: flex;
min-height: 100vh;
}
.sidePanel {
display: none;
width: 50%;
background-color: var(--color-primary-600);
background-size: cover;
background-position: center;
position: relative;
}
@media (min-width: 1024px) {
.sidePanel {
display: flex;
align-items: center;
justify-content: center;
}
}
.sidePanelContent {
padding: 48px;
color: var(--color-white);
text-align: center;
}
.main {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
background-color: var(--color-neutral-50);
}
.container {
width: 100%;
max-width: 400px;
}
.logo {
text-align: center;
margin-bottom: 32px;
}
.header {
: center;
: ;
}
{
: ;
: ;
: ;
: (--color-neutral-);
}
{
: ;
: ;
: (--color-neutral-);
}
{
: (--color-white);
: ;
: ;
: (, , , );
}
{
: ;
: center;
: ;
: (--color-neutral-);
}
{
: (--color-primary-);
: none;
}
{
: underline;
}
ProductListingLayout Template Example
import React from 'react';
import { MainLayout, type MainLayoutProps } from '../MainLayout';
import styles from './ProductListingLayout.module.css';
export interface ProductListingLayoutProps {
layoutProps: Omit<MainLayoutProps, 'children'>;
categoryTitle: string;
categoryDescription?: string;
productCount: number;
filters: React.ReactNode;
controls: React.ReactNode;
products: React.ReactNode;
pagination?: React.ReactNode;
mobileFiltersOpen?: ;
?: ;
}
: .<> = {
(
);
};
. = ;
BlogPostLayout Template Example
import React from 'react';
import { MainLayout, type MainLayoutProps } from '../MainLayout';
import { Avatar } from '@/components/atoms/Avatar';
import { Text } from '@/components/atoms/Typography';
import styles from './BlogPostLayout.module.css';
export interface Author {
name: string;
avatar?: string;
bio?: string;
}
export interface BlogPostLayoutProps {
layoutProps: Omit<MainLayoutProps, 'children'>;
title: string;
subtitle?: string;
featuredImage?: string;
author: Author;
: ;
?: ;
?: .;
: .;
?: .;
?: ;
?: .;
?: .;
?: .;
}
: .<> = {
formattedDate = (publishedAt).(, {
: ,
: ,
: ,
});
(
);
};
. = ;
TwoColumnLayout Template Example
import React from 'react';
import styles from './TwoColumnLayout.module.css';
export interface TwoColumnLayoutProps {
main: React.ReactNode;
sidebar: React.ReactNode;
sidebarPosition?: 'left' | 'right';
sidebarWidth?: 'narrow' | 'medium' | 'wide';
stickySidebar?: boolean;
reverseMobile?: boolean;
gap?: 'sm' | 'md' | 'lg';
}
export const TwoColumnLayout: React.FC<TwoColumnLayoutProps> = ({
main,
sidebar,
sidebarPosition = 'right',
sidebarWidth = 'medium',
stickySidebar = false,
reverseMobile = ,
gap = ,
}) => {
layoutClass = [
styles.,
styles[],
styles[],
styles[],
reverseMobile && styles.,
]
.()
.();
sidebarClass = [
styles.,
stickySidebar && styles.,
]
.()
.();
(
);
};
. = ;
Best Practices
1. Use Placeholder Content
const ProductDetailLayout = ({
productGallery, // Placeholder for gallery component
productInfo, // Placeholder for product details
productTabs, // Placeholder for tabs
relatedProducts, // Placeholder for recommendations
}) => (
<div>
<section>{productGallery}</section>
<section>{productInfo}</section>
<section>{productTabs}</section>
<section>{relatedProducts}</section>
</div>
);
const ProductDetailLayout = ({ product }) => (
<div>
<ProductGallery images={product.images} /> {/* Too specific */}
<h1>{product.name}</h1> {/* Real content */}
<p>{product.description}</p>
</div>
);
2. Define Clear Content Areas
interface PageTemplateProps {
header: React.ReactNode;
hero?: React.ReactNode;
main: React.ReactNode;
sidebar?: React.ReactNode;
footer: React.ReactNode;
}
interface PageTemplateProps {
children: React.ReactNode;
}
3. Handle Responsive Layouts
const DashboardLayout = ({ sidebar, main }) => (
<div className={styles.layout}>
<aside className={styles.sidebar}>{sidebar}</aside>
<main className={styles.main}>{main}</main>
</div>
);
4. Keep Templates Thin
const MainLayout = ({ header, main, footer }) => (
<div className={styles.layout}>
<div className={styles.header}>{header}</div>
<div className={styles.main}>{main}</div>
<div className={styles.footer}>{footer}</div>
</div>
);
const MainLayout = ({ userId }) => {
const user = useUser(userId);
const isAdmin = user?.role === 'admin';
return (
<div>
<Header user={user} showAdmin={isAdmin} />
{/* ... */}
</div>
);
};
Anti-Patterns to Avoid
1. Templates with Real Content
const HomepageLayout = () => (
<div>
<h1>Welcome to Our Store</h1> {/* Real content! */}
<p>Shop our latest collection...</p> {/* Real content! */}
</div>
);
const HomepageLayout = ({ heroTitle, heroDescription }) => (
<div>
<h1>{heroTitle}</h1>
<p>{heroDescription}</p>
</div>
);
2. Over-Nested Templates
const AppLayout = () => (
<BaseLayout>
<AuthLayout>
<DashboardLayout>
{/* Too much nesting */}
</DashboardLayout>
</AuthLayout>
</BaseLayout>
);
const AppPage = () => (
<DashboardLayout>
{/* Content */}
</DashboardLayout>
);
3. Templates with Too Many Props
interface LayoutProps {
showHeader: boolean;
showFooter: boolean;
showSidebar: boolean;
sidebarPosition: 'left' | 'right';
headerVariant: 'default' | 'minimal' | 'transparent';
footerVariant: 'default' | 'minimal';
maxWidth: 'sm' | 'md' | 'lg' | 'xl';
}
const FullPageLayout = ({ ... }) => { ... };
const MinimalLayout = ({ ... }) => { ... };
const SidebarLayout = ({ ... }) => { ... };
Template Composition Patterns
Nested Layouts
const BaseLayout = ({ children }) => (
<div className="base">
<SkipLink />
{children}
</div>
);
const MarketingLayout = ({ children }) => (
<BaseLayout>
<MarketingHeader />
<main>{children}</main>
<MarketingFooter />
</BaseLayout>
);
const AppLayout = ({ children }) => (
<BaseLayout>
<AppHeader />
<main>{children}</main>
</BaseLayout>
);
Slot-Based Layouts
interface SlotLayoutProps {
slots: {
header?: React.ReactNode;
sidebar?: React.ReactNode;
main: React.ReactNode;
footer?: React.ReactNode;
};
}
const SlotLayout: React.FC<SlotLayoutProps> = ({ slots }) => (
<div className={styles.layout}>
{slots.header && <header>{slots.header}</header>}
<div className={styles.body}>
{slots.sidebar && <aside>{slots.sidebar}</aside>}
<main>{slots.main}</main>
</div>
{slots.footer && <footer>{slots.footer}</footer>}
</div>
);
When to Use This Skill
- Creating page structure patterns
- Building reusable layout components
- Establishing consistent page architectures
- Setting up responsive frameworks
- Defining content slot patterns
Related Skills
atomic-design-fundamentals - Core methodology overview
atomic-design-organisms - Building complex organisms
atomic-design-integration - Framework-specific patterns