How to dynamically change header based on AngularJS partial view?
When building single-page applications in AngularJS, it’s common to display different partial views based on the route or state. Often, you’ll want your application’s header (whether that’s the <title> tag, a navigation bar, or a header <div>) to change dynamically depending on which partial is currently being shown. Below are a few ways to achieve this.
1. Change the Page <title> Dynamically
If by “header” you mean the HTML page title (in the <head> section), you can set it in your route configuration and update it whenever the route changes.
Step 1: Add a Title Property in Your Route Configuration
For ngRoute:
angular.module('myApp', ['ngRoute'])
.config(function($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: 'views/home.html',
controller: 'HomeController',
// Custom property for the page title
title: 'Home Page'
})
.when('/about', {
templateUrl: 'views/about.html',
controller: 'AboutController',
title: 'About Us'
})
.otherwise({ redirectTo: '/home' });
});
Step 2: Listen for $routeChangeSuccess and Update $rootScope Title
You can update $rootScope.pageTitle on each route change and then bind it in your main index.html.
angular.module('myApp')
.run(function($rootScope, $route) {
$rootScope.$on('$routeChangeSuccess', function(event, current) {
// current might be undefined if no matching route
if (current.$$route && current.$$route.title) {
$rootScope.pageTitle = current.$$route.title;
} else {
$rootScope.pageTitle = 'Default Title';
}
});
});
Step 3: Bind the Title in Your index.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>{{ pageTitle }}</title>
<!-- other head content -->
</head>
<body>
<ng-view></ng-view>
</body>
</html>
Now, whenever you navigate to a new route, $rootScope.pageTitle updates based on the route’s custom property, and the <title> tag reflects that change.
2. Change a Navigation Bar or Header <div> Dynamically
If your “header” refers to a navigation bar or a top <div> in your layout, you can do something similar:
- Store the desired header text, icons, or styles in your route config or in a service.
- Listen to route change events.
- Update a
$rootScopeor a shared service property that your main layout controller watches.
Recommended Courses
Example Using $routeProvider
$routeProvider
.when('/dashboard', {
templateUrl: 'views/dashboard.html',
controller: 'DashboardController',
headerInfo: { title: 'Dashboard', icon: 'dashboard-icon.png' }
})
.when('/profile', {
templateUrl: 'views/profile.html',
controller: 'ProfileController',
headerInfo: { title: 'User Profile', icon: 'user-icon.png' }
});
In your run block or a top-level controller, watch $routeChangeSuccess:
.run(function($rootScope) {
$rootScope.$on('$routeChangeSuccess', function(event, current) {
if (current.$$route && current.$$route.headerInfo) {
$rootScope.headerTitle = current.$$route.headerInfo.title;
$rootScope.headerIcon = current.$$route.headerInfo.icon;
} else {
$rootScope.headerTitle = 'My App';
$rootScope.headerIcon = 'default-icon.png';
}
});
});
In your main layout (e.g., index.html or a root partial):
<header>
<img ng-src="{{ headerIcon }}" alt="Header Icon">
<h1>{{ headerTitle }}</h1>
</header>
<ng-view></ng-view>
This way, each partial view can define how the header looks, and you only have one header element in the layout.
3. Using UI-Router (If You’re Not Using ngRoute)
If your project uses UI-Router (another popular router for AngularJS), the concept is similar but with states instead of $routeProvider. For each state, define custom data or a resolve property:
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'views/home.html',
controller: 'HomeController',
data: {
headerTitle: 'Home Page',
headerIcon: 'home-icon.png'
}
})
.state('about', {
url: '/about',
templateUrl: 'views/about.html',
controller: 'AboutController',
data: {
headerTitle: 'About Us'
}
});
Then in a run block or a top-level controller:
.run(function($rootScope, $state) {
$rootScope.$on('$stateChangeSuccess', function(event, toState) {
if (toState.data && toState.data.headerTitle) {
$rootScope.headerTitle = toState.data.headerTitle;
$rootScope.headerIcon = toState.data.headerIcon || 'default-icon.png';
} else {
$rootScope.headerTitle = 'My App';
$rootScope.headerIcon = 'default-icon.png';
}
});
});
The <header> binding remains the same:
<header>
<img ng-src="{{ headerIcon }}">
<h1>{{ headerTitle }}</h1>
</header>
<ui-view></ui-view> <!-- UI-Router's equivalent of <ng-view> -->
Best Practices
Single Source of Truth
Maintain the “header info” in the route config or UI-Router state so that each partial knows exactly how the header should look.Minimize Global Scope
Use$rootScopesparingly (only if your header is truly global). If you have a layout controller, consider storing the header info there, and inject it into child views as needed.Avoid Repeated Elements
Don’t duplicate<header>in every partial. Instead, keep one header in the layout (e.g.,index.html), and let each partial define the data that modifies that header.Fallbacks
Provide fallback values (like'My App', a default icon, etc.) so if a route does not define custom header data, the UI remains consistent.
Going Beyond: Mastering AngularJS & System Design
Setting up a dynamic header is just one piece of building a robust single-page application in AngularJS. To deepen your expertise, check out the following resources from DesignGurus.io:
Grokking JavaScript Fundamentals
Strengthen your JavaScript core skills—closures, prototypes, async patterns—critical for debugging and optimizing AngularJS code.Grokking the Coding Interview: Patterns for Coding Questions
Learn essential coding patterns for solving interview questions and day-to-day challenges in front-end or full-stack roles.Grokking the System Design Interview
As your AngularJS application grows, you’ll need to consider performance, caching, data flows, and more. This course offers a solid foundation in designing scalable software.
If you’d like personalized feedback from ex-FAANG engineers, check out:
And for free tutorials, visit the DesignGurus.io YouTube channel.
Final Thoughts
To dynamically change the header based on which AngularJS partial view is displayed:
- Attach data (like a title or icon) to each route/state.
- Listen for route/state changes in a run block or layout controller.
- Update a shared property (e.g.,
$rootScope.headerTitle) used by your main header.
By keeping your header in one place (e.g., index.html or a root component) and letting each partial define its own header data, you maintain a clean, modular design that’s easy to update as your AngularJS app evolves.