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
$rootScope
or a shared service property that your main layout controller watches.
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$rootScope
sparingly (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.