Ghost CMS Homepage Editing Guide
Overview
This technical guide explains how to customize your Ghost CMS homepage using the built-in editor and HTML/CSS code blocks. Ghost allows extensive homepage customization through posts, pages, and custom code injection.
Method 1: Creating a Static Homepage with a Page
Step 1: Create a New Page
- Go to Ghost Admin → Pages → New Page
- Set the page title (this won't be displayed if you use custom HTML)
- Set the page URL slug to
home
orhomepage
Step 2: Add Custom HTML Content
Copy and paste this code into a HTML card in the Ghost editor:
<!-- Hero Section -->
<section class="hero-section" style="
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 100px 0;
text-align: center;
margin: -8vmin -4vmin 4vmin -4vmin;
">
<div class="container" style="max-width: 1200px; margin: 0 auto; padding: 0 20px;">
<h1 style="font-size: 3.5rem; margin-bottom: 1rem; font-weight: 700;">
Welcome to Our Blog
</h1>
<p style="font-size: 1.3rem; margin-bottom: 2rem; opacity: 0.9;">
Discover amazing stories, insights, and ideas that inspire
</p>
<a href="/about" style="
display: inline-block;
background: rgba(255,255,255,0.2);
color: white;
padding: 15px 30px;
text-decoration: none;
border-radius: 50px;
border: 2px solid rgba(255,255,255,0.3);
transition: all 0.3s ease;
font-weight: 600;
" onmouseover="this.style.background='rgba(255,255,255,0.3)'"
onmouseout="this.style.background='rgba(255,255,255,0.2)'">
Learn More
</a>
</div>
</section>
<!-- Featured Posts Section -->
<section class="featured-posts" style="padding: 60px 0;">
<div class="container" style="max-width: 1200px; margin: 0 auto; padding: 0 20px;">
<h2 style="text-align: center; margin-bottom: 3rem; font-size: 2.5rem; color: #2d3748;">
Featured Articles
</h2>
<div class="posts-grid" style="
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
margin-bottom: 3rem;
">
<!-- Post Card Template - Duplicate this for each featured post -->
<article class="post-card" style="
background: white;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
overflow: hidden;
transition: transform 0.3s ease;
" onmouseover="this.style.transform='translateY(-5px)'"
onmouseout="this.style.transform='translateY(0)'">
<img src="https://images.unsplash.com/photo-1486312338219-ce68d2c6f44d?w=400"
alt="Featured Post"
style="width: 100%; height: 200px; object-fit: cover;">
<div style="padding: 1.5rem;">
<h3 style="margin-bottom: 0.5rem; font-size: 1.3rem;">
<a href="#" style="color: #2d3748; text-decoration: none;">
Your Featured Post Title
</a>
</h3>
<p style="color: #718096; margin-bottom: 1rem; line-height: 1.6;">
Brief excerpt of your post content goes here...
</p>
<div style="display: flex; justify-content: space-between; align-items: center; font-size: 0.9rem; color: #a0aec0;">
<span>Jan 15, 2025</span>
<span>5 min read</span>
</div>
</div>
</article>
</div>
<div style="text-align: center;">
<a href="/blog" style="
display: inline-block;
background: #667eea;
color: white;
padding: 12px 30px;
text-decoration: none;
border-radius: 25px;
font-weight: 600;
transition: background 0.3s ease;
" onmouseover="this.style.background='#5a67d8'"
onmouseout="this.style.background='#667eea'">
View All Posts
</a>
</div>
</div>
</section>
<!-- Newsletter Section -->
<section class="newsletter-section" style="
background: #f7fafc;
padding: 60px 0;
margin: 4vmin -4vmin -8vmin -4vmin;
">
<div class="container" style="max-width: 600px; margin: 0 auto; padding: 0 20px; text-align: center;">
<h2 style="margin-bottom: 1rem; font-size: 2rem; color: #2d3748;">
Stay Updated
</h2>
<p style="color: #718096; margin-bottom: 2rem; font-size: 1.1rem;">
Get the latest posts delivered right to your inbox
</p>
<form style="display: flex; gap: 10px; max-width: 400px; margin: 0 auto;">
<input type="email" placeholder="Enter your email" style="
flex: 1;
padding: 12px;
border: 2px solid #e2e8f0;
border-radius: 25px;
outline: none;
font-size: 1rem;
">
<button type="submit" style="
background: #667eea;
color: white;
border: none;
padding: 12px 24px;
border-radius: 25px;
cursor: pointer;
font-weight: 600;
transition: background 0.3s ease;
" onmouseover="this.style.background='#5a67d8'"
onmouseout="this.style.background='#667eea'">
Subscribe
</button>
</form>
</div>
</section>
Step 3: Set as Homepage
- Go to Settings → General
- Expand Publication Homepage
- Select "A static page" and choose your created page
Method 2: Custom Post Layout for Homepage
Create a new post and use this template:
<!-- Modern Blog Homepage Layout -->
<div class="custom-homepage">
<style>
.custom-homepage {
max-width: 100%;
margin: 0;
}
.hero-gradient {
background: linear-gradient(45deg, #1a202c, #2d3748, #4a5568);
color: white;
padding: 80px 20px;
text-align: center;
margin: -8vmin -4vmin 60px -4vmin;
position: relative;
overflow: hidden;
}
.hero-gradient::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse"><path d="M 10 0 L 0 0 0 10" fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="0.5"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>');
opacity: 0.3;
}
.hero-content {
position: relative;
z-index: 1;
}
.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 30px;
margin: 40px 0;
padding: 0 20px;
}
.feature-card {
background: white;
padding: 30px;
border-radius: 15px;
box-shadow: 0 10px 25px rgba(0,0,0,0.1);
text-align: center;
transition: all 0.3s ease;
border: 1px solid #e2e8f0;
}
.feature-card:hover {
transform: translateY(-10px);
box-shadow: 0 20px 40px rgba(0,0,0,0.15);
}
.cta-section {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
padding: 60px 20px;
text-align: center;
margin: 60px -4vmin -8vmin -4vmin;
border-radius: 0;
}
@media (max-width: 768px) {
.hero-gradient h1 { font-size: 2.5rem; }
.feature-grid { grid-template-columns: 1fr; }
}
</style>
<div class="hero-gradient">
<div class="hero-content">
<h1 style="font-size: 3.5rem; margin-bottom: 20px; font-weight: 800;">
Transform Your Ideas
</h1>
<p style="font-size: 1.4rem; margin-bottom: 30px; opacity: 0.9; max-width: 600px; margin-left: auto; margin-right: auto;">
Join thousands of creators sharing their stories and building communities
</p>
<div style="display: flex; gap: 15px; justify-content: center; flex-wrap: wrap;">
<a href="/signup" style="
background: white;
color: #2d3748;
padding: 15px 30px;
text-decoration: none;
border-radius: 50px;
font-weight: 700;
transition: all 0.3s ease;
">Get Started</a>
<a href="/about" style="
background: transparent;
color: white;
padding: 15px 30px;
text-decoration: none;
border-radius: 50px;
border: 2px solid rgba(255,255,255,0.5);
font-weight: 700;
transition: all 0.3s ease;
">Learn More</a>
</div>
</div>
</div>
<div style="max-width: 1200px; margin: 0 auto;">
<div class="feature-grid">
<div class="feature-card">
<div style="font-size: 3rem; margin-bottom: 15px;">✍️</div>
<h3 style="margin-bottom: 15px; color: #2d3748;">Easy Writing</h3>
<p style="color: #718096; line-height: 1.6;">
Powerful editor with markdown support and real-time collaboration
</p>
</div>
<div class="feature-card">
<div style="font-size: 3rem; margin-bottom: 15px;">🚀</div>
<h3 style="margin-bottom: 15px; color: #2d3748;">Fast Publishing</h3>
<p style="color: #718096; line-height: 1.6;">
Publish instantly with SEO optimization and social media integration
</p>
</div>
<div class="feature-card">
<div style="font-size: 3rem; margin-bottom: 15px;">📊</div>
<h3 style="margin-bottom: 15px; color: #2d3748;">Analytics</h3>
<p style="color: #718096; line-height: 1.6;">
Track your audience growth and engagement with detailed insights
</p>
</div>
</div>
</div>
<div class="cta-section">
<h2 style="font-size: 2.5rem; margin-bottom: 20px; font-weight: 700;">
Ready to Start Writing?
</h2>
<p style="font-size: 1.2rem; margin-bottom: 30px; opacity: 0.9;">
Join our community of writers and share your unique voice with the world
</p>
<a href="/signup" style="
display: inline-block;
background: white;
color: #667eea;
padding: 18px 40px;
text-decoration: none;
border-radius: 50px;
font-weight: 700;
font-size: 1.1rem;
transition: all 0.3s ease;
">Start Your Journey</a>
</div>
</div>
Method 3: Code Injection for Site-Wide Changes
For global homepage modifications, use Code Injection:
Go to Settings → Code Injection
Site Header (for CSS):
<style>
/* Custom Homepage Styles */
.home-template .site-header {
background: transparent;
position: absolute;
z-index: 100;
}
.home-template .site-main {
padding-top: 0;
}
/* Custom hero section for homepage */
.custom-hero {
height: 100vh;
background: linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.6)),
url('YOUR_BACKGROUND_IMAGE_URL') center/cover;
display: flex;
align-items: center;
justify-content: center;
color: white;
text-align: center;
}
.hero-content h1 {
font-size: 4rem;
margin-bottom: 1rem;
font-weight: 800;
}
.hero-content p {
font-size: 1.5rem;
margin-bottom: 2rem;
opacity: 0.9;
}
.hero-btn {
display: inline-block;
background: #667eea;
color: white;
padding: 15px 30px;
text-decoration: none;
border-radius: 50px;
font-weight: 600;
transition: all 0.3s ease;
}
.hero-btn:hover {
background: #5a67d8;
transform: translateY(-2px);
}
/* Responsive design */
@media (max-width: 768px) {
.hero-content h1 { font-size: 2.5rem; }
.hero-content p { font-size: 1.2rem; }
}
</style>
Site Footer (for JavaScript):
<script>
// Dynamic content loading for homepage
document.addEventListener('DOMContentLoaded', function() {
// Check if we're on the homepage
if (document.body.classList.contains('home-template')) {
// Add smooth scrolling to all links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
document.querySelector(this.getAttribute('href')).scrollIntoView({
behavior: 'smooth'
});
});
});
// Add animation on scroll
const observerOptions = {
threshold: 0.1,
rootMargin: '0px 0px -50px 0px'
};
const observer = new IntersectionObserver(function(entries) {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.style.opacity = '1';
entry.target.style.transform = 'translateY(0)';
}
});
}, observerOptions);
// Observe all cards for animation
document.querySelectorAll('.feature-card, .post-card').forEach(card => {
card.style.opacity = '0';
card.style.transform = 'translateY(20px)';
card.style.transition = 'opacity 0.6s ease, transform 0.6s ease';
observer.observe(card);
});
}
});
</script>
Method 4: Using Ghost's {{#is}} Helper (Advanced)
For theme-level customization, edit your theme's index.hbs
file:
{{!-- Custom homepage layout --}}
{{#is "home"}}
<section class="custom-homepage-hero">
<div class="hero-content">
<h1>{{@site.title}}</h1>
<p>{{@site.description}}</p>
<a href="{{@site.url}}/about" class="hero-cta">Discover More</a>
</div>
</section>
<section class="featured-posts-section">
<div class="container">
<h2>Latest Stories</h2>
<div class="posts-grid">
{{#get "posts" limit="6" include="tags,authors"}}
{{#foreach posts}}
<article class="post-preview">
<a href="{{url}}">
{{#if feature_image}}
<img src="{{img_url feature_image size="m"}}" alt="{{title}}">
{{/if}}
<div class="post-content">
<h3>{{title}}</h3>
<p>{{excerpt words="20"}}</p>
<div class="post-meta">
<time datetime="{{date format="YYYY-MM-DD"}}">{{date format="MMM DD, YYYY"}}</time>
<span class="reading-time">{{reading_time}}</span>
</div>
</div>
</a>
</article>
{{/foreach}}
{{/get}}
</div>
</div>
</section>
{{else}}
{{!-- Default post listing for non-homepage --}}
{{> "loop"}}
{{/is}}
Tips for Success
- Test Responsively: Always check your homepage on mobile devices
- Optimize Images: Use appropriate image sizes and formats
- SEO Considerations: Add proper meta tags and structured data
- Performance: Minimize custom CSS/JS for faster loading
- Backup: Always backup your theme before making changes
Common Issues & Solutions
Problem: Custom CSS not applying
- Solution: Clear Ghost cache and check CSS syntax
Problem: Layout breaks on mobile
- Solution: Use CSS media queries and test thoroughly
Problem: Images not loading
- Solution: Verify image URLs and file permissions
This guide provides multiple approaches to customize your Ghost CMS homepage. Choose the method that best fits your technical comfort level and requirements.