A professional WordPress header typically consists of two sections: a top navbar for contact information and social links, and a main header with branding and navigation. Theme Settings Free Version provides all the tools needed to make these elements fully customizable without writing complex code.
This tutorial shows you how to build a two-tier header system with contact details, social media links, logo, and navigation menu—all manageable through a clean admin interface. No CSS required, just structure and functionality.
Header Structure Overview
We’ll build a header with two distinct sections:
Top Navbar:
- Left side: Contact phone and email
- Right side: Social media links (Facebook, Twitter, Instagram, LinkedIn)
Main Header:
- Left side: Site logo
- Right side: Primary navigation menu
Final Structure:
┌─────────────────────────────────────────┐
│ Top Navbar │
│ Phone: +123 | Email [Social Links] → │
├─────────────────────────────────────────┤
│ Main Header │
│ [Logo] [Menu] [Menu] [Menu]│
└─────────────────────────────────────────┘
This structure is mobile-friendly, SEO-optimized, and fully customizable through Theme Settings.
Step 1: Configure Theme Settings Fields
First, add the necessary fields to your settings-config.php file.
Contact Information Fields
'header_settings' => [
'title' => 'Header Settings',
'icon' => 'bi-layout-text-window',
'sections' => [
// Contact Information
'contact_info' => [
'title' => 'Contact Information',
'desc' => 'Display contact details in top navbar',
'fields' => [
'header_phone' => [
'type' => 'tel',
'label' => 'Contact Phone',
'placeholder' => '+1 (555) 123-4567',
'desc' => 'Phone number displayed in top navbar',
],
'header_email' => [
'type' => 'email',
'label' => 'Contact Email',
'placeholder' => 'info@yoursite.com',
'desc' => 'Email address displayed in top navbar',
],
],
],
// Social Media Links
'social_links' => [
'title' => 'Social Media Links',
'desc' => 'Add social media profile URLs',
'fields' => [
'facebook_url' => [
'type' => 'url',
'label' => 'Facebook URL',
'placeholder' => 'https://facebook.com/yourpage',
],
'twitter_url' => [
'type' => 'url',
'label' => 'Twitter URL',
'placeholder' => 'https://twitter.com/yourhandle',
],
'instagram_url' => [
'type' => 'url',
'label' => 'Instagram URL',
'placeholder' => 'https://instagram.com/yourprofile',
],
'linkedin_url' => [
'type' => 'url',
'label' => 'LinkedIn URL',
'placeholder' => 'https://linkedin.com/company/yourcompany',
],
],
],
// Logo Settings
'branding' => [
'title' => 'Site Branding',
'desc' => 'Upload your site logo',
'fields' => [
'site_logo' => [
'type' => 'media',
'label' => 'Site Logo',
'desc' => 'Recommended size: 200x60px, PNG format',
],
'logo_width' => [
'type' => 'number',
'label' => 'Logo Width (px)',
'default' => 180,
'min' => 50,
'max' => 400,
],
],
],
],
],
What These Fields Do:
- ✅ header_phone - Phone number with tel format validation
- ✅ header_email - Email with automatic validation
- ✅ social_links - URL fields for each platform
- ✅ site_logo - Media upload for logo image
- ✅ logo_width - Numeric control for logo size
Step 2: Create Header Template Structure
Create or edit your header.php file with the two-tier structure.
Complete Header Template
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo('charset'); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
<header class="site-header">
<!-- Top Navbar -->
<?php get_template_part('template-parts/header/top-navbar'); ?>
<!-- Main Header -->
<?php get_template_part('template-parts/header/main-header'); ?>
</header>
<div id="page" class="site">
Top Navbar Template
Create template-parts/header/top-navbar.php:
<?php
/**
* Template part: Top Navbar
* Displays contact info and social links
*/
// Get contact information
$phone = ts_get_option('header_phone');
$email = ts_get_option('header_email');
// Get social media links
$facebook = ts_get_option('facebook_url');
$twitter = ts_get_option('twitter_url');
$instagram = ts_get_option('instagram_url');
$linkedin = ts_get_option('linkedin_url');
// Only display if at least one field has value
if ($phone || $email || $facebook || $twitter || $instagram || $linkedin) :
?>
<div class="top-navbar">
<div class="container">
<div class="top-navbar-content">
<!-- Left: Contact Info -->
<div class="contact-info">
<?php if ($phone) : ?>
<span class="contact-item phone">
<i class="bi bi-telephone"></i>
<a href="tel:<?php echo esc_attr(str_replace([' ', '(', ')', '-'], '', $phone)); ?>">
<?php echo esc_html($phone); ?>
</a>
</span>
<?php endif; ?>
<?php if ($email) : ?>
<span class="contact-item email">
<i class="bi bi-envelope"></i>
<a href="mailto:<?php echo esc_attr($email); ?>">
<?php echo esc_html($email); ?>
</a>
</span>
<?php endif; ?>
</div>
<!-- Right: Social Links -->
<div class="social-links">
<?php if ($facebook) : ?>
<a href="<?php echo esc_url($facebook); ?>"
target="_blank"
rel="noopener noreferrer"
aria-label="Facebook">
<i class="bi bi-facebook"></i>
</a>
<?php endif; ?>
<?php if ($twitter) : ?>
<a href="<?php echo esc_url($twitter); ?>"
target="_blank"
rel="noopener noreferrer"
aria-label="Twitter">
<i class="bi bi-twitter"></i>
</a>
<?php endif; ?>
<?php if ($instagram) : ?>
<a href="<?php echo esc_url($instagram); ?>"
target="_blank"
rel="noopener noreferrer"
aria-label="Instagram">
<i class="bi bi-instagram"></i>
</a>
<?php endif; ?>
<?php if ($linkedin) : ?>
<a href="<?php echo esc_url($linkedin); ?>"
target="_blank"
rel="noopener noreferrer"
aria-label="LinkedIn">
<i class="bi bi-linkedin"></i>
</a>
<?php endif; ?>
</div>
</div>
</div>
</div>
<?php endif; ?>
Key Features:
- ✅ Conditional display - Only shows if fields have values
- ✅ Proper phone links - Removes formatting for tel: protocol
- ✅ Accessible links - Includes aria-labels
- ✅ Security - All outputs escaped properly
- ✅ SEO-friendly - Uses semantic HTML
Main Header Template
Create template-parts/header/main-header.php:
<?php
/**
* Template part: Main Header
* Displays logo and primary navigation
*/
// Get logo settings
$logo = ts_get_option('site_logo');
$logo_width = ts_get_option('logo_width', 180);
$site_name = get_bloginfo('name');
?>
<div class="main-header">
<div class="container">
<div class="main-header-content">
<!-- Left: Site Logo -->
<div class="site-branding">
<a href="<?php echo esc_url(home_url('/')); ?>"
rel="home"
aria-label="<?php echo esc_attr($site_name); ?>">
<?php if ($logo) : ?>
<img src="<?php echo esc_url($logo); ?>"
alt="<?php echo esc_attr($site_name); ?>"
width="<?php echo esc_attr($logo_width); ?>"
class="site-logo">
<?php else : ?>
<span class="site-title">
<?php echo esc_html($site_name); ?>
</span>
<?php endif; ?>
</a>
</div>
<!-- Right: Primary Navigation -->
<nav class="primary-navigation" role="navigation" aria-label="Primary Menu">
<!-- Mobile Menu Toggle -->
<button class="menu-toggle"
aria-controls="primary-menu"
aria-expanded="false">
<span class="menu-icon">
<span></span>
<span></span>
<span></span>
</span>
<span class="menu-text">Menu</span>
</button>
<!-- Primary Menu -->
<?php
wp_nav_menu([
'theme_location' => 'primary',
'menu_id' => 'primary-menu',
'menu_class' => 'primary-menu',
'container' => false,
'fallback_cb' => false,
]);
?>
</nav>
</div>
</div>
</div>
What This Does:
- ✅ Logo display with fallback to site name
- ✅ Dynamic logo width from Theme Settings
- ✅ WordPress navigation using wp_nav_menu()
- ✅ Mobile menu toggle button structure
- ✅ Accessibility features with ARIA attributes
Step 3: Register Primary Menu Location
Add menu registration to your functions.php:
/**
* Register navigation menus
*/
function mytheme_register_menus() {
register_nav_menus([
'primary' => __('Primary Menu', 'mytheme'),
]);
}
add_action('after_setup_theme', 'mytheme_register_menus');
Then create a menu:
- Go to Appearance → Menus
- Create a new menu named “Primary Menu”
- Assign it to “Primary Menu” location
- Add your pages/links
Step 4: Adding Mobile Menu Toggle Functionality
Add this JavaScript to handle mobile menu toggle (already included in Theme Settings JS):
// Mobile menu toggle
document.addEventListener('DOMContentLoaded', function() {
const menuToggle = document.querySelector('.menu-toggle');
const primaryMenu = document.querySelector('#primary-menu');
if (menuToggle && primaryMenu) {
menuToggle.addEventListener('click', function() {
const expanded = this.getAttribute('aria-expanded') === 'true';
this.setAttribute('aria-expanded', !expanded);
primaryMenu.classList.toggle('active');
});
}
});
Step 5: Admin Configuration Guide
For End Users - How to Configure:
Setting Up Contact Information
- Go to WordPress Admin → Theme Settings
- Click Header Settings tab
- Navigate to Contact Information section
- Enter:
- Contact Phone:
+1 (555) 123-4567 - Contact Email:
info@yoursite.com
- Contact Phone:
- Click Save Changes
Adding Social Media Links
- In Header Settings tab
- Go to Social Media Links section
- Enter your profile URLs:
- Facebook:
https://facebook.com/yourpage - Twitter:
https://twitter.com/yourhandle - Instagram:
https://instagram.com/yourprofile - LinkedIn:
https://linkedin.com/company/yourcompany
- Facebook:
- Leave blank any platforms you don’t use
- Click Save Changes
Uploading Your Logo
- In Header Settings tab
- Go to Site Branding section
- Click Upload Logo button
- Choose image from Media Library or upload new
- Adjust Logo Width (default: 180px)
- Click Save Changes
Logo Best Practices:
- ✅ Use PNG format with transparent background
- ✅ Recommended size: 200x60px to 400x120px
- ✅ Keep file size under 100KB
- ✅ Use high-resolution for retina displays
Complete Example Output
When properly configured, your header will output clean HTML like this:
<header class="site-header">
<!-- Top Navbar -->
<div class="top-navbar">
<div class="container">
<div class="top-navbar-content">
<div class="contact-info">
<span class="contact-item phone">
<i class="bi bi-telephone"></i>
<a href="tel:+15551234567">+1 (555) 123-4567</a>
</span>
<span class="contact-item email">
<i class="bi bi-envelope"></i>
<a href="mailto:info@yoursite.com">info@yoursite.com</a>
</span>
</div>
<div class="social-links">
<a href="https://facebook.com/yourpage" target="_blank">
<i class="bi bi-facebook"></i>
</a>
<!-- More social links... -->
</div>
</div>
</div>
</div>
<!-- Main Header -->
<div class="main-header">
<div class="container">
<div class="main-header-content">
<div class="site-branding">
<a href="https://yoursite.com">
<img src="logo.png" alt="Site Name" width="180">
</a>
</div>
<nav class="primary-navigation">
<ul id="primary-menu">
<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
</div>
</div>
</div>
</header>
Template Hierarchy Best Practices
Organize header components properly:
your-theme/
├── header.php (main header file)
├── template-parts/
│ └── header/
│ ├── top-navbar.php (top navbar component)
│ └── main-header.php (main header component)
└── themesettings/
└── settings-config.php (field configuration)
Benefits of this structure:
- ✅ Easy maintenance - Each component isolated
- ✅ Reusable - Can use components elsewhere
- ✅ Clean code - Separation of concerns
- ✅ Developer-friendly - Easy to understand
Troubleshooting Common Issues
| Issue | Cause | Solution |
|---|---|---|
| Logo not displaying | Wrong media ID or URL | Check media library, re-upload logo |
| Social icons missing | Bootstrap Icons not loaded | Verify icons CSS in Theme Settings |
| Menu not showing | Menu not assigned | Assign menu in Appearance → Menus |
| Phone link broken | Special characters | Template handles formatting automatically |
| Email link wrong | Typo in email | Check spelling in Theme Settings |
Implementation Checklist
Theme Settings Configuration:
- ✅ Add header fields to settings-config.php
- ✅ Configure contact info fields (phone, email)
- ✅ Add social media URL fields
- ✅ Set up logo upload field
- ✅ Add logo width control
Template Files:
- ✅ Update header.php main structure
- ✅ Create top-navbar.php template part
- ✅ Create main-header.php template part
- ✅ Register primary menu location in functions.php
Admin Setup:
- ✅ Upload site logo via Theme Settings
- ✅ Enter contact phone and email
- ✅ Add social media profile URLs
- ✅ Create and assign primary menu
- ✅ Test all links and functionality
Testing:
- ✅ Verify contact info displays correctly
- ✅ Test phone and email links
- ✅ Confirm social links open in new tab
- ✅ Check logo displays at correct size
- ✅ Test navigation menu functionality
- ✅ Verify mobile menu toggle works
Conclusion
With Theme Settings Free Version, you can build a professional two-tier WordPress header without writing complex configuration code. The system provides all essential field types needed for contact information, social links, and branding.
What You’ve Achieved:
- ✅ Dynamic contact information display
- ✅ Flexible social media integration
- ✅ Professional logo management
- ✅ Clean, semantic HTML structure
- ✅ Accessible navigation menu
- ✅ User-friendly admin interface
This header structure is scalable, maintainable, and fully customizable through the admin panel. Users can update contact details, swap logos, and modify social links without touching code.
“A professional header is the first impression of your website—
make it count with clean structure and easy customization.”
Next Steps:
- Add basic CSS for layout and styling
- Implement sticky header on scroll
- Add search functionality to header
- Create header variations for different pages
- Explore Theme Settings Pro for repeater-based social links